diff options
author | Hans Insulander <hin@cvs.openbsd.org> | 2002-06-07 04:10:33 +0000 |
---|---|---|
committer | Hans Insulander <hin@cvs.openbsd.org> | 2002-06-07 04:10:33 +0000 |
commit | c7406af60dafab45e920d9c3f52cd74cd4b9e81b (patch) | |
tree | d99f95636a30c46ffc4acee6363ac4bf9db13c89 /sys/xfs/xfs_vnodeops-common.c | |
parent | 45d3283fa9b158e3ff3af143713064236a2eeb80 (diff) |
merge
Diffstat (limited to 'sys/xfs/xfs_vnodeops-common.c')
-rw-r--r-- | sys/xfs/xfs_vnodeops-common.c | 171 |
1 files changed, 94 insertions, 77 deletions
diff --git a/sys/xfs/xfs_vnodeops-common.c b/sys/xfs/xfs_vnodeops-common.c index 92b10c47232..cf2623bee3b 100644 --- a/sys/xfs/xfs_vnodeops-common.c +++ b/sys/xfs/xfs_vnodeops-common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -49,7 +44,27 @@ #include <xfs/xfs_syscalls.h> #include <xfs/xfs_vnodeops.h> -RCSID("$Id: xfs_vnodeops-common.c,v 1.5 2002/03/14 03:16:14 millert Exp $"); +RCSID("$Id: xfs_vnodeops-common.c,v 1.6 2002/06/07 04:10:32 hin Exp $"); + +static void +xfs_handle_stale(struct xfs_node *xn) +{ +#ifndef __OpenBSD__ + struct vnode *vp = XNODE_TO_VNODE(xn); +#endif + + if ((xn->flags & XFS_STALE) == 0) + return; + +#if __APPLE__ + if (UBCISVALID(vp) && !ubc_isinuse(vp, 1)) { + xn->flags &= ~XFS_STALE; + XFS_TOKEN_CLEAR(xn, ~0, + XFS_OPEN_MASK | XFS_ATTR_MASK | + XFS_DATA_MASK | XFS_LOCK_MASK); + } +#endif +} int xfs_open_valid(struct vnode *vp, struct ucred *cred, struct proc *p, @@ -61,6 +76,8 @@ xfs_open_valid(struct vnode *vp, struct ucred *cred, struct proc *p, XFSDEB(XDEBVFOPS, ("xfs_open_valid\n")); + xfs_handle_stale(xn); + do { if (!XFS_TOKEN_GOT(xn, tok)) { struct xfs_message_open msg; @@ -71,7 +88,7 @@ xfs_open_valid(struct vnode *vp, struct ucred *cred, struct proc *p, msg.handle = xn->handle; msg.tokens = tok; - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; @@ -103,7 +120,7 @@ xfs_attr_valid(struct vnode *vp, struct ucred *cred, struct proc *p, msg.cred.uid = cred->cr_uid; msg.cred.pag = pag; msg.handle = xn->handle; - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } else { @@ -132,7 +149,7 @@ xfs_fetch_rights(struct vnode *vp, struct ucred *cred, struct proc *p) msg.cred.uid = cred->cr_uid; msg.cred.pag = pag; msg.handle = xn->handle; - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } else { @@ -163,7 +180,7 @@ xfs_data_valid(struct vnode *vp, struct ucred *cred, struct proc *p, msg.handle = xn->handle; msg.tokens = tok; - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; @@ -229,7 +246,7 @@ do_fsync(struct xfs *xfsp, vattr2xfs_attr(&xn->attr, &msg.attr); msg.flag = flag; - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; @@ -260,6 +277,9 @@ xfs_fsync_common(struct vnode *vp, struct ucred *cred, return 0; } +#ifdef __APPLE__ + ubc_pushdirty(vp); +#endif if (xn->flags & XFS_DATA_DIRTY) { #ifdef FSYNC_RECLAIM /* writing back the data from this vnode failed */ @@ -316,10 +336,6 @@ xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, xfs_vfs_readlock(t, xfs_uio_to_proc(uio)); xfs_vop_read(t, uio, ioflag, cred, error); xfs_vfs_unlock(t, xfs_uio_to_proc(uio)); - - if (uio->uio_iovcnt && uio->uio_iov[0].iov_len > 0) - XFSDEB(XDEBVNOPS, ("xfs_read: byte: %d\n", - ((char *)uio->uio_iov[0].iov_base)[0])); } XFSDEB(XDEBVNOPS, ("xfs_read offset: %lu resid: %d\n", @@ -391,7 +407,7 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, #define CHECK_XFSATTR(A, cast) (vap->A == cast VNOVAL || vap->A == xn->attr.A) if (CHECK_XFSATTR(va_mode,(mode_t)) && CHECK_XFSATTR(va_nlink,(short)) && - CHECK_XFSATTR(va_size,(u_quad_t)) && + CHECK_XFSATTR(va_size,(va_size_t)) && CHECK_XFSATTR(va_uid,(uid_t)) && CHECK_XFSATTR(va_gid,(gid_t)) && CHECK_XFSATTR(va_mtime.tv_sec,(unsigned int)) && @@ -420,10 +436,14 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, vattr2xfs_attr(vap, &msg.attr); if (XFS_TOKEN_GOT(xn, XFS_DATA_R)) { if (vp->v_type == VREG) { - if (vap->va_size != (u_quad_t)VNOVAL) + if (vap->va_size != (va_size_t)VNOVAL) XA_SET_SIZE(&msg.attr, vap->va_size); else XA_SET_SIZE(&msg.attr, xn->attr.va_size); +#ifdef __APPLE__ + if (UBCINFOEXISTS(vp)) + ubc_setsize(vp, msg.attr.xa_size); +#endif } if (vap->va_mtime.tv_sec != (unsigned int)VNOVAL) XA_SET_MTIME(&msg.attr, vap->va_mtime.tv_sec); @@ -432,7 +452,7 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, } XFS_TOKEN_CLEAR(xn, XFS_ATTR_VALID, XFS_ATTR_MASK); - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } @@ -508,8 +528,13 @@ xfs_lookup_common(struct vnode *dvp, struct proc *proc = xfs_cnp_to_proc(cnp); struct ucred *cred = xfs_proc_to_cred(proc); + XFSDEB(XDEBVNOPS, ("xfs_lookup_common: enter\n")); + *vpp = NULL; + if (cnp->cn_namelen >= XFS_MAX_NAME) + return ENAMETOOLONG; + if (dvp->v_type != VDIR) return ENOTDIR; @@ -524,6 +549,9 @@ xfs_lookup_common(struct vnode *dvp, if (error != 0) goto done; + XFSDEB(XDEBVNOPS, ("xfs_lookup_common: dvp = %lx\n", (unsigned long) dvp)); + + error = xfs_dnlc_lookup(dvp, cnp, vpp); if (error == 0) { @@ -548,12 +576,10 @@ xfs_lookup_common(struct vnode *dvp, msg.cred.pag = XFS_ANONYMOUSID; } msg.parent_handle = d->handle; - - bcopy(cnp->cn_nameptr, msg.name, cnp->cn_namelen); + memcpy(msg.name, cnp->cn_nameptr, cnp->cn_namelen); msg.name[cnp->cn_namelen] = '\0'; - - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); - + error = xfs_message_rpc(xfsp->fd, &msg.header, + sizeof(msg), proc); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; if(error == ENOENT && cnp->cn_nameiop != CREATE) { @@ -569,6 +595,7 @@ xfs_lookup_common(struct vnode *dvp, } while (error == 0); done: + XFSDEB(XDEBVNOPS, ("xfs_lookup_common: return\n")); return error; } @@ -590,7 +617,8 @@ xfs_create_common(struct vnode *dvp, msg.header.opcode = XFS_MSG_CREATE; msg.parent_handle = xn->handle; - strncpy(msg.name, name, 256); + if (strlcpy(msg.name, name, sizeof(msg.name)) >= XFS_MAX_NAME) + return ENAMETOOLONG; vattr2xfs_attr(vap, &msg.attr); msg.mode = 0; /* XXX - mode */ @@ -603,7 +631,7 @@ xfs_create_common(struct vnode *dvp, } - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; @@ -633,25 +661,19 @@ xfs_remove_common(struct vnode *dvp, msg.header.opcode = XFS_MSG_REMOVE; msg.parent_handle = xn->handle; - strncpy(msg.name, name, 256); msg.cred.uid = cred->cr_uid; msg.cred.pag = xfs_get_pag(cred); - - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + + if (strlcpy(msg.name, name, sizeof(msg.name)) >= XFS_MAX_NAME) + error = ENAMETOOLONG; + else + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) &msg)->error; if (error == 0) xfs_dnlc_purge (vp); -#if !defined(__FreeBSD__) || __FreeBSD_version < 300000 - if (dvp == vp) - vrele(vp); - else - vput(vp); - vput(dvp); -#endif - return error; } @@ -680,12 +702,14 @@ xfs_rename_common(struct vnode *fdvp, msg.header.opcode = XFS_MSG_RENAME; msg.old_parent_handle = VNODE_TO_XNODE(fdvp)->handle; - strncpy(msg.old_name, fname, 256); + if (strlcpy(msg.old_name, fname, sizeof(msg.old_name)) >= XFS_MAX_NAME) + return ENAMETOOLONG; msg.new_parent_handle = VNODE_TO_XNODE(tdvp)->handle; - strncpy(msg.new_name, tname, 256); + if (strlcpy(msg.new_name, tname, sizeof(msg.new_name)) >= XFS_MAX_NAME) + return ENAMETOOLONG; msg.cred.uid = cred->cr_uid; msg.cred.pag = xfs_get_pag(cred); - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) &msg)->error; @@ -713,7 +737,8 @@ xfs_mkdir_common(struct vnode *dvp, msg.header.opcode = XFS_MSG_MKDIR; msg.parent_handle = xn->handle; - strncpy(msg.name, name, 256); + if (strlcpy(msg.name, name, sizeof(msg.name)) >= XFS_MAX_NAME) + return ENAMETOOLONG; vattr2xfs_attr(vap, &msg.attr); if (cred != NOCRED) { msg.cred.uid = cred->cr_uid; @@ -722,7 +747,7 @@ xfs_mkdir_common(struct vnode *dvp, msg.cred.uid = 0; msg.cred.pag = XFS_ANONYMOUSID; } - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } @@ -746,24 +771,18 @@ xfs_rmdir_common(struct vnode *dvp, msg.header.opcode = XFS_MSG_RMDIR; msg.parent_handle = xn->handle; - strncpy(msg.name, name, 256); msg.cred.uid = cred->cr_uid; msg.cred.pag = xfs_get_pag(cred); - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (strlcpy(msg.name, name, sizeof(msg.name)) >= XFS_MAX_NAME) + error = ENAMETOOLONG; + else + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) &msg)->error; if (error == 0) xfs_dnlc_purge (vp); -#if !defined(__FreeBSD__) || __FreeBSD_version < 300000 - if (dvp == vp) - vrele(vp); - else - vput(vp); - vput(dvp); -#endif - XFSDEB(XDEBVNOPS, ("xfs_rmdir error: %d\n", error)); return error; @@ -819,11 +838,12 @@ xfs_link_common(struct vnode *dvp, msg.header.opcode = XFS_MSG_LINK; msg.parent_handle = xn->handle; msg.from_handle = xn2->handle; - strncpy(msg.name, name, 256); + if (strlcpy(msg.name, name, sizeof(msg.name)) >= XFS_MAX_NAME) + return ENAMETOOLONG; msg.cred.uid = cred->cr_uid; msg.cred.pag = xfs_get_pag(cred); - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; @@ -849,30 +869,22 @@ xfs_symlink_common(struct vnode *dvp, msg.header.opcode = XFS_MSG_SYMLINK; msg.parent_handle = xn->handle; - strncpy(msg.name, name, sizeof(msg.name)); - msg.name[sizeof(msg.name) - 1] = '\0'; vattr2xfs_attr(vap, &msg.attr); msg.cred.uid = cred->cr_uid; msg.cred.pag = xfs_get_pag(cred); - strncpy (msg.contents, target, sizeof(msg.contents)); - msg.contents[sizeof(msg.contents) - 1] = '\0'; - - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (strlcpy (msg.contents, target, sizeof(msg.contents)) >= XFS_MAX_SYMLINK_CONTENT) { + error = ENAMETOOLONG; + goto done; + } + if (strlcpy(msg.name, name, sizeof(msg.name)) >= XFS_MAX_NAME) { + error = ENAMETOOLONG; + goto done; + } + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), proc); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; - if (error == 0) { - error = xfs_lookup_common(dvp, cnp, vpp); -#if !defined(__FreeBSD__) || __FreeBSD_version < 400012 - if (error == 0) - vput (*vpp); -#endif - } - -#if !defined(__FreeBSD__) - vput(dvp); -#endif - + done: return error; } @@ -918,18 +930,23 @@ xfs_inactive_common(struct vnode *vp, struct proc *p) error = xfs_fsync_common(vp, xn->cred, /* XXX */ 0, p); if (error) { printf ("xfs_inactive: failed writing back data: %d\n", error); + xn->flags &= ~XFS_DATA_DIRTY; } #ifndef __osf__ xfs_vfs_unlock(vp, p); /* If this node is no longer valid, recycle immediately. */ - if (!XFS_TOKEN_GOT(xn, XFS_ATTR_R | XFS_ATTR_W)) { + if (!XFS_TOKEN_GOT(xn, XFS_ATTR_R | XFS_ATTR_W) + || (xn->flags & XFS_STALE) == XFS_STALE) { XFSDEB(XDEBVNOPS, ("xfs_inactive: vrecycle\n")); vrecycle(vp, 0, p); } #else - /* XXX ? */ + + XFSDEB(XDEBVNOPS, ("xfs_inactive: vp = %lx vp->v_usecount= %d\n", + (unsigned long)vp, vp?vp->v_usecount:0)); #endif + xn->flags &= ~XFS_STALE; XFSDEB(XDEBVNOPS, ("return: xfs_inactive\n")); @@ -943,7 +960,7 @@ xfs_reclaim_common(struct vnode *vp) struct xfs *xfsp = XFS_FROM_VNODE(vp); struct xfs_node *xn = VNODE_TO_XNODE(vp); - XFSDEB(XDEBVNOPS, ("xfs_reclaim: %lx", + XFSDEB(XDEBVNOPS, ("xfs_reclaim: %lx\n", (unsigned long)vp)); XFS_TOKEN_CLEAR(xn, @@ -998,7 +1015,7 @@ xfs_advlock_common(struct vnode *dvp, msg.cred.uid = 0; msg.cred.pag = XFS_ANONYMOUSID; } - error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } |