From 5237d3d232f22aaf4f67f3a8727a293f4058a7ae Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Thu, 26 Jul 2012 16:40:03 -0500 Subject: [PATCH] LINUX: Hold GLOCK for proc traversal 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 Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Derrick Brashear --- src/afs/LINUX/osi_proc.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/afs/LINUX/osi_proc.c b/src/afs/LINUX/osi_proc.c index ecb145761..bb1529bf1 100644 --- a/src/afs/LINUX/osi_proc.c +++ b/src/afs/LINUX/osi_proc.c @@ -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) -- 2.39.5