]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.15/nfsd-introduce-struct-nfsd_attrs.patch
Fixes for 5.15
[thirdparty/kernel/stable-queue.git] / queue-5.15 / nfsd-introduce-struct-nfsd_attrs.patch
1 From 2665a88c9d8e81d1e9f47d56f9002bf2c1a6646f Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Tue, 26 Jul 2022 16:45:30 +1000
4 Subject: NFSD: introduce struct nfsd_attrs
5
6 From: NeilBrown <neilb@suse.de>
7
8 [ Upstream commit 7fe2a71dda349a1afa75781f0cc7975be9784d15 ]
9
10 The attributes that nfsd might want to set on a file include 'struct
11 iattr' as well as an ACL and security label.
12 The latter two are passed around quite separately from the first, in
13 part because they are only needed for NFSv4. This leads to some
14 clumsiness in the code, such as the attributes NOT being set in
15 nfsd_create_setattr().
16
17 We need to keep the directory locked until all attributes are set to
18 ensure the file is never visibile without all its attributes. This need
19 combined with the inconsistent handling of attributes leads to more
20 clumsiness.
21
22 As a first step towards tidying this up, introduce 'struct nfsd_attrs'.
23 This is passed (by reference) to vfs.c functions that work with
24 attributes, and is assembled by the various nfs*proc functions which
25 call them. As yet only iattr is included, but future patches will
26 expand this.
27
28 Signed-off-by: NeilBrown <neilb@suse.de>
29 Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
30 ---
31 fs/nfsd/nfs3proc.c | 20 ++++++++++++++++----
32 fs/nfsd/nfs4proc.c | 23 ++++++++++++++++-------
33 fs/nfsd/nfs4state.c | 5 ++++-
34 fs/nfsd/nfsproc.c | 17 +++++++++++++----
35 fs/nfsd/vfs.c | 24 ++++++++++++++----------
36 fs/nfsd/vfs.h | 12 ++++++++----
37 6 files changed, 71 insertions(+), 30 deletions(-)
38
39 diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
40 index 57854ca022d18..113567b3a98a5 100644
41 --- a/fs/nfsd/nfs3proc.c
42 +++ b/fs/nfsd/nfs3proc.c
43 @@ -67,12 +67,15 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp)
44 {
45 struct nfsd3_sattrargs *argp = rqstp->rq_argp;
46 struct nfsd3_attrstat *resp = rqstp->rq_resp;
47 + struct nfsd_attrs attrs = {
48 + .na_iattr = &argp->attrs,
49 + };
50
51 dprintk("nfsd: SETATTR(3) %s\n",
52 SVCFH_fmt(&argp->fh));
53
54 fh_copy(&resp->fh, &argp->fh);
55 - resp->status = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,
56 + resp->status = nfsd_setattr(rqstp, &resp->fh, &attrs,
57 argp->check_guard, argp->guardtime);
58 return rpc_success;
59 }
60 @@ -233,6 +236,9 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
61 {
62 struct iattr *iap = &argp->attrs;
63 struct dentry *parent, *child;
64 + struct nfsd_attrs attrs = {
65 + .na_iattr = iap,
66 + };
67 __u32 v_mtime, v_atime;
68 struct inode *inode;
69 __be32 status;
70 @@ -331,7 +337,7 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
71 }
72
73 set_attr:
74 - status = nfsd_create_setattr(rqstp, fhp, resfhp, iap);
75 + status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs);
76
77 out:
78 fh_unlock(fhp);
79 @@ -368,6 +374,9 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp)
80 {
81 struct nfsd3_createargs *argp = rqstp->rq_argp;
82 struct nfsd3_diropres *resp = rqstp->rq_resp;
83 + struct nfsd_attrs attrs = {
84 + .na_iattr = &argp->attrs,
85 + };
86
87 dprintk("nfsd: MKDIR(3) %s %.*s\n",
88 SVCFH_fmt(&argp->fh),
89 @@ -378,7 +387,7 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp)
90 fh_copy(&resp->dirfh, &argp->fh);
91 fh_init(&resp->fh, NFS3_FHSIZE);
92 resp->status = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
93 - &argp->attrs, S_IFDIR, 0, &resp->fh);
94 + &attrs, S_IFDIR, 0, &resp->fh);
95 fh_unlock(&resp->dirfh);
96 return rpc_success;
97 }
98 @@ -428,6 +437,9 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp)
99 {
100 struct nfsd3_mknodargs *argp = rqstp->rq_argp;
101 struct nfsd3_diropres *resp = rqstp->rq_resp;
102 + struct nfsd_attrs attrs = {
103 + .na_iattr = &argp->attrs,
104 + };
105 int type;
106 dev_t rdev = 0;
107
108 @@ -453,7 +465,7 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp)
109
110 type = nfs3_ftypes[argp->ftype];
111 resp->status = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
112 - &argp->attrs, type, rdev, &resp->fh);
113 + &attrs, type, rdev, &resp->fh);
114 fh_unlock(&resp->dirfh);
115 out:
116 return rpc_success;
117 diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
118 index ae0948271da9c..9b04611a318d7 100644
119 --- a/fs/nfsd/nfs4proc.c
120 +++ b/fs/nfsd/nfs4proc.c
121 @@ -286,6 +286,9 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
122 struct svc_fh *resfhp, struct nfsd4_open *open)
123 {
124 struct iattr *iap = &open->op_iattr;
125 + struct nfsd_attrs attrs = {
126 + .na_iattr = iap,
127 + };
128 struct dentry *parent, *child;
129 __u32 v_mtime, v_atime;
130 struct inode *inode;
131 @@ -404,7 +407,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
132 }
133
134 set_attr:
135 - status = nfsd_create_setattr(rqstp, fhp, resfhp, iap);
136 + status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs);
137
138 out:
139 fh_unlock(fhp);
140 @@ -787,6 +790,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
141 union nfsd4_op_u *u)
142 {
143 struct nfsd4_create *create = &u->create;
144 + struct nfsd_attrs attrs = {
145 + .na_iattr = &create->cr_iattr,
146 + };
147 struct svc_fh resfh;
148 __be32 status;
149 dev_t rdev;
150 @@ -818,7 +824,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
151 goto out_umask;
152 status = nfsd_create(rqstp, &cstate->current_fh,
153 create->cr_name, create->cr_namelen,
154 - &create->cr_iattr, S_IFBLK, rdev, &resfh);
155 + &attrs, S_IFBLK, rdev, &resfh);
156 break;
157
158 case NF4CHR:
159 @@ -829,26 +835,26 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
160 goto out_umask;
161 status = nfsd_create(rqstp, &cstate->current_fh,
162 create->cr_name, create->cr_namelen,
163 - &create->cr_iattr, S_IFCHR, rdev, &resfh);
164 + &attrs, S_IFCHR, rdev, &resfh);
165 break;
166
167 case NF4SOCK:
168 status = nfsd_create(rqstp, &cstate->current_fh,
169 create->cr_name, create->cr_namelen,
170 - &create->cr_iattr, S_IFSOCK, 0, &resfh);
171 + &attrs, S_IFSOCK, 0, &resfh);
172 break;
173
174 case NF4FIFO:
175 status = nfsd_create(rqstp, &cstate->current_fh,
176 create->cr_name, create->cr_namelen,
177 - &create->cr_iattr, S_IFIFO, 0, &resfh);
178 + &attrs, S_IFIFO, 0, &resfh);
179 break;
180
181 case NF4DIR:
182 create->cr_iattr.ia_valid &= ~ATTR_SIZE;
183 status = nfsd_create(rqstp, &cstate->current_fh,
184 create->cr_name, create->cr_namelen,
185 - &create->cr_iattr, S_IFDIR, 0, &resfh);
186 + &attrs, S_IFDIR, 0, &resfh);
187 break;
188
189 default:
190 @@ -1142,6 +1148,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
191 union nfsd4_op_u *u)
192 {
193 struct nfsd4_setattr *setattr = &u->setattr;
194 + struct nfsd_attrs attrs = {
195 + .na_iattr = &setattr->sa_iattr,
196 + };
197 __be32 status = nfs_ok;
198 int err;
199
200 @@ -1174,7 +1183,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
201 &setattr->sa_label);
202 if (status)
203 goto out;
204 - status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
205 + status = nfsd_setattr(rqstp, &cstate->current_fh, &attrs,
206 0, (time64_t)0);
207 out:
208 fh_drop_write(&cstate->current_fh);
209 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
210 index 7122ebc50a035..a299aeaa0de07 100644
211 --- a/fs/nfsd/nfs4state.c
212 +++ b/fs/nfsd/nfs4state.c
213 @@ -5077,11 +5077,14 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
214 .ia_valid = ATTR_SIZE,
215 .ia_size = 0,
216 };
217 + struct nfsd_attrs attrs = {
218 + .na_iattr = &iattr,
219 + };
220 if (!open->op_truncate)
221 return 0;
222 if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
223 return nfserr_inval;
224 - return nfsd_setattr(rqstp, fh, &iattr, 0, (time64_t)0);
225 + return nfsd_setattr(rqstp, fh, &attrs, 0, (time64_t)0);
226 }
227
228 static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
229 diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
230 index f65eba938a57d..c75d83bc3f21b 100644
231 --- a/fs/nfsd/nfsproc.c
232 +++ b/fs/nfsd/nfsproc.c
233 @@ -51,6 +51,9 @@ nfsd_proc_setattr(struct svc_rqst *rqstp)
234 struct nfsd_sattrargs *argp = rqstp->rq_argp;
235 struct nfsd_attrstat *resp = rqstp->rq_resp;
236 struct iattr *iap = &argp->attrs;
237 + struct nfsd_attrs attrs = {
238 + .na_iattr = iap,
239 + };
240 struct svc_fh *fhp;
241
242 dprintk("nfsd: SETATTR %s, valid=%x, size=%ld\n",
243 @@ -100,7 +103,7 @@ nfsd_proc_setattr(struct svc_rqst *rqstp)
244 }
245 }
246
247 - resp->status = nfsd_setattr(rqstp, fhp, iap, 0, (time64_t)0);
248 + resp->status = nfsd_setattr(rqstp, fhp, &attrs, 0, (time64_t)0);
249 if (resp->status != nfs_ok)
250 goto out;
251
252 @@ -261,6 +264,9 @@ nfsd_proc_create(struct svc_rqst *rqstp)
253 svc_fh *dirfhp = &argp->fh;
254 svc_fh *newfhp = &resp->fh;
255 struct iattr *attr = &argp->attrs;
256 + struct nfsd_attrs attrs = {
257 + .na_iattr = attr,
258 + };
259 struct inode *inode;
260 struct dentry *dchild;
261 int type, mode;
262 @@ -386,7 +392,7 @@ nfsd_proc_create(struct svc_rqst *rqstp)
263 if (!inode) {
264 /* File doesn't exist. Create it and set attrs */
265 resp->status = nfsd_create_locked(rqstp, dirfhp, argp->name,
266 - argp->len, attr, type, rdev,
267 + argp->len, &attrs, type, rdev,
268 newfhp);
269 } else if (type == S_IFREG) {
270 dprintk("nfsd: existing %s, valid=%x, size=%ld\n",
271 @@ -397,7 +403,7 @@ nfsd_proc_create(struct svc_rqst *rqstp)
272 */
273 attr->ia_valid &= ATTR_SIZE;
274 if (attr->ia_valid)
275 - resp->status = nfsd_setattr(rqstp, newfhp, attr, 0,
276 + resp->status = nfsd_setattr(rqstp, newfhp, &attrs, 0,
277 (time64_t)0);
278 }
279
280 @@ -512,6 +518,9 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp)
281 {
282 struct nfsd_createargs *argp = rqstp->rq_argp;
283 struct nfsd_diropres *resp = rqstp->rq_resp;
284 + struct nfsd_attrs attrs = {
285 + .na_iattr = &argp->attrs,
286 + };
287
288 dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
289
290 @@ -523,7 +532,7 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp)
291 argp->attrs.ia_valid &= ~ATTR_SIZE;
292 fh_init(&resp->fh, NFS_FHSIZE);
293 resp->status = nfsd_create(rqstp, &argp->fh, argp->name, argp->len,
294 - &argp->attrs, S_IFDIR, 0, &resp->fh);
295 + &attrs, S_IFDIR, 0, &resp->fh);
296 fh_put(&argp->fh);
297 if (resp->status != nfs_ok)
298 goto out;
299 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
300 index 6689ad5bb790d..489225de05a2a 100644
301 --- a/fs/nfsd/vfs.c
302 +++ b/fs/nfsd/vfs.c
303 @@ -350,11 +350,13 @@ nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
304 * Set various file attributes. After this call fhp needs an fh_put.
305 */
306 __be32
307 -nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
308 +nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
309 + struct nfsd_attrs *attr,
310 int check_guard, time64_t guardtime)
311 {
312 struct dentry *dentry;
313 struct inode *inode;
314 + struct iattr *iap = attr->na_iattr;
315 int accmode = NFSD_MAY_SATTR;
316 umode_t ftype = 0;
317 __be32 err;
318 @@ -1203,14 +1205,15 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset,
319 * @rqstp: RPC transaction being executed
320 * @fhp: NFS filehandle of parent directory
321 * @resfhp: NFS filehandle of new object
322 - * @iap: requested attributes of new object
323 + * @attrs: requested attributes of new object
324 *
325 * Returns nfs_ok on success, or an nfsstat in network byte order.
326 */
327 __be32
328 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
329 - struct svc_fh *resfhp, struct iattr *iap)
330 + struct svc_fh *resfhp, struct nfsd_attrs *attrs)
331 {
332 + struct iattr *iap = attrs->na_iattr;
333 __be32 status;
334
335 /*
336 @@ -1231,7 +1234,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
337 * if the attributes have not changed.
338 */
339 if (iap->ia_valid)
340 - status = nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0);
341 + status = nfsd_setattr(rqstp, resfhp, attrs, 0, (time64_t)0);
342 else
343 status = nfserrno(commit_metadata(resfhp));
344
345 @@ -1270,11 +1273,12 @@ nfsd_check_ignore_resizing(struct iattr *iap)
346 /* The parent directory should already be locked: */
347 __be32
348 nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
349 - char *fname, int flen, struct iattr *iap,
350 - int type, dev_t rdev, struct svc_fh *resfhp)
351 + char *fname, int flen, struct nfsd_attrs *attrs,
352 + int type, dev_t rdev, struct svc_fh *resfhp)
353 {
354 struct dentry *dentry, *dchild;
355 struct inode *dirp;
356 + struct iattr *iap = attrs->na_iattr;
357 __be32 err;
358 int host_err;
359
360 @@ -1348,7 +1352,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
361 if (host_err < 0)
362 goto out_nfserr;
363
364 - err = nfsd_create_setattr(rqstp, fhp, resfhp, iap);
365 + err = nfsd_create_setattr(rqstp, fhp, resfhp, attrs);
366
367 out:
368 dput(dchild);
369 @@ -1367,8 +1371,8 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
370 */
371 __be32
372 nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
373 - char *fname, int flen, struct iattr *iap,
374 - int type, dev_t rdev, struct svc_fh *resfhp)
375 + char *fname, int flen, struct nfsd_attrs *attrs,
376 + int type, dev_t rdev, struct svc_fh *resfhp)
377 {
378 struct dentry *dentry, *dchild = NULL;
379 __be32 err;
380 @@ -1400,7 +1404,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
381 dput(dchild);
382 if (err)
383 return err;
384 - return nfsd_create_locked(rqstp, fhp, fname, flen, iap, type,
385 + return nfsd_create_locked(rqstp, fhp, fname, flen, attrs, type,
386 rdev, resfhp);
387 }
388
389 diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
390 index 26347d76f44a0..d8b1a36fca956 100644
391 --- a/fs/nfsd/vfs.h
392 +++ b/fs/nfsd/vfs.h
393 @@ -42,6 +42,10 @@ struct nfsd_file;
394 typedef int (*nfsd_filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
395
396 /* nfsd/vfs.c */
397 +struct nfsd_attrs {
398 + struct iattr *na_iattr; /* input */
399 +};
400 +
401 int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
402 struct svc_export **expp);
403 __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *,
404 @@ -50,7 +54,7 @@ __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *,
405 const char *, unsigned int,
406 struct svc_export **, struct dentry **);
407 __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *,
408 - struct iattr *, int, time64_t);
409 + struct nfsd_attrs *, int, time64_t);
410 int nfsd_mountpoint(struct dentry *, struct svc_export *);
411 #ifdef CONFIG_NFSD_V4
412 __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
413 @@ -63,14 +67,14 @@ __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp,
414 u64 count, bool sync);
415 #endif /* CONFIG_NFSD_V4 */
416 __be32 nfsd_create_locked(struct svc_rqst *, struct svc_fh *,
417 - char *name, int len, struct iattr *attrs,
418 + char *name, int len, struct nfsd_attrs *attrs,
419 int type, dev_t rdev, struct svc_fh *res);
420 __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
421 - char *name, int len, struct iattr *attrs,
422 + char *name, int len, struct nfsd_attrs *attrs,
423 int type, dev_t rdev, struct svc_fh *res);
424 __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
425 __be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
426 - struct svc_fh *resfhp, struct iattr *iap);
427 + struct svc_fh *resfhp, struct nfsd_attrs *iap);
428 __be32 nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp,
429 u64 offset, u32 count, __be32 *verf);
430 #ifdef CONFIG_NFSD_V4
431 --
432 2.43.0
433