Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jun 2011 09:58:52 GMT
From:      Ilya Putsikau <ilya@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 195359 for review
Message-ID:  <201106260958.p5Q9wqx1012776@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@195359?ac=10

Change 195359 by ilya@ilya_triton2011 on 2011/06/26 09:58:02

	Add fuse_internal_vnode_disappear, reclaim vnode in vnop_inactive
	Disappear vnode in vnop_remove and vnop_rmdir
	Add debug sysctl to reclaim vnodes in vop_inactive

Affected files ...

.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.c#10 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#15 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#15 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#11 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#31 edit

Differences ...

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.c#10 (text+ko) ====

@@ -84,10 +84,7 @@
     if ((err = fdisp_wait_answ(&fdi))) {
         debug_printf("OUCH ... daemon didn't give fh (err = %d)\n", err);
         if (err == ENOENT) {
-            /*
-             * See comment in fuse_vnop_reclaim().
-             */
-            cache_purge(vp);
+            fuse_internal_vnode_disappear(vp);
         }
         return err;
     }

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#15 (text+ko) ====

@@ -574,6 +574,16 @@
     fuse_insert_message(fdip->tick);
 }
 
+void
+fuse_internal_vnode_disappear(struct vnode *vp)
+{
+    struct fuse_vnode_data *fvdat = VTOFUD(vp);
+
+    ASSERT_VOP_ELOCKED(vp, "fuse_internal_vnode_disappear");
+    fvdat->flag |= FN_REVOKED;
+    cache_purge(vp);
+}
+
 /* fuse start/stop */
 
 int

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#15 (text+ko) ====

@@ -269,6 +269,10 @@
                      struct componentname *fcnp,
                      struct vnode *tdvp,
                      struct componentname *tcnp);
+/* revoke */
+
+void
+fuse_internal_vnode_disappear(struct vnode *vp);
 
 /* strategy */
 

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#11 (text+ko) ====

@@ -11,7 +11,8 @@
 
 #include "fuse_file.h"
 
-#define FN_CREATING      0x00000001
+#define FN_CREATING          0x00000002
+#define FN_REVOKED           0x00000020
 
 struct fuse_vnode_data {
     /** self **/

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#31 (text+ko) ====

@@ -126,6 +126,10 @@
 SYSCTL_INT(_vfs_fuse, OID_AUTO, lookup_cache_enable, CTLFLAG_RW,
            &fuse_lookup_cache_enable, 0, "");
 
+static int fuse_reclaim_inactive = 0;
+SYSCTL_INT(_vfs_fuse, OID_AUTO, reclaim_inactive, CTLFLAG_RW,
+           &fuse_reclaim_inactive, 0, "");
+
 int fuse_pbuf_freecnt = -1;
 
 /*
@@ -484,7 +488,9 @@
             /* see comment at similar place in fuse_statfs() */
             goto fake;
         }
-        debug_printf("fuse_getattr c: returning ENOTCONN\n");
+        if (err == ENOENT) {
+            fuse_internal_vnode_disappear(vp);
+        }
         return err;
     }
 
@@ -517,10 +523,15 @@
              * vp->vtype = vap->v_type
              */
         } else {
-            /* stale vnode */
-            // XXX: vnode should be ditched.
-            debug_printf("fuse_getattr d: returning ENOTCONN\n");
-            return ENOTCONN;
+            /*
+             * STALE vnode, ditch
+             *
+             * The vnode has changed its type "behind our back". There's
+             * nothing really we can do, so let us just force an internal
+             * revocation.
+             */
+            fuse_internal_vnode_disappear(vp);
+            return EIO;
         }
     }
 
@@ -561,6 +572,10 @@
         }
     }
 
+    if ((fvdat->flag & FN_REVOKED) != 0 || fuse_reclaim_inactive) {
+        vrecycle(vp, td);
+    }
+
     return 0;
 }
 
@@ -1416,7 +1431,7 @@
     err = fuse_internal_remove(dvp, vp, cnp, FUSE_UNLINK);
 
     if (err == 0) {
-        cache_purge(vp);
+        fuse_internal_vnode_disappear(vp);
         fuse_invalidate_attr(dvp);
     }
 
@@ -1526,11 +1541,10 @@
         return EINVAL;
     }
 
-    cache_purge(ap->a_vp);
-
-    err = fuse_internal_remove(ap->a_dvp, ap->a_vp, ap->a_cnp, FUSE_RMDIR);
+    err = fuse_internal_remove(dvp, vp, ap->a_cnp, FUSE_RMDIR);
 
     if (err == 0) {
+        fuse_internal_vnode_disappear(vp);
         fuse_invalidate_attr(dvp);
     }
 
@@ -1690,8 +1704,15 @@
         if (vnode_vtype(vp) == VNON && vtyp != VNON) {
             debug_printf("FUSE: Dang! vnode_vtype is VNON and vtype isn't.\n");
         } else {
-            // XXX: should ditch vnode.
-            err = ENOTCONN;
+            /*
+             * STALE vnode, ditch
+             *
+             * The vnode has changed its type "behind our back". There's
+             * nothing really we can do, so let us just force an internal
+             * revocation and tell the caller to try again, if interested.
+             */
+            fuse_internal_vnode_disappear(vp);
+            err = EAGAIN;
         }
     }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106260958.p5Q9wqx1012776>