OSDN Git Service

lockd: don't attempt blocking locks on nfs reexports
authorJ. Bruce Fields <bfields@redhat.com>
Fri, 20 Aug 2021 21:02:05 +0000 (17:02 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Thu, 26 Aug 2021 19:32:18 +0000 (15:32 -0400)
As in the v4 case, it doesn't work well to block waiting for a lock on
an nfs filesystem.

As in the v4 case, that means we're depending on the client to poll.
It's probably incorrect to depend on that, but I *think* clients do poll
in practice.  In any case, it's an improvement over hanging the lockd
thread indefinitely as we currently are.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Acked-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/svclock.c

index a7b4c51..e9b85d8 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/lockd/nlm.h>
 #include <linux/lockd/lockd.h>
 #include <linux/kthread.h>
+#include <linux/exportfs.h>
 
 #define NLMDBG_FACILITY                NLMDBG_SVCLOCK
 
@@ -470,18 +471,24 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
            struct nlm_cookie *cookie, int reclaim)
 {
        struct nlm_block        *block = NULL;
+       struct inode            *inode = nlmsvc_file_inode(file);
        int                     error;
        int                     mode;
+       int                     async_block = 0;
        __be32                  ret;
 
        dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
-                               nlmsvc_file_inode(file)->i_sb->s_id,
-                               nlmsvc_file_inode(file)->i_ino,
+                               inode->i_sb->s_id, inode->i_ino,
                                lock->fl.fl_type, lock->fl.fl_pid,
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end,
                                wait);
 
+       if (inode->i_sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS) {
+               async_block = wait;
+               wait = 0;
+       }
+
        /* Lock file against concurrent access */
        mutex_lock(&file->f_mutex);
        /* Get existing block (in case client is busy-waiting)
@@ -542,7 +549,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
                         */
                        if (wait)
                                break;
-                       ret = nlm_lck_denied;
+                       ret = async_block ? nlm_lck_blocked : nlm_lck_denied;
                        goto out;
                case FILE_LOCK_DEFERRED:
                        if (wait)