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

chas williams - CONTRACTOR chas@cmf.nrl.navy.mil
Tue, 27 Feb 2007 16:48:48 -0500


In message <x364b3a8sn.fsf@nowhere.com>,Adam Megacz writes:
>
>Derrick J Brashear <shadow@dementia.org> writes:
>> On Wed, 3 Jan 2007, chas williams - CONTRACTOR wrote:
>>
>>> In message <x3lkkku88x.fsf@nowhere.com>,Adam Megacz writes:
>>>> http://www.openafs.org/pipermail/openafs-info/2006-October/023804.html
>>>
>>> cute.  i suppose at this point i would put a bit of debugging in
>>> afs_remunlink() and see if its getting called.  i can't see why
>>> it wouldn't.  i suspect you might be having trouble with:
>>>
>>> 	#if defined(AFS_DARWIN80_ENV)
>>> 	    if (vnode_get(AFSTOV(avc))) {
>>> 		ReleaseWriteLock(&avc->lock);
>>> 		return 0;
>>> 	    }
>>> 	#endif
>>>
>>> vnode_get() returns an error if a vnode is marked DEAD or TERMINATE.
>>> i dont see why you wouldnt want to remove the unlinked file in this
>>> case.
>>
>> this is probably it.
>
>Unfortunately, removing that code doesn't appear to fix the problem =(

i didnt forget about this problem.  it just took a bit of time to get
around to it.  anyway, i believe the problem is the vnode_recycle()
when afs doesnt remove the file but instead renames it.

i dont quite understand why this is broken, but it appears that setting
VL_MARKTERM before VL_NEEDINACTIVE keeps vnode_rele_internal() from
marking the vnode with the VL_NEEDINACTIVE flag.

its likely that afs_remunlink() should be calling vnode_recycle()
as well with this fix to force the reclaim a bit sooner.  that
has been left as an exercise for the reader.

--- src/afs/DARWIN/osi_vnodeops.c.000	2007-02-27 16:27:07.000000000 -0500
+++ src/afs/DARWIN/osi_vnodeops.c	2007-02-27 16:29:58.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) {
@@ -1192,8 +1193,10 @@
     cache_purge(vp);
     if (!error) {
 #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);