Here is the latest patch for -stable.  vmiodirenable is turned on by
    default, the cache purge code is enabled based on vmiodirenable, and
    I added a new sysctl called nameileafonly which defaults to ON (1).

    nameileafonly vmiodirenable action
        1               1       (DEFAULT) purge leaf dirs on vnode reclaim
        0               1       purge any dir on vnode reclaim
        1               0       purge leaf dirs on vnode reclaim
        0               0       do not purge dirs on vnode reclaim
        -1              0       puger any dir on vnode reclaim

Index: sys/vnode.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/vnode.h,v
retrieving revision 1.111.2.12
diff -u -r1.111.2.12 vnode.h
--- sys/vnode.h 2001/09/22 09:21:48     1.111.2.12
+++ sys/vnode.h 2001/09/23 21:18:00
@@ -550,6 +550,7 @@
            struct componentname *cnp));
 void   cache_purge __P((struct vnode *vp));
 void   cache_purgevfs __P((struct mount *mp));
+int    cache_leaf_test __P((struct vnode *vp));
 void   cvtstat __P((struct stat *st, struct ostat *ost));
 void   cvtnstat __P((struct stat *sb, struct nstat *nsb));
 int    getnewvnode __P((enum vtagtype tag,
Index: kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.242.2.9
diff -u -r1.242.2.9 vfs_bio.c
--- kern/vfs_bio.c      2001/06/03 05:00:09     1.242.2.9
+++ kern/vfs_bio.c      2001/09/23 20:24:47
@@ -82,7 +82,7 @@
  * but the code is intricate enough already.
  */
 vm_page_t bogus_page;
-int vmiodirenable = FALSE;
+int vmiodirenable = TRUE;
 int runningbufspace;
 static vm_offset_t bogus_offset;
 
Index: kern/vfs_cache.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_cache.c,v
retrieving revision 1.42.2.4
diff -u -r1.42.2.4 vfs_cache.c
--- kern/vfs_cache.c    2001/03/21 10:50:58     1.42.2.4
+++ kern/vfs_cache.c    2001/09/23 21:18:24
@@ -405,6 +405,31 @@
 }
 
 /*
+ * cache_leaf_test()
+ *
+ *     Test whether this (directory) vnode's namei cache entry contains
+ *     subdirectories or not.  Used to determine whether the directory is
+ *     a leaf in the namei cache or not.  Note: the directory may still
+ *     contain files in the namei cache.
+ *
+ *     Returns 0 if the directory is a leaf, -1 if it isn't.
+ */
+int
+cache_leaf_test(struct vnode *vp)
+{
+       struct namecache *ncpc;
+
+       for (ncpc = LIST_FIRST(&vp->v_cache_src);
+            ncpc != NULL;
+            ncpc = LIST_NEXT(ncpc, nc_src)
+       ) {
+               if (ncpc->nc_vp != NULL && ncpc->nc_vp->v_type == VDIR)
+                       return(0);
+       }
+       return(-1);
+}
+
+/*
  * Perform canonical checks and cache lookup and pass on to filesystem
  * through the vop_cachedlookup only if needed.
  */
Index: kern/vfs_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.249.2.11
diff -u -r1.249.2.11 vfs_subr.c
--- kern/vfs_subr.c     2001/09/11 09:49:53     1.249.2.11
+++ kern/vfs_subr.c     2001/09/23 21:18:20
@@ -113,6 +113,8 @@
 SYSCTL_INT(_vfs, OID_AUTO, reassignbufsortbad, CTLFLAG_RW, &reassignbufsortbad, 0, 
"");
 static int reassignbufmethod = 1;
 SYSCTL_INT(_vfs, OID_AUTO, reassignbufmethod, CTLFLAG_RW, &reassignbufmethod, 0, "");
+static int nameileafonly = 1;
+SYSCTL_INT(_vfs, OID_AUTO, nameileafonly, CTLFLAG_RW, &nameileafonly, 0, "");
 
 #ifdef ENABLE_VFS_IOOPT
 int vfs_ioopt = 0;
@@ -506,13 +508,32 @@
                                TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
                                TAILQ_INSERT_TAIL(&vnode_tmp_list, vp, v_freelist);
                                continue;
-                       } else if (LIST_FIRST(&vp->v_cache_src)) {
-                               /* Don't recycle if active in the namecache */
-                               simple_unlock(&vp->v_interlock);
-                               continue;
-                       } else {
-                               break;
                        }
+                       if (LIST_FIRST(&vp->v_cache_src)) {
+                               /* 
+                                * If nameileafonly is set, do not throw
+                                * away directory vnodes unless they are
+                                * leaf nodes in the namecache.
+                                *
+                                * If nameileafonly is not set then throw-aways
+                                * are based on vmiodirenable.  If
+                                * vmiodirenable is turned off we do not throw
+                                * away directory vnodes active in the
+                                * namecache.  The (nameileafonly < 0) test
+                                * is for further debugging only.
+                                */
+                               if (nameileafonly > 0) {
+                                       if (cache_leaf_test(vp) == 0) {
+                                               simple_unlock(&vp->v_interlock);
+                                               continue;
+                                       }
+                               } else if (nameileafonly < 0 || 
+                                           vmiodirenable == 0) {
+                                       simple_unlock(&vp->v_interlock);
+                                       continue;
+                               }
+                       }
+                       break;
                }
        }
 

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to