]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
LINUX: Hold GLOCK for proc traversal
authorAndrew Deason <adeason@sinenomine.net>
Thu, 26 Jul 2012 21:40:03 +0000 (16:40 -0500)
committerDerrick Brashear <shadow@dementix.org>
Sat, 28 Jul 2012 03:19:27 +0000 (20:19 -0700)
The functions that traverse unixuser structures for display via /proc
(uu_start et al) call various libafs functions hold and release locks,
etc. To do any of that, we need GLOCK. Amongst other issues, we can
panic if we try to acquire a contested lock without GLOCK, since we
assert glock is held when we sleep for the lock or try to wake other
waiters. The same goes for the legacy CellServDB proc file.

So, hold and release GLOCK as appropriate.

Change-Id: I9ec2051bc5d914521d12a9d20d28da1076c090fc
Reviewed-on: http://gerrit.openafs.org/7885
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
src/afs/LINUX/osi_proc.c

index ecb1457615d6a7621fa5af59d2c1e13b4cbc1ae9..bb1529bf1c640c5b74636ba9a202b8bebfbfc587 100644 (file)
@@ -134,21 +134,29 @@ static void *
 uu_start(struct seq_file *m, loff_t *pos)
 {
     struct unixuser *tu;
+    void *ret;
     loff_t n = 0;
     afs_int32 i;
 
-    ObtainReadLock(&afs_xuser);
     if (!*pos)
        return (void *)(1);
 
+    AFS_GLOCK();
+    ObtainReadLock(&afs_xuser);
+
+    ret = NULL;
+
     for (i = 0; i < NUSERS; i++) {
        for (tu = afs_users[i]; tu; tu = tu->next) {
            if (++n == *pos)
-               return tu;
+               ret = tu;
+               goto done;
        }
     }
 
-    return NULL;
+ done:
+    AFS_GUNLOCK();
+    return ret;
 }
 
 static void *
@@ -173,7 +181,9 @@ uu_next(struct seq_file *m, void *p, loff_t *pos)
 static void
 uu_stop(struct seq_file *m, void *p)
 {
+    AFS_GLOCK();
     ReleaseReadLock(&afs_xuser);
+    AFS_GUNLOCK();
 }
 
 static int
@@ -195,6 +205,8 @@ uu_show(struct seq_file *m, void *p)
        return 0;
     }
 
+    AFS_GLOCK();
+
     tu->refCount++;
     ReleaseReadLock(&afs_xuser);
 
@@ -250,6 +262,8 @@ uu_show(struct seq_file *m, void *p)
     afs_PutUser(tu, READ_LOCK);
     ObtainReadLock(&afs_xuser);
 
+    AFS_GUNLOCK();
+
     return 0;
 }
 
@@ -289,6 +303,8 @@ csdbproc_info(char *buffer, char **start, off_t offset, int length)
        decor */
     char temp[91];
     afs_uint32 addr;
+
+    AFS_GLOCK();
     
     ObtainReadLock(&afs_xcell);
 
@@ -335,6 +351,8 @@ csdbproc_info(char *buffer, char **start, off_t offset, int length)
     ReleaseReadLock(&afs_xcell);
     
 done:
+    AFS_GUNLOCK();
+
     *start = buffer + len - (pos - offset);
     len = pos - offset;
     if (len > length)