[OpenAFS] [grand.central.org #19412] OpenAFS-1.3.85 on Solars 10 Problem with pwd after rename of a directory

chas williams - CONTRACTOR chas@cmf.nrl.navy.mil
Fri, 05 Aug 2005 07:31:01 -0400

In message <42F22E0A.70103@anl.gov>,"Douglas E. Engert" writes:
>I thing the v_path was added to make getcwd much more efficient. But
>if the v_path is not correct it will fall back to walking the
>directories and thus running into my problem. It would also appear
>that rename should also change or free v_path, but I don't see this
>being done in other Solaris drivers.

i agree that rename should probably fix v_path so its right.  why isnt
it done by the upper layer?  perhaps it was felt it wasnt necessary
since the cached information will get corrected by the next lookup.

when you do the pwd/getcwd, the v_path of the vnode is used to do
a lookup.  this fails since either the directory no longer exists at
that path or a vnode is found but isnt the vnode currently in hand.
so you lookup .. and read the contents of that directory looking for
the vnode that matches .. and recurse until you find /.  it seems that
dirfindvp() gives up a little too easily when it comes across a bad
vnode is a parent directory.

if you could duplicate the problem with nfs, i suspect you could
get someone at sun to look at the problem.

anyway, the following might be a more correct solution:

Index: src/afs/SOLARIS/osi_vnodeops.c
RCS file: /cvs/openafs/src/afs/SOLARIS/osi_vnodeops.c,v
retrieving revision
diff -u -u -r1.20.2.1 osi_vnodeops.c
--- src/afs/SOLARIS/osi_vnodeops.c	18 Oct 2004 07:11:47 -0000
+++ src/afs/SOLARIS/osi_vnodeops.c	5 Aug 2005 11:01:24 -0000
@@ -2028,7 +2028,27 @@
     register int code;
     code = afs_rename(aodp, aname1, andp, aname2, acred);
+#ifdef AFS_SUN510_ENV
+    if (code == 0) {
+	struct vcache *avcp = NULL;
+	(void) afs_lookup(andp, aname2, &avcp, NULL, 0, NULL, acred);
+	if (avcp) {
+	    struct vnode *vp = AFSTOV(avcp), *pvp = AFSTOV(andp);
+	    mutex_enter(&vp->v_lock);
+	    kmem_free(vp->v_path, strlen(vp->v_path) + 1);
+	    vp->v_path = NULL;
+	    mutex_exit(&vp->v_lock);
+	    VN_SETPATH(afs_globalVp, pvp, vp, aname2, strlen(aname2));
+	    AFS_RELE(avcp);
+	}
+    }
     return (code);

>Not calling the vn_recycle when done with a vnode will leave an old
>v_path value, and some other fields that vn_recycle clears in the vnode
>which  could cause other problems when the vnode is reused by AFS.

the last VN_RELE() doesnt always call vn_recycle().  vn_recycle()
happens when the system needs to reuse that vnode.  otherwise it
can come back out of retirement.