[OpenAFS-devel] Re: understanding afs_remunlink() and why .__afsXXX don't get cleaned up (FIXED!)

chas williams - CONTRACTOR chas@cmf.nrl.navy.mil
Wed, 28 Feb 2007 11:01:48 -0500


In message <x3r6sayjx8.fsf_-_@nowhere.com>,Adam Megacz writes:
>I can confirm that this patch fixes the problem -- no more .__afsXXX
>leftovers after applying this to 1.4.3rc2.  Thank you!!
>
>Hopefully this will get folded into the OpenAFS source at some point...

could you try this version.  it adds a vnode_recycle()/cache_purge() 
to the afs_vop_inactive() if it stumbles across an unlinked file.

also, it adds a vnode_recycle() for successful rmdir's and doesnt 
do cache_purges() when remove operations fail.

--- src/afs/DARWIN/osi_vnodeops.c.000	2007-02-27 16:27:07.000000000 -0500
+++ src/afs/DARWIN/osi_vnodeops.c	2007-02-28 10:58:21.000000000 -0500
@@ -1175,6 +1175,7 @@
     int error = 0;
     register struct vnode *vp = ap->a_vp;
     register struct vnode *dvp = ap->a_dvp;
+    struct vcache *tvc = VTOAFS(vp);
 
 #ifdef AFS_DARWIN80_ENV
     if (ap->a_flags & VNODE_REMOVE_NODELETEBUSY) {
@@ -1189,11 +1190,13 @@
     AFS_GLOCK();
     error = afs_remove(VTOAFS(dvp), name, vop_cn_cred);
     AFS_GUNLOCK();
-    cache_purge(vp);
     if (!error) {
+	cache_purge(vp);
 #ifdef AFS_DARWIN80_ENV
-        ubc_setsize(vp, (off_t)0);
-	vnode_recycle(vp);
+	if (!(tvc->states & CUnlinked)) {
+	    ubc_setsize(vp, (off_t)0);
+	    vnode_recycle(vp);
+        }
 #else
         /* necessary so we don't deadlock ourselves in vclean */
         VOP_UNLOCK(vp, 0, cnp->cn_proc);
@@ -1498,8 +1501,13 @@
     error = afs_rmdir(VTOAFS(dvp), name, vop_cn_cred);
     AFS_GUNLOCK();
     DROPNAME();
-    cache_purge(dvp);
-    cache_purge(vp);
+    if (!error) {
+#ifdef AFS_DARWIN80_ENV
+        vnode_recycle(vp);
+#endif
+	cache_purge(dvp);
+	cache_purge(vp);
+    }
 #ifndef AFS_DARWIN80_ENV
     vput(dvp);
     vput(vp);
@@ -1624,9 +1632,18 @@
 	vprint("afs_vop_inactive(): pushing active", vp);
 #endif
     if (tvc) {
-       AFS_GLOCK();
-       afs_InactiveVCache(tvc, 0);	/* decrs ref counts */
-       AFS_GUNLOCK();
+#ifdef AFS_DARWIN80_ENV
+	int unlinked = tvc->states & CUnlinked;
+#endif
+	AFS_GLOCK();
+	afs_InactiveVCache(tvc, 0);	/* decrs ref counts */
+	AFS_GUNLOCK();
+#ifdef AFS_DARWIN80_ENV
+	if (unlinked) {
+	    vnode_recycle(vp);
+	    cache_purge(vp);
+	}
+#endif
     }
 #ifndef AFS_DARWIN80_ENV
     VOP_UNLOCK(vp, 0, ap->a_p);