[OpenAFS-devel] Re: understanding afs_remunlink() and why .__afsXXX don't get cleaned up (FIXED!)
chas williams - CONTRACTOR
chas@cmf.nrl.navy.mil
Thu, 01 Mar 2007 14:43:51 -0500
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);