Get rid of the weird FSMID update path in the vnode and namecache code.
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 25 Apr 2006 22:11:32 +0000 (22:11 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 25 Apr 2006 22:11:32 +0000 (22:11 +0000)
Instead, mark the vnode as needing an FSMID update when the vnode is
disconnected from the namecache.

This fixes a bug where FSMID updates were being lost at unmount time.

sys/kern/vfs_cache.c
sys/kern/vfs_subr.c
sys/kern/vfs_vopops.c
sys/sys/namecache.h
sys/sys/vfsops.h
sys/sys/vnode.h
sys/vfs/nfs/nfs_socket.c
sys/vfs/ufs/ufs_inode.c
sys/vfs/ufs/ufs_vnops.c

index 5aab9f1..a415562 100644 (file)
@@ -67,7 +67,7 @@
  *
  *     @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
  * $FreeBSD: src/sys/kern/vfs_cache.c,v 1.42.2.6 2001/10/05 20:07:03 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_cache.c,v 1.63 2006/04/25 19:36:03 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_cache.c,v 1.64 2006/04/25 22:11:28 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -286,7 +286,6 @@ static struct namecache *
 cache_alloc(int nlen)
 {
        struct namecache *ncp;
-       static int fsmid_roller;
 
        ncp = malloc(sizeof(*ncp), M_VFSCACHE, M_WAITOK|M_ZERO);
        if (nlen)
@@ -301,9 +300,7 @@ cache_alloc(int nlen)
         * roller for uniqueness.  This is used to generate a useful
         * FSMID for filesystems which do not support it.
         */
-       ncp->nc_fsmid = ((int64_t)time_second << 32) |
-                       (fsmid_roller & 0x7FFFFFFF);
-       ++fsmid_roller;
+       ncp->nc_fsmid = cache_getnewfsmid();
        TAILQ_INIT(&ncp->nc_list);
        cache_lock(ncp);
        return(ncp);
@@ -576,8 +573,6 @@ cache_setunresolved(struct namecache *ncp)
 
        if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
                ncp->nc_flag |= NCF_UNRESOLVED;
-               ncp->nc_flag &= ~(NCF_WHITEOUT|NCF_ISDIR|NCF_ISSYMLINK|
-                                 NCF_FSMID);
                ncp->nc_timeout = 0;
                ncp->nc_error = ENOTCONN;
                ++numunres;
@@ -592,6 +587,8 @@ cache_setunresolved(struct namecache *ncp)
                         * ncp is held by that ncp.  These conditions must be
                         * undone when the vp is cleared out from the ncp.
                         */
+                       if (ncp->nc_flag & NCF_FSMID)
+                               vupdatefsmid(vp);
                        if (!TAILQ_EMPTY(&ncp->nc_list))
                                vdrop(vp);
                        if (ncp->nc_exlocks)
@@ -600,6 +597,8 @@ cache_setunresolved(struct namecache *ncp)
                        TAILQ_REMOVE(&ncneglist, ncp, nc_vnode);
                        --numneg;
                }
+               ncp->nc_flag &= ~(NCF_WHITEOUT|NCF_ISDIR|NCF_ISSYMLINK|
+                                 NCF_FSMID);
        }
 }
 
@@ -700,7 +699,7 @@ cache_inval(struct namecache *ncp, int flags)
  * any time if not locked, even if held.
  */
 int
-cache_inval_vp(struct vnode *vp, int flags, int *retflags)
+cache_inval_vp(struct vnode *vp, int flags)
 {
        struct namecache *ncp;
        struct namecache *next;
@@ -722,7 +721,6 @@ restart:
                                cache_drop(next);
                        goto restart;
                }
-               *retflags |= ncp->nc_flag & NCF_FSMID;
                cache_inval(ncp, flags);
                cache_put(ncp);         /* also releases reference */
                ncp = next;
@@ -1906,17 +1904,13 @@ vfs_cache_setroot(struct vnode *nvp, struct namecache *ncp)
  * XXX: v_id wraparound.  The period of resistance can be extended
  * XXX: by incrementing each vnodes v_id individually instead of
  * XXX: using the global v_id.
- *
- * Does not support NCP_FSMID accumulation on invalidation (retflags is
- * not used).
  */
 void
 cache_purge(struct vnode *vp)
 {
        static u_long nextid;
-       int retflags = 0;
 
-       cache_inval_vp(vp, CINV_DESTROY | CINV_CHILDREN, &retflags);
+       cache_inval_vp(vp, CINV_DESTROY | CINV_CHILDREN);
 
        /*
         * Calculate a new unique id for ".." handling
@@ -1961,6 +1955,22 @@ cache_purgevfs(struct mount *mp)
        }
 }
 
+/*
+ * Create a new (theoretically) unique fsmid
+ */
+int64_t
+cache_getnewfsmid(void)
+{
+       static int fsmid_roller;
+       int64_t fsmid;
+
+       ++fsmid_roller;
+       fsmid = ((int64_t)time_second << 32) |
+                       (fsmid_roller & 0x7FFFFFFF);
+       return (fsmid);
+}
+
+
 static int disablecwd;
 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, "");
 
