diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-06 15:19:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-06 15:19:37 -0400 |
commit | 459aa077a2f21e21bb0849007bc6909b0d20b1f6 (patch) | |
tree | 64bc3c58c63bfb330711a2a450ab8ce1852e235a /fs/nfs | |
parent | 44e843eb5cc383fe58fc8ec17dba0ab1dc45db2d (diff) | |
parent | ba851a39c9703f09684a541885ed176f8fb7c868 (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.c | 32 |
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 | ||
6938 | static int | 6937 | static 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 | |||
6969 | nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) | 6968 | nfs4_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 */ |