Skip to content

Commit d75a6a0

Browse files
bcodding-rhamschuma-ntap
authored andcommitted
NFSv4.1: Keep a reference on lock states while checking
While walking the list of lock_states, keep a reference on each nfs4_lock_state to be checked, otherwise the lock state could be removed while the check performs TEST_STATEID and possible FREE_STATEID. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent d41cbfc commit d75a6a0

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

fs/nfs/nfs4proc.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,15 +2564,23 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
25642564
static int nfs41_check_expired_locks(struct nfs4_state *state)
25652565
{
25662566
int status, ret = NFS_OK;
2567-
struct nfs4_lock_state *lsp;
2567+
struct nfs4_lock_state *lsp, *prev = NULL;
25682568
struct nfs_server *server = NFS_SERVER(state->inode);
25692569

25702570
if (!test_bit(LK_STATE_IN_USE, &state->flags))
25712571
goto out;
2572+
2573+
spin_lock(&state->state_lock);
25722574
list_for_each_entry(lsp, &state->lock_states, ls_locks) {
25732575
if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
25742576
struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
25752577

2578+
atomic_inc(&lsp->ls_count);
2579+
spin_unlock(&state->state_lock);
2580+
2581+
nfs4_put_lock_state(prev);
2582+
prev = lsp;
2583+
25762584
status = nfs41_test_and_free_expired_stateid(server,
25772585
&lsp->ls_stateid,
25782586
cred);
@@ -2585,10 +2593,14 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
25852593
set_bit(NFS_LOCK_LOST, &lsp->ls_flags);
25862594
} else if (status != NFS_OK) {
25872595
ret = status;
2588-
break;
2596+
nfs4_put_lock_state(prev);
2597+
goto out;
25892598
}
2599+
spin_lock(&state->state_lock);
25902600
}
2591-
};
2601+
}
2602+
spin_unlock(&state->state_lock);
2603+
nfs4_put_lock_state(prev);
25922604
out:
25932605
return ret;
25942606
}

0 commit comments

Comments
 (0)