index a2b3161..e5ae5cf 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_subr.c  8.31 (Berkeley) 5/26/95
  * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_subr.c,v 1.77 2006/04/24 22:01:18 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_subr.c,v 1.78 2006/04/25 22:11:28 dillon Exp $
  */
 
 /*
@@ -274,6 +274,12 @@ struct vinvalbuf_bp_info {
        int flags;
 };
 
+void
+vupdatefsmid(struct vnode *vp)
+{
+       atomic_set_int(&vp->v_flag, VFSMID);
+}
+
 int
 vinvalbuf(struct vnode *vp, int flags, struct thread *td,
        int slpflag, int slptimeo)
@@ -1034,7 +1040,6 @@ void
 vclean(struct vnode *vp, int flags, struct thread *td)
 {
        int active;
-       int retflags = 0;
        int n;
        vm_object_t object;
 
@@ -1048,7 +1053,7 @@ vclean(struct vnode *vp, int flags, struct thread *td)
        /*
         * Scrap the vfs cache
         */
-       while (cache_inval_vp(vp, 0, &retflags) != 0) {
+       while (cache_inval_vp(vp, 0) != 0) {
                printf("Warning: vnode %p clean/cache_resolution race detected\n", vp);
                tsleep(vp, 0, "vclninv", 2);
        }
@@ -1110,7 +1115,7 @@ vclean(struct vnode *vp, int flags, struct thread *td)
        /*
         * Reclaim the vnode.
         */
-       if (VOP_RECLAIM(vp, retflags, td))
+       if (VOP_RECLAIM(vp, td))
                panic("vclean: cannot reclaim");
 
        /*
index 44e2c87..70cef21 100644 (file)
@@ -32,7 +32,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.20 2006/03/29 18:44:50 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.21 2006/04/25 22:11:28 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -793,7 +793,7 @@ vop_inactive(struct vop_ops *ops, struct vnode *vp, struct thread *td)
 }
 
 int
-vop_reclaim(struct vop_ops *ops, struct vnode *vp, int retflags, struct thread *td)
+vop_reclaim(struct vop_ops *ops, struct vnode *vp, struct thread *td)
 {
        struct vop_reclaim_args ap;
        int error;
@@ -802,7 +802,6 @@ vop_reclaim(struct vop_ops *ops, struct vnode *vp, int retflags, struct thread *
        ap.a_head.a_ops = ops;
        ap.a_vp = vp;
        ap.a_td = td;
-       ap.a_retflags = retflags;       /* return to filesystem inode */
 
        DO_OPS(ops, error, &ap, vop_reclaim);
        return(error);
index 703af90..e635cfd 100644 (file)
@@ -62,7 +62,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/namecache.h,v 1.23 2006/03/30 02:39:48 dillon Exp $
+ * $DragonFly: src/sys/sys/namecache.h,v 1.24 2006/04/25 22:11:29 dillon Exp $
  */
 
 #ifndef _SYS_NAMECACHE_H_
@@ -156,7 +156,7 @@ void        cache_setunresolved(struct namecache *ncp);
 struct namecache *cache_nlookup(struct namecache *par, struct nlcomponent *nlc);
 struct namecache *cache_allocroot(struct mount *mp, struct vnode *vp);
 int    cache_inval(struct namecache *ncp, int flags);
-int    cache_inval_vp(struct vnode *vp, int flags, int *retflags);
+int    cache_inval_vp(struct vnode *vp, int flags);
 void   vfs_cache_setroot(struct vnode *vp, struct namecache *ncp);
 
 int    cache_resolve(struct namecache *ncp, struct ucred *cred);
@@ -177,6 +177,7 @@ int cache_fullpath(struct proc *, struct namecache *, char **, char **);
 void   cache_update_fsmid(struct namecache *);
 void   cache_update_fsmid_vp(struct vnode *);
 int    cache_check_fsmid_vp(struct vnode *, int64_t *);
+int64_t cache_getnewfsmid(void);
 
 #endif
 
index ef6e269..68024bf 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/vfsops.h,v 1.18 2006/03/29 18:44:52 dillon Exp $
+ * $DragonFly: src/sys/sys/vfsops.h,v 1.19 2006/04/25 22:11:29 dillon Exp $
  */
 
 /*
@@ -299,7 +299,6 @@ struct vop_reclaim_args {
        struct vop_generic_args a_head;
        struct vnode *a_vp;
        struct thread *a_td;
-       int a_retflags;
 };
 
 struct vop_lock_args {
@@ -781,8 +780,7 @@ int vop_readdir(struct vop_ops *ops, struct vnode *vp, struct uio *uio,
 int vop_readlink(struct vop_ops *ops, struct vnode *vp, struct uio *uio,
                struct ucred *cred);
 int vop_inactive(struct vop_ops *ops, struct vnode *vp, struct thread *td);
-int vop_reclaim(struct vop_ops *ops, struct vnode *vp, int retflags,
-               struct thread *td);
+int vop_reclaim(struct vop_ops *ops, struct vnode *vp, struct thread *td);
 int vop_lock(struct vop_ops *ops, struct vnode *vp,
                int flags, struct thread *td);
 int vop_unlock(struct vop_ops *ops, struct vnode *vp,
@@ -1021,8 +1019,8 @@ extern struct vnodeop_desc vop_nrename_desc;
        vop_readlink(*(vp)->v_ops, vp, uio, cred)
 #define VOP_INACTIVE(vp, td)                           \
        vop_inactive(*(vp)->v_ops, vp, td)
-#define VOP_RECLAIM(vp, retflags, td)                  \
-       vop_reclaim(*(vp)->v_ops, vp, retflags, td)
+#define VOP_RECLAIM(vp, td)                            \
+       vop_reclaim(*(vp)->v_ops, vp, td)
 #define VOP_LOCK(vp, flags, td)                                \
        vop_lock(*(vp)->v_ops, vp, flags, td)
 #define VOP_UNLOCK(vp, flags, td)                      \
index 145e366..1a2b4e3 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)vnode.h     8.7 (Berkeley) 2/4/94
  * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/sys/vnode.h,v 1.48 2006/04/24 22:01:20 dillon Exp $
+ * $DragonFly: src/sys/sys/vnode.h,v 1.49 2006/04/25 22:11:29 dillon Exp $
  */
 
 #ifndef _SYS_VNODE_H_
@@ -158,7 +158,7 @@ RB_HEAD(buf_rb_tree, buf);
 RB_HEAD(buf_rb_hash, buf);
 
 struct vnode {
-       u_long  v_flag;                         /* vnode flags (see below) */
+       int     v_flag;                         /* vnode flags (see below) */
        int     v_usecount;                     /* reference count of users */
        int     v_writecount;
        int     v_holdcnt;                      /* page & buffer references */
@@ -232,7 +232,7 @@ struct vnode {
 #define        VISTTY          0x00008 /* vnode represents a tty */
 #define VCTTYISOPEN    0x00010 /* controlling terminal tty is open */
 #define VCKPT          0x00020 /* checkpoint-restored vnode */
-/* open for business    0x00040 */
+#define VFSMID         0x00040 /* request FSMID update */
 /* open for business    0x00080 */
 /* open for business    0x00100 */
 /* open for business    0x00200 */
@@ -591,6 +591,7 @@ void        insmntque(struct vnode *vp, struct mount *mp);
 
 void   vclean (struct vnode *vp, int flags, struct thread *td);
 void   vgone (struct vnode *vp);
+void   vupdatefsmid (struct vnode *vp);
 int    vinvalbuf (struct vnode *vp, int save, 
            struct thread *td, int slpflag, int slptimeo);
 int    vtruncbuf (struct vnode *vp, struct thread *td,
index 4227cf7..d45f6fd 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_socket.c        8.5 (Berkeley) 3/30/95
  * $FreeBSD: src/sys/nfs/nfs_socket.c,v 1.60.2.6 2003/03/26 01:44:46 alfred Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_socket.c,v 1.33 2006/03/27 16:18:39 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_socket.c,v 1.34 2006/04/25 22:11:31 dillon Exp $
  */
 
 /*
@@ -937,7 +937,6 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum,
        int t1, error = 0, mrest_len, auth_len, auth_type;
        int trylater_delay = 15, trylater_cnt = 0, failed_auth = 0;
        int verf_len, verf_type;
-       int retdummy;
        u_int32_t xid;
        char *auth_str, *verf_str;
        NFSKERBKEY_T key;               /* save session key */
@@ -1176,8 +1175,7 @@ tryagain:
                         * lookup cache, just in case.
                         */
                        if (error == ESTALE) {
-                               retdummy = 0;
-                               cache_inval_vp(vp, CINV_CHILDREN, &retdummy);
+                               cache_inval_vp(vp, CINV_CHILDREN);
                        }
                        if (nmp->nm_flag & NFSMNT_NFSV3) {
                                *mrp = mrep;
index cd13906..900e789 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)ufs_inode.c 8.9 (Berkeley) 5/14/95
  * $FreeBSD: src/sys/ufs/ufs/ufs_inode.c,v 1.25.2.3 2002/07/05 22:42:31 dillon Exp $
- * $DragonFly: src/sys/vfs/ufs/ufs_inode.c,v 1.16 2006/04/03 02:02:37 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ufs_inode.c,v 1.17 2006/04/25 22:11:32 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -127,7 +127,8 @@ ufs_reclaim(struct vop_reclaim_args *ap)
         * Lazy updates.
         */
        if (ip) {
-               if (ap->a_retflags & NCF_FSMID) {
+               if (vp->v_flag & VFSMID) {
+                       vp->v_flag &= ~VFSMID;
                        ++ip->i_fsmid;
                        ip->i_flag |= IN_LAZYMOD;
                }
index 1b481f4..17a17d9 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $
- * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.43 2006/04/24 21:45:47 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.44 2006/04/25 22:11:32 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -2172,6 +2172,7 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
        }
 #endif
 #endif /* !SUIDDIR */
+       ip->i_fsmid = cache_getnewfsmid();
        ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
        ip->i_mode = mode;
        tvp->v_type = IFTOVT(mode);     /* Rest init'd in getnewvnode(). */