diff options
Diffstat (limited to 'sys/xfs/xfs_vnodeops-common.c')
-rw-r--r-- | sys/xfs/xfs_vnodeops-common.c | 314 |
1 files changed, 198 insertions, 116 deletions
diff --git a/sys/xfs/xfs_vnodeops-common.c b/sys/xfs/xfs_vnodeops-common.c index 0fae847867d..ed102ad1205 100644 --- a/sys/xfs/xfs_vnodeops-common.c +++ b/sys/xfs/xfs_vnodeops-common.c @@ -1,7 +1,5 @@ -/* $OpenBSD: xfs_vnodeops-common.c,v 1.3 2000/03/03 00:54:59 todd Exp $ */ - /* - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -51,10 +49,11 @@ #include <xfs/xfs_syscalls.h> #include <xfs/xfs_vnodeops.h> -RCSID("$OpenBSD: xfs_vnodeops-common.c,v 1.3 2000/03/03 00:54:59 todd Exp $"); +RCSID("$Id: xfs_vnodeops-common.c,v 1.4 2000/09/11 14:26:54 art Exp $"); int -xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok) +xfs_open_valid(struct vnode *vp, struct ucred *cred, struct proc *p, + u_int tok) { struct xfs *xfsp = XFS_FROM_VNODE(vp); struct xfs_node *xn = VNODE_TO_XNODE(vp); @@ -71,7 +70,9 @@ xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok) msg.cred.pag = xfs_get_pag(cred); msg.handle = xn->handle; msg.tokens = tok; + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } else { @@ -86,12 +87,13 @@ done: } int -xfs_attr_valid(struct vnode * vp, struct ucred * cred, u_int tok) +xfs_attr_valid(struct vnode *vp, struct ucred *cred, struct proc *p, + u_int tok) { struct xfs *xfsp = XFS_FROM_VNODE(vp); struct xfs_node *xn = VNODE_TO_XNODE(vp); int error = 0; - pag_t pag = xfs_get_pag(cred); + xfs_pag_t pag = xfs_get_pag(cred); do { if (!XFS_TOKEN_GOT(xn, tok)) { @@ -114,13 +116,13 @@ done: } int -xfs_fetch_rights(struct vnode * vp, struct ucred * cred) +xfs_fetch_rights(struct vnode *vp, struct ucred *cred, struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(vp); struct xfs_node *xn = VNODE_TO_XNODE(vp); int error = 0; - pag_t pag = xfs_get_pag(cred); + xfs_pag_t pag = xfs_get_pag(cred); do { if (!xfs_has_pag(xn, pag)) { @@ -144,7 +146,8 @@ done: } int -xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok) +xfs_data_valid(struct vnode *vp, struct ucred *cred, struct proc *p, + u_int tok) { struct xfs *xfsp = XFS_FROM_VNODE(vp); struct xfs_node *xn = VNODE_TO_XNODE(vp); @@ -159,7 +162,9 @@ xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok) msg.cred.pag = xfs_get_pag(cred); msg.handle = xn->handle; msg.tokens = tok; + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } else { @@ -171,14 +176,46 @@ done: return error; } +int +xfs_open_common(struct vnode *vp, + int mode, + struct ucred *cred, + struct proc *p) +{ + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + XFSDEB(XDEBVNOPS, ("xfs_open\n")); + + if (mode & FWRITE) { + if (xn->cred) + crfree (xn->cred); + crhold (cred); + xn->cred = cred; + return xfs_open_valid(vp, cred, p, XFS_OPEN_NW); + } else { + return xfs_open_valid(vp, cred, p, XFS_OPEN_NR); + } +} + static int -do_fsync(struct xfs * xfsp, - struct xfs_node * xn, - struct ucred * cred, +do_fsync(struct xfs *xfsp, + struct xfs_node *xn, + struct ucred *cred, + struct proc *p, u_int flag) { int error; struct xfs_message_putdata msg; +#if 0 + struct vnode *vp = XNODE_TO_VNODE(xn); + struct vnode *t = DATA_FROM_XNODE(xn); + + vinvalbuf (vp, V_SAVE, cred, p, 0, 0); + + xfs_vfs_writelock(t, p); + vinvalbuf(t, V_SAVE, cred, p, 0, 0); + xfs_vfs_unlock(t, p); +#endif msg.header.opcode = XFS_MSG_PUTDATA; if (cred != NOCRED) { @@ -193,6 +230,7 @@ do_fsync(struct xfs * xfsp, msg.flag = flag; error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; @@ -210,7 +248,7 @@ xfs_fsync_common(struct vnode *vp, struct ucred *cred, struct xfs_node *xn = VNODE_TO_XNODE(vp); int error = 0; - XFSDEB(XDEBVNOPS, ("xfs_fsync: %p\n", vp)); + XFSDEB(XDEBVNOPS, ("xfs_fsync: %lx\n", (unsigned long)vp)); /* * It seems that fsync is sometimes called after reclaiming a node. @@ -222,8 +260,17 @@ xfs_fsync_common(struct vnode *vp, struct ucred *cred, return 0; } - if (xn->flags & XFS_DATA_DIRTY) - error = do_fsync(xfsp, xn, cred, XFS_WRITE); + if (xn->flags & XFS_DATA_DIRTY) { +#ifdef FSYNC_RECLAIM + /* writing back the data from this vnode failed */ + if (waitfor & FSYNC_RECLAIM) { + printf("xfs_fsync: data lost, failed to write back\n"); + xn->flags &= ~XFS_DATA_DIRTY; + return 0; + } +#endif + error = do_fsync(xfsp, xn, cred, proc, XFS_WRITE | XFS_FSYNC); + } return error; } @@ -236,45 +283,62 @@ xfs_close_common(struct vnode *vp, int fflag, struct xfs_node *xn = VNODE_TO_XNODE(vp); int error = 0; - XFSDEB(XDEBVNOPS, ("xfs_close cred = %p\n", cred)); + XFSDEB(XDEBVNOPS, + ("xfs_close cred = %lx, fflag = %x, xn->flags = %x\n", + (unsigned long)cred, fflag, xn->flags)); if (fflag & FWRITE && xn->flags & XFS_DATA_DIRTY) - error = do_fsync(xfsp, xn, cred, XFS_WRITE); + error = do_fsync(xfsp, xn, cred, proc, XFS_WRITE); return error; } int -xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) +xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, + struct ucred *cred) { int error = 0; + int i; XFSDEB(XDEBVNOPS, ("xfs_read\n")); - error = xfs_data_valid(vp, cred, XFS_DATA_R); + error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uio), XFS_DATA_R); + + XFSDEB(XDEBVNOPS, ("xfs_read: iovcnt: %d\n", uio->uio_iovcnt)); + for (i = 0; i < uio->uio_iovcnt; i++) + XFSDEB(XDEBVNOPS, (" base: %lx len: %d\n", + (unsigned long)uio->uio_iov[i].iov_base, + uio->uio_iov[i].iov_len)); if (error == 0) { struct vnode *t = DATA_FROM_VNODE(vp); xfs_vfs_readlock(t, xfs_uio_to_proc(uio)); -#ifdef __osf__ - VOP_READ(t, uio, ioflag, cred, error); -#else /* __osf__ */ - error = VOP_READ(t, uio, ioflag, cred); -#endif /* __osf__ */ + 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", + (unsigned long)uio->uio_offset, + uio->uio_resid)); + XFSDEB(XDEBVNOPS, ("xfs_read error: %d\n", error)); + return error; } int -xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *cred) +xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, + struct ucred *cred) { int error = 0; XFSDEB(XDEBVNOPS, ("xfs_write\n")); - error = xfs_data_valid(vp, cred, XFS_DATA_W); + error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), XFS_DATA_W); if (error == 0) { struct xfs_node *xn = VNODE_TO_XNODE(vp); @@ -283,26 +347,14 @@ xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *c int error2 = 0; xfs_vfs_writelock(t, xfs_uio_to_proc(uiop)); -#ifdef __osf__ - VOP_WRITE(t, uiop, ioflag, cred, error); - VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY; - VOP_GETATTR(t, &sub_attr, cred, error2); -#else /* __osf__ */ - error = VOP_WRITE(t, uiop, ioflag, cred); + xfs_vop_write(t, uiop, ioflag, cred, error); VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY; - error2 = VOP_GETATTR(t, &sub_attr, cred, uiop->uio_procp); -#endif /* __osf__ */ + xfs_vop_getattr(t, &sub_attr, cred, xfs_uio_to_proc(uiop), error2); if (error2 == 0) { xn->attr.va_size = sub_attr.va_size; xn->attr.va_mtime = sub_attr.va_mtime; -#ifdef UVM - uvm_vnp_setsize(vp, sub_attr.va_size); -#else -#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE - vnode_pager_setsize(vp, sub_attr.va_size); -#endif -#endif + xfs_set_vp_size(vp, sub_attr.va_size); } xfs_vfs_unlock(t, xfs_uio_to_proc(uiop)); } @@ -311,7 +363,8 @@ xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *c } int -xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) +xfs_getattr_common(struct vnode *vp, struct vattr *vap, + struct ucred *cred, struct proc *p) { int error = 0; @@ -319,14 +372,15 @@ xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) XFSDEB(XDEBVNOPS, ("xfs_getattr\n")); - error = xfs_attr_valid(vp, cred, XFS_ATTR_R); + error = xfs_attr_valid(vp, cred, p, XFS_ATTR_R); if (error == 0) *vap = xn->attr; return error; } int -xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) +xfs_setattr_common(struct vnode *vp, struct vattr *vap, + struct ucred *cred, struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(vp); struct xfs_node *xn = VNODE_TO_XNODE(vp); @@ -336,13 +390,13 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) #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,) && - CHECK_XFSATTR(va_size,) && - CHECK_XFSATTR(va_uid,) && - CHECK_XFSATTR(va_gid,) && - CHECK_XFSATTR(va_mtime.tv_sec,) && - CHECK_XFSATTR(va_fileid,) && - CHECK_XFSATTR(va_type,)) + CHECK_XFSATTR(va_nlink,(short)) && + CHECK_XFSATTR(va_size,(u_quad_t)) && + CHECK_XFSATTR(va_uid,(uid_t)) && + CHECK_XFSATTR(va_gid,(gid_t)) && + CHECK_XFSATTR(va_mtime.tv_sec,(unsigned int)) && + CHECK_XFSATTR(va_fileid,(long)) && + CHECK_XFSATTR(va_type,(enum vtype))) return 0; /* Nothing to do */ #undef CHECK_XFSATTR @@ -364,6 +418,18 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) } msg.handle = xn->handle; 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) + XA_SET_SIZE(&msg.attr, vap->va_size); + else + XA_SET_SIZE(&msg.attr, xn->attr.va_size); + } + if (vap->va_mtime.tv_sec != (unsigned int)VNOVAL) + XA_SET_MTIME(&msg.attr, vap->va_mtime.tv_sec); + else + XA_SET_MTIME(&msg.attr, xn->attr.va_mtime.tv_sec); + } XFS_TOKEN_CLEAR(xn, XFS_ATTR_VALID, XFS_ATTR_MASK); error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); @@ -393,14 +459,15 @@ check_rights (u_char rights, int mode) } int -xfs_access_common(struct vnode *vp, int mode, struct ucred *cred) +xfs_access_common(struct vnode *vp, int mode, struct ucred *cred, + struct proc *p) { int error = 0; - pag_t pag = xfs_get_pag(cred); + xfs_pag_t pag = xfs_get_pag(cred); XFSDEB(XDEBVNOPS, ("xfs_access mode = 0%o\n", mode)); - error = xfs_attr_valid(vp, cred, XFS_ATTR_R); + error = xfs_attr_valid(vp, cred, p, XFS_ATTR_R); if (error == 0) { struct xfs_node *xn = VNODE_TO_XNODE(vp); int i; @@ -412,7 +479,7 @@ xfs_access_common(struct vnode *vp, int mode, struct ucred *cred) XFSDEB(XDEBVNOPS, ("xfs_access anonaccess failed\n")); - xfs_fetch_rights(vp, cred); /* ignore error */ + xfs_fetch_rights(vp, cred, p); /* ignore error */ error = EACCES; /* default to EACCES if pag isn't in xn->id */ @@ -445,15 +512,15 @@ xfs_lookup_common(struct vnode *dvp, if (dvp->v_type != VDIR) return ENOTDIR; - - again: + if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { + *vpp = dvp; + VREF(*vpp); + return 0; + } + do { -#ifdef __osf__ - VOP_ACCESS(dvp, VEXEC, cred, error); -#else - error = VOP_ACCESS(dvp, VEXEC, cred, xfs_cnp_to_proc(cnp)); -#endif + xfs_vop_access(dvp, VEXEC, cred, proc, error); if (error != 0) goto done; @@ -490,14 +557,12 @@ xfs_lookup_common(struct vnode *dvp, if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; if(error == ENOENT && cnp->cn_nameiop != CREATE) { - XFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %p (%s, %ld)\n", - dvp, + XFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %lx (%s, %ld)\n", + (unsigned long)dvp, cnp->cn_nameptr, cnp->cn_namelen)); xfs_dnlc_enter (dvp, cnp, NULL); } } else if (error == -1) { - if (xfs_do_vget(*vpp, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp))) - goto again; error = 0; goto done; } @@ -508,29 +573,18 @@ done: } int -xfs_lookup_name(struct vnode *dvp, - const char *name, - struct proc *proc, - struct ucred *cred, - struct vnode **vpp) -{ - xfs_componentname cn; - - xfs_cnp_init (&cn, name, NULL, dvp, proc, cred, CREATE); - return xfs_lookup_common (dvp, &cn, vpp); -} - -int xfs_create_common(struct vnode *dvp, const char *name, struct vattr *vap, - struct ucred *cred) + struct ucred *cred, + struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(dvp); struct xfs_node *xn = VNODE_TO_XNODE(dvp); int error = 0; - XFSDEB(XDEBVNOPS, ("xfs_create: (%s)\n", name)); + XFSDEB(XDEBVNOPS, ("xfs_create: (%lx, %s)\n", + (unsigned long)dvp, name)); { struct xfs_message_create msg; @@ -548,7 +602,9 @@ xfs_create_common(struct vnode *dvp, msg.cred.pag = XFS_ANONYMOUSID; } + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } @@ -565,7 +621,8 @@ int xfs_remove_common(struct vnode *dvp, struct vnode *vp, const char *name, - struct ucred *cred) + struct ucred *cred, + struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(dvp); struct xfs_node *xn = VNODE_TO_XNODE(dvp); @@ -579,6 +636,7 @@ xfs_remove_common(struct vnode *dvp, 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 (error == 0) error = ((struct xfs_message_wakeup *) &msg)->error; @@ -604,7 +662,8 @@ xfs_rename_common(struct vnode *fdvp, struct vnode *tdvp, struct vnode *tvp, const char *tname, - struct ucred *cred) + struct ucred *cred, + struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(fdvp); int error; @@ -641,7 +700,8 @@ int xfs_mkdir_common(struct vnode *dvp, const char *name, struct vattr *vap, - struct ucred *cred) + struct ucred *cred, + struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(dvp); struct xfs_node *xn = VNODE_TO_XNODE(dvp); @@ -674,7 +734,8 @@ int xfs_rmdir_common(struct vnode *dvp, struct vnode *vp, const char *name, - struct ucred *cred) + struct ucred *cred, + struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(dvp); struct xfs_node *xn = VNODE_TO_XNODE(dvp); @@ -703,6 +764,8 @@ xfs_rmdir_common(struct vnode *dvp, vput(dvp); #endif + XFSDEB(XDEBVNOPS, ("xfs_rmdir error: %d\n", error)); + return error; } @@ -710,6 +773,7 @@ int xfs_readdir_common(struct vnode *vp, struct uio *uiop, struct ucred *cred, + struct proc *p, int *eofflag) { int error = 0; @@ -718,18 +782,20 @@ xfs_readdir_common(struct vnode *vp, if(eofflag) *eofflag = 0; - error = xfs_data_valid(vp, cred, XFS_DATA_R); + error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), XFS_DATA_R); if (error == 0) { struct vnode *t = DATA_FROM_VNODE(vp); xfs_vfs_readlock(t, xfs_uio_to_proc(uiop)); -#ifdef __osf__ - VOP_READ(t, uiop, 0, cred, error); -#else - error = VOP_READ(t, uiop, 0, cred); -#endif - if(eofflag) - *eofflag = VNODE_TO_XNODE(vp)->attr.va_size <= uiop->uio_offset; + xfs_vop_read(t, uiop, 0, cred, error); + if (eofflag) { + struct vattr t_attr; + int error2; + + xfs_vop_getattr(t, &t_attr, cred, xfs_uio_to_proc(uiop), error2); + if (error2 == 0) + *eofflag = t_attr.va_size <= uiop->uio_offset; + } xfs_vfs_unlock(t, xfs_uio_to_proc(uiop)); } return error; @@ -739,7 +805,8 @@ int xfs_link_common(struct vnode *dvp, struct vnode *vp, const char *name, - struct ucred *cred) + struct ucred *cred, + struct proc *p) { struct xfs *xfsp = XFS_FROM_VNODE(dvp); struct xfs_node *xn = VNODE_TO_XNODE(dvp); @@ -766,15 +833,16 @@ xfs_link_common(struct vnode *dvp, int xfs_symlink_common(struct vnode *dvp, struct vnode **vpp, - const char *name, - struct proc *proc, - struct ucred *cred, + xfs_componentname *cnp, struct vattr *vap, char *target) { struct xfs *xfsp = XFS_FROM_VNODE(dvp); struct xfs_node *xn = VNODE_TO_XNODE(dvp); + struct proc *proc = xfs_cnp_to_proc(cnp); + struct ucred *cred = xfs_proc_to_cred(proc); struct xfs_message_symlink msg; + const char *name = cnp->cn_nameptr; int error = 0; XFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name)); @@ -794,12 +862,14 @@ xfs_symlink_common(struct vnode *dvp, error = ((struct xfs_message_wakeup *) & msg)->error; if (error == 0) { - error = xfs_lookup_name(dvp, name, proc, cred, vpp); + error = xfs_lookup_common(dvp, cnp, vpp); +#if !defined(__FreeBSD__) || __FreeBSD_version < 400012 if (error == 0) vput (*vpp); +#endif } -#if !defined(__FreeBSD__) || __FreeBSD_version < 300000 +#if !defined(__FreeBSD__) vput(dvp); #endif @@ -813,16 +883,12 @@ xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred) XFSDEB(XDEBVNOPS, ("xfs_readlink\n")); - error = xfs_data_valid(vp, cred, XFS_DATA_R); + error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), XFS_DATA_R); if (error == 0) { struct vnode *t = DATA_FROM_VNODE(vp); xfs_vfs_readlock(t, xfs_uio_to_proc(uiop)); -#ifdef __osf__ - VOP_READ(t, uiop, 0, cred, error); -#else - error = VOP_READ(t, uiop, 0, cred); -#endif + xfs_vop_read(t, uiop, 0, cred, error); xfs_vfs_unlock(t, xfs_uio_to_proc(uiop)); } return error; @@ -831,11 +897,11 @@ xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred) int xfs_inactive_common(struct vnode *vp, struct proc *p) { - struct xfs_message_inactivenode msg; - struct xfs *xfsp = XFS_FROM_VNODE(vp); + int error; struct xfs_node *xn = VNODE_TO_XNODE(vp); - XFSDEB(XDEBVNOPS, ("xfs_inactive, %p\n", vp)); + XFSDEB(XDEBVNOPS, ("xfs_inactive, %lx\n", + (unsigned long)vp)); /* * This seems rather bogus, but sometimes we get an already @@ -847,14 +913,20 @@ xfs_inactive_common(struct vnode *vp, struct proc *p) return 0; } - xn->tokens = 0; - msg.header.opcode = XFS_MSG_INACTIVENODE; - msg.handle = xn->handle; - msg.flag = XFS_NOREFS; - xfs_message_send(xfsp->fd, &msg.header, sizeof(msg)); + /* xn->cred not set -> NOCRED */ + + error = xfs_fsync_common(vp, xn->cred, /* XXX */ 0, p); + if (error) { + printf ("xfs_inactive: failed writing back data: %d\n", error); + } #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)) { + XFSDEB(XDEBVNOPS, ("xfs_inactive: vrecycle\n")); + vrecycle(vp, 0, p); + } #else /* XXX ? */ #endif @@ -871,7 +943,18 @@ 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: %p\n", vp)); + XFSDEB(XDEBVNOPS, ("xfs_reclaim: %lx", + (unsigned long)vp)); + + XFS_TOKEN_CLEAR(xn, + ~0, + XFS_OPEN_MASK | XFS_ATTR_MASK | + XFS_DATA_MASK | XFS_LOCK_MASK); + /* Release, data if we still have it. */ + if (DATA_FROM_XNODE(xn) != 0) { + vrele(DATA_FROM_XNODE(xn)); + DATA_FROM_XNODE(xn) = 0; + } msg.header.opcode = XFS_MSG_INACTIVENODE; msg.handle = xn->handle; @@ -880,7 +963,6 @@ xfs_reclaim_common(struct vnode *vp) xfs_dnlc_purge(vp); free_xfs_node(xn); - return 0; } |