aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-04-08 15:40:08 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-04-23 16:13:43 -0400
commitf97c650dda24e48405399aa0676e90da52408515 (patch)
tree9bb7d41c05ff8377cad7048b45fa900262688142 /fs/lockd
parent06e02d66fa0055230efc2443c43ee4f3ab5eb0b6 (diff)
NLM: don't let lockd exit on unexpected svc_recv errors (try #2)
When svc_recv returns an unexpected error, lockd will print a warning and exit. This problematic for several reasons. In particular, it will cause the reference counts for the thread to be wrong, and can lead to a potential BUG() call. Rather than exiting on error from svc_recv, have the thread do a 1s sleep and then retry the loop. This is unlikely to cause any harm, and if the error turns out to be something temporary then it may be able to recover. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/lockd')
-rw-r--r--fs/lockd/svc.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 66b5c98c7ff5..cf977bbcf303 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -112,7 +112,7 @@ static inline void clear_grace_period(void)
112static int 112static int
113lockd(void *vrqstp) 113lockd(void *vrqstp)
114{ 114{
115 int err = 0; 115 int err = 0, preverr = 0;
116 struct svc_rqst *rqstp = vrqstp; 116 struct svc_rqst *rqstp = vrqstp;
117 unsigned long grace_period_expire; 117 unsigned long grace_period_expire;
118 118
@@ -172,14 +172,20 @@ lockd(void *vrqstp)
172 * recvfrom routine. 172 * recvfrom routine.
173 */ 173 */
174 err = svc_recv(rqstp, timeout); 174 err = svc_recv(rqstp, timeout);
175 if (err == -EAGAIN || err == -EINTR) 175 if (err == -EAGAIN || err == -EINTR) {
176 preverr = err;
176 continue; 177 continue;
178 }
177 if (err < 0) { 179 if (err < 0) {
178 printk(KERN_WARNING 180 if (err != preverr) {
179 "lockd: terminating on error %d\n", 181 printk(KERN_WARNING "%s: unexpected error "
180 -err); 182 "from svc_recv (%d)\n", __func__, err);
181 break; 183 preverr = err;
184 }
185 schedule_timeout_interruptible(HZ);
186 continue;
182 } 187 }
188 preverr = err;
183 189
184 dprintk("lockd: request from %s\n", 190 dprintk("lockd: request from %s\n",
185 svc_print_addr(rqstp, buf, sizeof(buf))); 191 svc_print_addr(rqstp, buf, sizeof(buf)));