]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.15/filelock-add-a-new-locks_inode_context-accessor-func.patch
Fixes for 5.15
[thirdparty/kernel/stable-queue.git] / queue-5.15 / filelock-add-a-new-locks_inode_context-accessor-func.patch
1 From 11111ab9e11b05b76ef1d82199a846d59c06b2f6 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Wed, 16 Nov 2022 09:02:30 -0500
4 Subject: filelock: add a new locks_inode_context accessor function
5
6 From: Jeff Layton <jlayton@kernel.org>
7
8 [ Upstream commit 401a8b8fd5acd51582b15238d72a8d0edd580e9f ]
9
10 There are a number of places in the kernel that are accessing the
11 inode->i_flctx field without smp_load_acquire. This is required to
12 ensure that the caller doesn't see a partially-initialized structure.
13
14 Add a new accessor function for it to make this clear and convert all of
15 the relevant accesses in locks.c to use it. Also, convert
16 locks_free_lock_context to use the helper as well instead of just doing
17 a "bare" assignment.
18
19 Reviewed-by: Christoph Hellwig <hch@lst.de>
20 Signed-off-by: Jeff Layton <jlayton@kernel.org>
21 Stable-dep-of: 77c67530e1f9 ("nfsd: use locks_inode_context helper")
22 Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
23 ---
24 fs/locks.c | 24 ++++++++++++------------
25 include/linux/fs.h | 14 ++++++++++++++
26 2 files changed, 26 insertions(+), 12 deletions(-)
27
28 diff --git a/fs/locks.c b/fs/locks.c
29 index 317c2ec17b943..77781b71bcaab 100644
30 --- a/fs/locks.c
31 +++ b/fs/locks.c
32 @@ -251,7 +251,7 @@ locks_get_lock_context(struct inode *inode, int type)
33 struct file_lock_context *ctx;
34
35 /* paired with cmpxchg() below */
36 - ctx = smp_load_acquire(&inode->i_flctx);
37 + ctx = locks_inode_context(inode);
38 if (likely(ctx) || type == F_UNLCK)
39 goto out;
40
41 @@ -270,7 +270,7 @@ locks_get_lock_context(struct inode *inode, int type)
42 */
43 if (cmpxchg(&inode->i_flctx, NULL, ctx)) {
44 kmem_cache_free(flctx_cache, ctx);
45 - ctx = smp_load_acquire(&inode->i_flctx);
46 + ctx = locks_inode_context(inode);
47 }
48 out:
49 trace_locks_get_lock_context(inode, type, ctx);
50 @@ -323,7 +323,7 @@ locks_check_ctx_file_list(struct file *filp, struct list_head *list,
51 void
52 locks_free_lock_context(struct inode *inode)
53 {
54 - struct file_lock_context *ctx = inode->i_flctx;
55 + struct file_lock_context *ctx = locks_inode_context(inode);
56
57 if (unlikely(ctx)) {
58 locks_check_ctx_lists(inode);
59 @@ -985,7 +985,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
60 void *owner;
61 void (*func)(void);
62
63 - ctx = smp_load_acquire(&inode->i_flctx);
64 + ctx = locks_inode_context(inode);
65 if (!ctx || list_empty_careful(&ctx->flc_posix)) {
66 fl->fl_type = F_UNLCK;
67 return;
68 @@ -1577,7 +1577,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
69 new_fl->fl_flags = type;
70
71 /* typically we will check that ctx is non-NULL before calling */
72 - ctx = smp_load_acquire(&inode->i_flctx);
73 + ctx = locks_inode_context(inode);
74 if (!ctx) {
75 WARN_ON_ONCE(1);
76 goto free_lock;
77 @@ -1682,7 +1682,7 @@ void lease_get_mtime(struct inode *inode, struct timespec64 *time)
78 struct file_lock_context *ctx;
79 struct file_lock *fl;
80
81 - ctx = smp_load_acquire(&inode->i_flctx);
82 + ctx = locks_inode_context(inode);
83 if (ctx && !list_empty_careful(&ctx->flc_lease)) {
84 spin_lock(&ctx->flc_lock);
85 fl = list_first_entry_or_null(&ctx->flc_lease,
86 @@ -1728,7 +1728,7 @@ int fcntl_getlease(struct file *filp)
87 int type = F_UNLCK;
88 LIST_HEAD(dispose);
89
90 - ctx = smp_load_acquire(&inode->i_flctx);
91 + ctx = locks_inode_context(inode);
92 if (ctx && !list_empty_careful(&ctx->flc_lease)) {
93 percpu_down_read(&file_rwsem);
94 spin_lock(&ctx->flc_lock);
95 @@ -1917,7 +1917,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
96 struct file_lock_context *ctx;
97 LIST_HEAD(dispose);
98
99 - ctx = smp_load_acquire(&inode->i_flctx);
100 + ctx = locks_inode_context(inode);
101 if (!ctx) {
102 trace_generic_delete_lease(inode, NULL);
103 return error;
104 @@ -2651,7 +2651,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
105 * posix_lock_file(). Another process could be setting a lock on this
106 * file at the same time, but we wouldn't remove that lock anyway.
107 */
108 - ctx = smp_load_acquire(&inode->i_flctx);
109 + ctx = locks_inode_context(inode);
110 if (!ctx || list_empty(&ctx->flc_posix))
111 return;
112
113 @@ -2724,7 +2724,7 @@ void locks_remove_file(struct file *filp)
114 {
115 struct file_lock_context *ctx;
116
117 - ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
118 + ctx = locks_inode_context(locks_inode(filp));
119 if (!ctx)
120 return;
121
122 @@ -2771,7 +2771,7 @@ bool vfs_inode_has_locks(struct inode *inode)
123 struct file_lock_context *ctx;
124 bool ret;
125
126 - ctx = smp_load_acquire(&inode->i_flctx);
127 + ctx = locks_inode_context(inode);
128 if (!ctx)
129 return false;
130
131 @@ -2962,7 +2962,7 @@ void show_fd_locks(struct seq_file *f,
132 struct file_lock_context *ctx;
133 int id = 0;
134
135 - ctx = smp_load_acquire(&inode->i_flctx);
136 + ctx = locks_inode_context(inode);
137 if (!ctx)
138 return;
139
140 diff --git a/include/linux/fs.h b/include/linux/fs.h
141 index ef5a04d626953..61e86502fe65e 100644
142 --- a/include/linux/fs.h
143 +++ b/include/linux/fs.h
144 @@ -1217,6 +1217,13 @@ extern void show_fd_locks(struct seq_file *f,
145 struct file *filp, struct files_struct *files);
146 extern bool locks_owner_has_blockers(struct file_lock_context *flctx,
147 fl_owner_t owner);
148 +
149 +static inline struct file_lock_context *
150 +locks_inode_context(const struct inode *inode)
151 +{
152 + return smp_load_acquire(&inode->i_flctx);
153 +}
154 +
155 #else /* !CONFIG_FILE_LOCKING */
156 static inline int fcntl_getlk(struct file *file, unsigned int cmd,
157 struct flock __user *user)
158 @@ -1362,6 +1369,13 @@ static inline bool locks_owner_has_blockers(struct file_lock_context *flctx,
159 {
160 return false;
161 }
162 +
163 +static inline struct file_lock_context *
164 +locks_inode_context(const struct inode *inode)
165 +{
166 + return NULL;
167 +}
168 +
169 #endif /* !CONFIG_FILE_LOCKING */
170
171 static inline struct inode *file_inode(const struct file *f)
172 --
173 2.43.0
174