OSDN Git Service

NFSv4.x: fix lock recovery during delegation recall
authorOlga Kornievskaia <kolga@netapp.com>
Thu, 4 Oct 2018 18:45:00 +0000 (14:45 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Nov 2019 14:54:43 +0000 (15:54 +0100)
[ Upstream commit 44f411c353bf6d98d5a34f8f1b8605d43b2e50b8 ]

Running "./nfstest_delegation --runtest recall26" uncovers that
client doesn't recover the lock when we have an appending open,
where the initial open got a write delegation.

Instead of checking for the passed in open context against
the file lock's open context. Check that the state is the same.

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/delegation.c

index 5dac338..b50315a 100644 (file)
@@ -101,7 +101,7 @@ int nfs4_check_delegation(struct inode *inode, fmode_t flags)
        return nfs4_do_check_delegation(inode, flags, false);
 }
 
-static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
+static int nfs_delegation_claim_locks(struct nfs4_state *state, const nfs4_stateid *stateid)
 {
        struct inode *inode = state->inode;
        struct file_lock *fl;
@@ -116,7 +116,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
        spin_lock(&flctx->flc_lock);
 restart:
        list_for_each_entry(fl, list, fl_list) {
-               if (nfs_file_open_context(fl->fl_file) != ctx)
+               if (nfs_file_open_context(fl->fl_file)->state != state)
                        continue;
                spin_unlock(&flctx->flc_lock);
                status = nfs4_lock_delegation_recall(fl, state, stateid);
@@ -163,7 +163,7 @@ again:
                seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
                err = nfs4_open_delegation_recall(ctx, state, stateid, type);
                if (!err)
-                       err = nfs_delegation_claim_locks(ctx, state, stateid);
+                       err = nfs_delegation_claim_locks(state, stateid);
                if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
                        err = -EAGAIN;
                mutex_unlock(&sp->so_delegreturn_mutex);