summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2018-03-18 08:37:03 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2018-04-10 16:06:22 -0400
commit571745935b2ec276345faec81af732fb9f51082b (patch)
treea23fe9112ffc8a69b4ef01a5c804e992cdcb906f /fs
parent5656610325a926141625e2d5eed1b0ba57a2e4cb (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.c26
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
6621nfs4_wake_lock_waiter(wait_queue_entry_t *wait, unsigned int mode, int flags, void *key) 6621nfs4_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;