diff options
author | Jeff Layton <jlayton@redhat.com> | 2018-03-18 08:37:03 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2018-04-10 16:06:22 -0400 |
commit | 571745935b2ec276345faec81af732fb9f51082b (patch) | |
tree | a23fe9112ffc8a69b4ef01a5c804e992cdcb906f /fs | |
parent | 5656610325a926141625e2d5eed1b0ba57a2e4cb (diff) |
nfs4: wake any lock waiters on successful RECLAIM_COMPLETE
If we have a RECLAIM_COMPLETE with a populated cl_lock_waitq, then
that implies that a reconnect has occurred. Since we can't expect a
CB_NOTIFY_LOCK callback at that point, just wake up the entire queue
so that all the tasks can re-poll for their locks.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 669ba9211177..ec68edce6cc3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -6621,20 +6621,24 @@ static int | |||
6621 | nfs4_wake_lock_waiter(wait_queue_entry_t *wait, unsigned int mode, int flags, void *key) | 6621 | nfs4_wake_lock_waiter(wait_queue_entry_t *wait, unsigned int mode, int flags, void *key) |
6622 | { | 6622 | { |
6623 | int ret; | 6623 | int ret; |
6624 | struct cb_notify_lock_args *cbnl = key; | ||
6625 | struct nfs4_lock_waiter *waiter = wait->private; | 6624 | struct nfs4_lock_waiter *waiter = wait->private; |
6626 | struct nfs_lowner *lowner = &cbnl->cbnl_owner, | ||
6627 | *wowner = waiter->owner; | ||
6628 | 6625 | ||
6629 | /* Only wake if the callback was for the same owner. */ | 6626 | /* NULL key means to wake up everyone */ |
6630 | if (lowner->id != wowner->id || lowner->s_dev != wowner->s_dev) | 6627 | if (key) { |
6631 | return 0; | 6628 | struct cb_notify_lock_args *cbnl = key; |
6629 | struct nfs_lowner *lowner = &cbnl->cbnl_owner, | ||
6630 | *wowner = waiter->owner; | ||
6632 | 6631 | ||
6633 | /* Make sure it's for the right inode */ | 6632 | /* Only wake if the callback was for the same owner. */ |
6634 | if (nfs_compare_fh(NFS_FH(waiter->inode), &cbnl->cbnl_fh)) | 6633 | if (lowner->id != wowner->id || lowner->s_dev != wowner->s_dev) |
6635 | return 0; | 6634 | return 0; |
6636 | 6635 | ||
6637 | waiter->notified = true; | 6636 | /* Make sure it's for the right inode */ |
6637 | if (nfs_compare_fh(NFS_FH(waiter->inode), &cbnl->cbnl_fh)) | ||
6638 | return 0; | ||
6639 | |||
6640 | waiter->notified = true; | ||
6641 | } | ||
6638 | 6642 | ||
6639 | /* override "private" so we can use default_wake_function */ | 6643 | /* override "private" so we can use default_wake_function */ |
6640 | wait->private = waiter->task; | 6644 | wait->private = waiter->task; |
@@ -8413,6 +8417,8 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf | |||
8413 | { | 8417 | { |
8414 | switch(task->tk_status) { | 8418 | switch(task->tk_status) { |
8415 | case 0: | 8419 | case 0: |
8420 | wake_up_all(&clp->cl_lock_waitq); | ||
8421 | /* Fallthrough */ | ||
8416 | case -NFS4ERR_COMPLETE_ALREADY: | 8422 | case -NFS4ERR_COMPLETE_ALREADY: |
8417 | case -NFS4ERR_WRONG_CRED: /* What to do here? */ | 8423 | case -NFS4ERR_WRONG_CRED: /* What to do here? */ |
8418 | break; | 8424 | break; |