aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/cache.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2010-09-19 22:55:06 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-09-19 23:49:30 -0400
commit06497524589f2a7717da33969d541674e0a27da6 (patch)
tree3d7d21b9dd325c36e11a923f186059f587d7724d /net/sunrpc/cache.c
parentc88739b373e4930ed082a607cb78bf82616fd076 (diff)
nfsd4: fix hang on fast-booting nfs servers
The last_close field of a cache_detail is initialized to zero, so the condition detail->last_close < seconds_since_boot() - 30 may be false even for a cache that was never opened. However, we want to immediately fail upcalls to caches that were never opened: in the case of the auth_unix_gid cache, especially, which may never be opened by mountd (if the --manage-gids option is not set), we want to fail the upcall immediately. Otherwise client requests will be dropped unnecessarily on reboot. Also document these conditions. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r--net/sunrpc/cache.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index da872f9fe1e0..ca7c621cd975 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1091,6 +1091,23 @@ static void warn_no_listener(struct cache_detail *detail)
1091 } 1091 }
1092} 1092}
1093 1093
1094static bool cache_listeners_exist(struct cache_detail *detail)
1095{
1096 if (atomic_read(&detail->readers))
1097 return true;
1098 if (detail->last_close == 0)
1099 /* This cache was never opened */
1100 return false;
1101 if (detail->last_close < seconds_since_boot() - 30)
1102 /*
1103 * We allow for the possibility that someone might
1104 * restart a userspace daemon without restarting the
1105 * server; but after 30 seconds, we give up.
1106 */
1107 return false;
1108 return true;
1109}
1110
1094/* 1111/*
1095 * register an upcall request to user-space and queue it up for read() by the 1112 * register an upcall request to user-space and queue it up for read() by the
1096 * upcall daemon. 1113 * upcall daemon.
@@ -1109,10 +1126,9 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h,
1109 char *bp; 1126 char *bp;
1110 int len; 1127 int len;
1111 1128
1112 if (atomic_read(&detail->readers) == 0 && 1129 if (!cache_listeners_exist(detail)) {
1113 detail->last_close < seconds_since_boot() - 30) { 1130 warn_no_listener(detail);
1114 warn_no_listener(detail); 1131 return -EINVAL;
1115 return -EINVAL;
1116 } 1132 }
1117 1133
1118 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1134 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);