afs: only reset access caches for the matching cell
authorMark Vitale <mvitale@sinenomine.net>
Thu, 3 Apr 2014 20:37:51 +0000 (16:37 -0400)
committerD Brashear <shadow@your-file-system.com>
Thu, 5 Jun 2014 11:20:40 +0000 (07:20 -0400)
When an AFS user's tokens change (unlog, aklog) or expire,
afs_ResetAccessCache() is called to reset all the access caches
for that uid/PAG.

However, a user/PAG may have tokens for multiple cells, and they
may expire or be set/reset at different times.  Therefore, it is
incorrect to assume that all access caches for a uid/PAG should
be discarded when only one cell's tokens have changed.

Modify afs_ResetAccessCache() to acccept a new argument 'cell',
and only reset the access caches for a uid/PAG if the vcache
resides in the specified cell.  If the caller really wants to
reset all a user's access caches, specify cell=-1.

For cache managers that are running with multiple PAGs and multiple
cells, this should improve performance because 1) it avoids
scanning access caches chains for vcaches that are not part of the
current cell and 2) it avoids deleting access caches that may still
good, thus preventing unnecessary FetchStatus calls.

Change-Id: Id4c138dab45fd48265a4029880a5d57947e67a52
Reviewed-on: http://gerrit.openafs.org/11070
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: D Brashear <shadow@your-file-system.com>

src/afs/afs_prototypes.h
src/afs/afs_user.c

index 6a1db16..6e51879 100644 (file)
@@ -1004,7 +1004,7 @@ extern void afs_ComputePAGStats(void);
 extern void afs_PutUser(struct unixuser *au, afs_int32 locktype);
 extern void afs_GCUserData(int aforce);
 extern void afs_CheckTokenCache(void);
-extern void afs_ResetAccessCache(afs_int32 uid, int alock);
+extern void afs_ResetAccessCache(afs_int32 uid, afs_int32 cell, int alock);
 extern void afs_ResetUserConns(struct unixuser *auser);
 extern void afs_SetPrimary(struct unixuser *au, int aflag);
 extern void afs_MarkUserExpired(afs_int32 pag);
index 0b63550..7f7468c 100644 (file)
@@ -50,7 +50,7 @@ struct unixuser *afs_users[NUSERS];
 
 #ifndef AFS_PAG_MANAGER
 /* Forward declarations */
-void afs_ResetAccessCache(afs_int32 uid, int alock);
+void afs_ResetAccessCache(afs_int32 uid, afs_int32 cell, int alock);
 #endif /* !AFS_PAG_MANAGER */
 
 
@@ -218,8 +218,13 @@ done:
 }                              /*afs_CheckTokenCache */
 
 
+/* Remove any access caches associated with this uid+cell
+ * by scanning the entire vcache table.  Specify cell=-1
+ * to remove all access caches associated with this uid
+ * regardless of cell.
+ */
 void
-afs_ResetAccessCache(afs_int32 uid, int alock)
+afs_ResetAccessCache(afs_int32 uid, afs_int32 cell, int alock)
 {
     int i;
     struct vcache *tvc;
@@ -232,8 +237,11 @@ afs_ResetAccessCache(afs_int32 uid, int alock)
        for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
            /* really should do this under cache write lock, but that.
             * is hard to under locking hierarchy */
-           if (tvc->Access && (ac = afs_FindAxs(tvc->Access, uid))) {
-               afs_RemoveAxs(&tvc->Access, ac);
+           if (tvc->Access && (cell == -1 || tvc->f.fid.Cell == cell)) {
+               ac = afs_FindAxs(tvc->Access, uid);
+               if (ac) {
+                   afs_RemoveAxs(&tvc->Access, ac);
+               }
            }
        }
     }
@@ -272,7 +280,7 @@ afs_ResetUserConns(struct unixuser *auser)
 
     ReleaseWriteLock(&afs_xconn);
     ReleaseReadLock(&afs_xsrvAddr);
-    afs_ResetAccessCache(auser->uid, 1);
+    afs_ResetAccessCache(auser->uid, auser->cell, 1);
     auser->states &= ~UNeedsReset;
 }                              /*afs_ResetUserConns */
 #endif /* !AFS_PAG_MANAGER */