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

Adam Megacz megacz@cs.berkeley.edu
Sat, 03 Mar 2007 19:22:55 -0800


Sorry for not replying earlier.  This patch works properly when
applied to 1.4.3rc2.

  - a

"chas williams - CONTRACTOR" <chas@cmf.nrl.navy.mil> writes:
> In message <45E725ED.7030800@mikefedyk.com>,Mike Fedyk writes:
>>> 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.
>>
>>I imagine that afs_vop_inactive() somewhere in the directory listing 
>>code.  If so can you print out a warning in the logs?
>>
>>It's good to clean up after a spill, but at least we'll know that there 
>>has been a spill this way.
>
> its not really a spill, its just that afs does its unlink of busy files
> differently.  its similar to nfs, so after looking at the nfs yesterday
> code i spotted this helpful comment in nfs remove stub:
>
> 	/* clear flags now: won't get nfs_inactive for recycled vnode */
>
> so nfs skips the vnode_recycle() and does it cleanup in the inactive
> stub.  the following seems like a good approximation.
>
> Index: src/afs/DARWIN/osi_vnodeops.c
> ===================================================================
> --- src/afs/DARWIN/osi_vnodeops.c	(revision 78)
> +++ src/afs/DARWIN/osi_vnodeops.c	(revision 79)
> @@ -1192,8 +1192,12 @@
>      cache_purge(vp);
>      if (!error) {
>  #ifdef AFS_DARWIN80_ENV
> -        ubc_setsize(vp, (off_t)0);
> -        vnode_recycle(vp);
> +	struct vcache *tvc = VTOAFS(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);
> @@ -1619,14 +1623,24 @@
>  {
>      register struct vnode *vp = ap->a_vp;
>      struct vcache *tvc = VTOAFS(vp);
> +
>  #ifndef AFS_DARWIN80_ENV
>      if (prtactive && vp->v_usecount != 0)
>  	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);

-- 
PGP/GPG: 5C9F F366 C9CF 2145 E770  B1B8 EFB1 462D A146 C380