| From 7d1a1c3b87a5c728fcc0696aa7ed97d655e1548f Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 6 Nov 2022 14:02:39 -0500 |
| Subject: lockd: set other missing fields when unlocking files |
| |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| |
| [ Upstream commit 18ebd35b61b4693a0ddc270b6d4f18def232e770 ] |
| |
| vfs_lock_file() expects the struct file_lock to be fully initialised by |
| the caller. Re-exported NFSv3 has been seen to Oops if the fl_file field |
| is NULL. |
| |
| Fixes: aec158242b87 ("lockd: set fl_owner when unlocking files") |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Reviewed-by: Jeff Layton <jlayton@kernel.org> |
| Link: https://bugzilla.kernel.org/show_bug.cgi?id=216582 |
| Signed-off-by: Chuck Lever <chuck.lever@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/lockd/svcsubs.c | 17 ++++++++++------- |
| 1 file changed, 10 insertions(+), 7 deletions(-) |
| |
| diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c |
| index e1c4617de771..3515f17eaf3f 100644 |
| --- a/fs/lockd/svcsubs.c |
| +++ b/fs/lockd/svcsubs.c |
| @@ -176,7 +176,7 @@ nlm_delete_file(struct nlm_file *file) |
| } |
| } |
| |
| -static int nlm_unlock_files(struct nlm_file *file, fl_owner_t owner) |
| +static int nlm_unlock_files(struct nlm_file *file, const struct file_lock *fl) |
| { |
| struct file_lock lock; |
| |
| @@ -184,12 +184,15 @@ static int nlm_unlock_files(struct nlm_file *file, fl_owner_t owner) |
| lock.fl_type = F_UNLCK; |
| lock.fl_start = 0; |
| lock.fl_end = OFFSET_MAX; |
| - lock.fl_owner = owner; |
| - if (file->f_file[O_RDONLY] && |
| - vfs_lock_file(file->f_file[O_RDONLY], F_SETLK, &lock, NULL)) |
| + lock.fl_owner = fl->fl_owner; |
| + lock.fl_pid = fl->fl_pid; |
| + lock.fl_flags = FL_POSIX; |
| + |
| + lock.fl_file = file->f_file[O_RDONLY]; |
| + if (lock.fl_file && vfs_lock_file(lock.fl_file, F_SETLK, &lock, NULL)) |
| goto out_err; |
| - if (file->f_file[O_WRONLY] && |
| - vfs_lock_file(file->f_file[O_WRONLY], F_SETLK, &lock, NULL)) |
| + lock.fl_file = file->f_file[O_WRONLY]; |
| + if (lock.fl_file && vfs_lock_file(lock.fl_file, F_SETLK, &lock, NULL)) |
| goto out_err; |
| return 0; |
| out_err: |
| @@ -226,7 +229,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, |
| if (match(lockhost, host)) { |
| |
| spin_unlock(&flctx->flc_lock); |
| - if (nlm_unlock_files(file, fl->fl_owner)) |
| + if (nlm_unlock_files(file, fl)) |
| return 1; |
| goto again; |
| } |
| -- |
| 2.35.1 |
| |