linux26-dcache-lock-20050116
authorChaskiel M Grundman <cg2v@andrew.cmu.edu>
Sun, 16 Jan 2005 16:43:34 +0000 (16:43 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sun, 16 Jan 2005 16:43:34 +0000 (16:43 +0000)
FIXES 17266

"The changes I submitted previously, and committed as
linux-26-vlru-cycle-20041012 do not satisfy necessary invariants of the
dcache api.

1) the dcache_lock is not held when calling d_unhashed and
list_empty(&dentry->d_subdirs)
2) the caller of d_prune_aliases does not hold it's own ref on the inode

Patch attached.(has been used lightly for a month or so)"

src/afs/afs_vcache.c

index 9d4ff99..6e38da8 100644 (file)
@@ -842,16 +842,24 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
 #if defined(AFS_LINUX26_ENV)
                 struct dentry *dentry;
                 struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
+                AFS_FAST_HOLD(tvc);
                 AFS_GUNLOCK();
+shrink_restart:
+                DLOCK();
                 cur=head;
                 while ((cur = cur->next) != head) {
                     dentry = list_entry(cur, struct dentry, d_alias);
                     if (!d_unhashed(dentry) &&
-                        !list_empty(&dentry->d_subdirs))
+                        !list_empty(&dentry->d_subdirs)) {
+                        DUNLOCK();
                        shrink_dcache_parent(dentry);
+                        goto shrink_restart;
+                    }
                 }
+                DUNLOCK();
                 d_prune_aliases(AFSTOI(tvc));
                 AFS_GLOCK();
+                AFS_FAST_RELE(tvc);
 #else
                afs_TryFlushDcacheChildren(tvc);
 #endif