]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
NFS: don't let nfs_callback_svc exit on unexpected svc_recv errors (try #2)
authorJeff Layton <jlayton@redhat.com>
Tue, 8 Apr 2008 19:40:07 +0000 (15:40 -0400)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Wed, 23 Apr 2008 20:13:42 +0000 (16:13 -0400)
When svc_recv returns an unexpected error, nfs_callback_svc 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 no
new thread will be started until all nfs4 mounts are unmounted.

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>
fs/nfs/callback.c

index a9f153867554fbe69d8af3382a846f79a824b58a..5606ae3d72d377792bfd8689487389cc967315b5 100644 (file)
@@ -59,7 +59,7 @@ module_param_call(callback_tcpport, param_set_port, param_get_int,
 static int
 nfs_callback_svc(void *vrqstp)
 {
-       int err;
+       int err, preverr = 0;
        struct svc_rqst *rqstp = vrqstp;
 
        set_freezable();
@@ -74,14 +74,20 @@ nfs_callback_svc(void *vrqstp)
                 * Listen for a request on the socket
                 */
                err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
-               if (err == -EAGAIN || err == -EINTR)
+               if (err == -EAGAIN || err == -EINTR) {
+                       preverr = err;
                        continue;
+               }
                if (err < 0) {
-                       printk(KERN_WARNING
-                                       "%s: terminating on error %d\n",
-                                       __FUNCTION__, -err);
-                       break;
+                       if (err != preverr) {
+                               printk(KERN_WARNING "%s: unexpected error "
+                                       "from svc_recv (%d)\n", __func__, err);
+                               preverr = err;
+                       }
+                       schedule_timeout_uninterruptible(HZ);
+                       continue;
                }
+               preverr = err;
                svc_process(rqstp);
        }
        unlock_kernel();