summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-06-06 15:19:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-06-06 15:19:37 -0400
commit459aa077a2f21e21bb0849007bc6909b0d20b1f6 (patch)
tree64bc3c58c63bfb330711a2a450ab8ce1852e235a /fs/nfs
parent44e843eb5cc383fe58fc8ec17dba0ab1dc45db2d (diff)
parentba851a39c9703f09684a541885ed176f8fb7c868 (diff)
Merge tag 'nfs-for-5.2-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker: "These are mostly stable bugfixes found during testing, many during the recent NFS bake-a-thon. Stable bugfixes: - SUNRPC: Fix regression in umount of a secure mount - SUNRPC: Fix a use after free when a server rejects the RPCSEC_GSS credential - NFSv4.1: Again fix a race where CB_NOTIFY_LOCK fails to wake a waiter - NFSv4.1: Fix bug only first CB_NOTIFY_LOCK is handled Other bugfixes: - xprtrdma: Use struct_size() in kzalloc()" * tag 'nfs-for-5.2-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: NFSv4.1: Fix bug only first CB_NOTIFY_LOCK is handled NFSv4.1: Again fix a race where CB_NOTIFY_LOCK fails to wake a waiter SUNRPC: Fix a use after free when a server rejects the RPCSEC_GSS credential SUNRPC fix regression in umount of a secure mount xprtrdma: Use struct_size() in kzalloc()
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c32
1 files changed, 12 insertions, 20 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c29cbef6b53f..e38f4af20950 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6932,7 +6932,6 @@ struct nfs4_lock_waiter {
6932 struct task_struct *task; 6932 struct task_struct *task;
6933 struct inode *inode; 6933 struct inode *inode;
6934 struct nfs_lowner *owner; 6934 struct nfs_lowner *owner;
6935 bool notified;
6936}; 6935};
6937 6936
6938static int 6937static int
@@ -6954,13 +6953,13 @@ nfs4_wake_lock_waiter(wait_queue_entry_t *wait, unsigned int mode, int flags, vo
6954 /* Make sure it's for the right inode */ 6953 /* Make sure it's for the right inode */
6955 if (nfs_compare_fh(NFS_FH(waiter->inode), &cbnl->cbnl_fh)) 6954 if (nfs_compare_fh(NFS_FH(waiter->inode), &cbnl->cbnl_fh))
6956 return 0; 6955 return 0;
6957
6958 waiter->notified = true;
6959 } 6956 }
6960 6957
6961 /* override "private" so we can use default_wake_function */ 6958 /* override "private" so we can use default_wake_function */
6962 wait->private = waiter->task; 6959 wait->private = waiter->task;
6963 ret = autoremove_wake_function(wait, mode, flags, key); 6960 ret = woken_wake_function(wait, mode, flags, key);
6961 if (ret)
6962 list_del_init(&wait->entry);
6964 wait->private = waiter; 6963 wait->private = waiter;
6965 return ret; 6964 return ret;
6966} 6965}
@@ -6969,7 +6968,6 @@ static int
6969nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 6968nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
6970{ 6969{
6971 int status = -ERESTARTSYS; 6970 int status = -ERESTARTSYS;
6972 unsigned long flags;
6973 struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner; 6971 struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
6974 struct nfs_server *server = NFS_SERVER(state->inode); 6972 struct nfs_server *server = NFS_SERVER(state->inode);
6975 struct nfs_client *clp = server->nfs_client; 6973 struct nfs_client *clp = server->nfs_client;
@@ -6979,8 +6977,7 @@ nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
6979 .s_dev = server->s_dev }; 6977 .s_dev = server->s_dev };
6980 struct nfs4_lock_waiter waiter = { .task = current, 6978 struct nfs4_lock_waiter waiter = { .task = current,
6981 .inode = state->inode, 6979 .inode = state->inode,
6982 .owner = &owner, 6980 .owner = &owner};
6983 .notified = false };
6984 wait_queue_entry_t wait; 6981 wait_queue_entry_t wait;
6985 6982
6986 /* Don't bother with waitqueue if we don't expect a callback */ 6983 /* Don't bother with waitqueue if we don't expect a callback */
@@ -6990,27 +6987,22 @@ nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
6990 init_wait(&wait); 6987 init_wait(&wait);
6991 wait.private = &waiter; 6988 wait.private = &waiter;
6992 wait.func = nfs4_wake_lock_waiter; 6989 wait.func = nfs4_wake_lock_waiter;
6993 add_wait_queue(q, &wait);
6994 6990
6995 while(!signalled()) { 6991 while(!signalled()) {
6996 waiter.notified = false; 6992 add_wait_queue(q, &wait);
6997 status = nfs4_proc_setlk(state, cmd, request); 6993 status = nfs4_proc_setlk(state, cmd, request);
6998 if ((status != -EAGAIN) || IS_SETLK(cmd)) 6994 if ((status != -EAGAIN) || IS_SETLK(cmd)) {
6995 finish_wait(q, &wait);
6999 break; 6996 break;
7000
7001 status = -ERESTARTSYS;
7002 spin_lock_irqsave(&q->lock, flags);
7003 if (waiter.notified) {
7004 spin_unlock_irqrestore(&q->lock, flags);
7005 continue;
7006 } 6997 }
7007 set_current_state(TASK_INTERRUPTIBLE);
7008 spin_unlock_irqrestore(&q->lock, flags);
7009 6998
7010 freezable_schedule_timeout(NFS4_LOCK_MAXTIMEOUT); 6999 status = -ERESTARTSYS;
7000 freezer_do_not_count();
7001 wait_woken(&wait, TASK_INTERRUPTIBLE, NFS4_LOCK_MAXTIMEOUT);
7002 freezer_count();
7003 finish_wait(q, &wait);
7011 } 7004 }
7012 7005
7013 finish_wait(q, &wait);
7014 return status; 7006 return status;
7015} 7007}
7016#else /* !CONFIG_NFS_V4_1 */ 7008#else /* !CONFIG_NFS_V4_1 */