]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Prevent VLRUQ race in ShakeLooseVCaches
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Wed, 4 Nov 2009 23:40:39 +0000 (23:40 +0000)
committerDerrick Brashear <shadow|account-1000005@unknown>
Thu, 5 Nov 2009 04:40:04 +0000 (20:40 -0800)
When ShakeLooseVCaches is called from afs_Daemon, the xvcache lock
is not held. This means that if the GLOCK is dropped for any reason
(for example, whilst purging the dentry cache), then
ShakeLooseVCaches can be raced, end we can end up attempting to
flush the same vcache twice.

The symptoms of this in Linux are that we oops in clear_inode.

Get the xvcache lock in afs_Daemon(), before calling
ShakeLooseVCaches. Also, remove the conditional GLOCK code from
that function. If we don't have the GLOCK on entry, then we're really
in trouble (and both code paths - afs_Daemon and afs_NewVCache should
get the GLOCK for us, anyway)

FIXES 125589

Change-Id: I3fe5b41a661cd162ec73c51492925ad87c6d4c13
Reviewed-on: http://gerrit.openafs.org/781
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
src/afs/afs_daemons.c
src/afs/afs_vcache.c

index 21cf93109c19a3f63eed43570652065417d2e6f2..db5f2a883cf62db8813186155371d969fe81815e 100644 (file)
@@ -127,6 +127,10 @@ afs_CheckServerDaemon(void)
 
 extern int vfs_context_ref;
 
+/* This function always holds the GLOCK whilst it is running. The caller
+ * gets the GLOCK before invoking it, and afs_osi_Sleep drops the GLOCK
+ * whilst we are sleeping, and regains it when we're woken up.
+ */
 void
 afs_Daemon(void)
 {
@@ -219,7 +223,9 @@ afs_Daemon(void)
             else
                 anumber = VCACHE_FREE + (afs_maxvcount - afs_cacheStats);
 
+           ObtainWriteLock(&afs_xvcache, 734);
             afs_ShakeLooseVCaches(anumber);
+           ReleaseWriteLock(&afs_xvcache);
             last5MinCheck = now;
         }
 
index 5d070943a5e4138ebf4325e7ad5dbd0900034df7..6d69b07d6d120f1e17f2719e561fbe7bb95e7076 100644 (file)
@@ -634,13 +634,6 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
     struct afs_q *tq, *uq;
     int code, fv_slept;
     afs_int32 target = anumber;
-    int haveGlock = 1;
-
-    /* Should probably deal better */
-    if (!ISAFS_GLOCK()) {
-       haveGlock = 0;
-       AFS_GLOCK();
-    }
 
     if (afsd_dynamic_vcaches || afs_vcount >= afs_maxvcount) {
        i = 0;
@@ -723,8 +716,6 @@ restart:
 /*
     printf("recycled %d entries\n", target-anumber);
 */
-    if (!haveGlock)
-       AFS_GUNLOCK();
 #endif
     return 0;
 }