forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/overlayfs/export.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Overlayfs NFS export support.
34 *
45 * Amir Goldstein <amir73il@gmail.com>
56 *
67 * Copyright (C) 2017-2018 CTERA Networks. All Rights Reserved.
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License version 2 as published by
10
- * the Free Software Foundation.
118 */
129
1310 #include <linux/fs.h>
....@@ -33,7 +30,7 @@
3330 }
3431
3532 if (err) {
36
- pr_warn_ratelimited("overlayfs: failed to copy up on encode (%pd2, err=%i)\n",
33
+ pr_warn_ratelimited("failed to copy up on encode (%pd2, err=%i)\n",
3734 dentry, err);
3835 }
3936
....@@ -207,17 +204,18 @@
207204 * ovl_connect_layer() will try to make origin's layer "connected" by
208205 * copying up a "connectable" ancestor.
209206 */
210
- if (d_is_dir(dentry) && ofs->upper_mnt)
207
+ if (d_is_dir(dentry) && ovl_upper_mnt(ofs))
211208 return ovl_connect_layer(dentry);
212209
213210 /* Lower file handle for indexed and non-upper dir/non-dir */
214211 return 1;
215212 }
216213
217
-static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
214
+static int ovl_dentry_to_fid(struct dentry *dentry, u32 *fid, int buflen)
218215 {
219216 struct ovl_fh *fh = NULL;
220217 int err, enc_lower;
218
+ int len;
221219
222220 /*
223221 * Check if we should encode a lower or upper file handle and maybe
....@@ -233,57 +231,45 @@
233231 if (IS_ERR(fh))
234232 return PTR_ERR(fh);
235233
236
- err = -EOVERFLOW;
237
- if (fh->len > buflen)
238
- goto fail;
239
-
240
- memcpy(buf, (char *)fh, fh->len);
241
- err = fh->len;
234
+ len = OVL_FH_LEN(fh);
235
+ if (len <= buflen)
236
+ memcpy(fid, fh, len);
237
+ err = len;
242238
243239 out:
244240 kfree(fh);
245241 return err;
246242
247243 fail:
248
- pr_warn_ratelimited("overlayfs: failed to encode file handle (%pd2, err=%i, buflen=%d, len=%d, type=%d)\n",
249
- dentry, err, buflen, fh ? (int)fh->len : 0,
250
- fh ? fh->type : 0);
244
+ pr_warn_ratelimited("failed to encode file handle (%pd2, err=%i)\n",
245
+ dentry, err);
251246 goto out;
252
-}
253
-
254
-static int ovl_dentry_to_fh(struct dentry *dentry, u32 *fid, int *max_len)
255
-{
256
- int res, len = *max_len << 2;
257
-
258
- res = ovl_d_to_fh(dentry, (char *)fid, len);
259
- if (res <= 0)
260
- return FILEID_INVALID;
261
-
262
- len = res;
263
-
264
- /* Round up to dwords */
265
- *max_len = (len + 3) >> 2;
266
- return OVL_FILEID;
267247 }
268248
269249 static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len,
270250 struct inode *parent)
271251 {
272252 struct dentry *dentry;
273
- int type;
253
+ int bytes, buflen = *max_len << 2;
274254
275255 /* TODO: encode connectable file handles */
276256 if (parent)
277257 return FILEID_INVALID;
278258
279259 dentry = d_find_any_alias(inode);
280
- if (WARN_ON(!dentry))
260
+ if (!dentry)
281261 return FILEID_INVALID;
282262
283
- type = ovl_dentry_to_fh(dentry, fid, max_len);
284
-
263
+ bytes = ovl_dentry_to_fid(dentry, fid, buflen);
285264 dput(dentry);
286
- return type;
265
+ if (bytes <= 0)
266
+ return FILEID_INVALID;
267
+
268
+ *max_len = bytes >> 2;
269
+ if (bytes > buflen)
270
+ return FILEID_INVALID;
271
+
272
+ return OVL_FILEID_V1;
287273 }
288274
289275 /*
....@@ -320,29 +306,35 @@
320306 ovl_set_flag(OVL_UPPERDATA, inode);
321307
322308 dentry = d_find_any_alias(inode);
323
- if (!dentry) {
324
- dentry = d_alloc_anon(inode->i_sb);
325
- if (!dentry)
326
- goto nomem;
327
- oe = ovl_alloc_entry(lower ? 1 : 0);
328
- if (!oe)
329
- goto nomem;
309
+ if (dentry)
310
+ goto out_iput;
330311
331
- if (lower) {
332
- oe->lowerstack->dentry = dget(lower);
333
- oe->lowerstack->layer = lowerpath->layer;
334
- }
335
- dentry->d_fsdata = oe;
336
- if (upper_alias)
337
- ovl_dentry_set_upper_alias(dentry);
312
+ dentry = d_alloc_anon(inode->i_sb);
313
+ if (unlikely(!dentry))
314
+ goto nomem;
315
+ oe = ovl_alloc_entry(lower ? 1 : 0);
316
+ if (!oe)
317
+ goto nomem;
318
+
319
+ if (lower) {
320
+ oe->lowerstack->dentry = dget(lower);
321
+ oe->lowerstack->layer = lowerpath->layer;
338322 }
323
+ dentry->d_fsdata = oe;
324
+ if (upper_alias)
325
+ ovl_dentry_set_upper_alias(dentry);
326
+
327
+ ovl_dentry_update_reval(dentry, upper,
328
+ DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
339329
340330 return d_instantiate_anon(dentry, inode);
341331
342332 nomem:
343
- iput(inode);
344333 dput(dentry);
345
- return ERR_PTR(-ENOMEM);
334
+ dentry = ERR_PTR(-ENOMEM);
335
+out_iput:
336
+ iput(inode);
337
+ return dentry;
346338 }
347339
348340 /* Get the upper or lower dentry in stach whose on layer @idx */
....@@ -370,7 +362,7 @@
370362 */
371363 static struct dentry *ovl_lookup_real_one(struct dentry *connected,
372364 struct dentry *real,
373
- struct ovl_layer *layer)
365
+ const struct ovl_layer *layer)
374366 {
375367 struct inode *dir = d_inode(connected);
376368 struct dentry *this, *parent = NULL;
....@@ -397,7 +389,8 @@
397389 * pointer because we hold no lock on the real dentry.
398390 */
399391 take_dentry_name_snapshot(&name, real);
400
- this = lookup_one_len(name.name, connected, strlen(name.name));
392
+ this = lookup_one_len(name.name.name, connected, name.name.len);
393
+ release_dentry_name_snapshot(&name);
401394 err = PTR_ERR(this);
402395 if (IS_ERR(this)) {
403396 goto fail;
....@@ -412,13 +405,12 @@
412405 }
413406
414407 out:
415
- release_dentry_name_snapshot(&name);
416408 dput(parent);
417409 inode_unlock(dir);
418410 return this;
419411
420412 fail:
421
- pr_warn_ratelimited("overlayfs: failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
413
+ pr_warn_ratelimited("failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
422414 real, layer->idx, connected, err);
423415 this = ERR_PTR(err);
424416 goto out;
....@@ -426,17 +418,16 @@
426418
427419 static struct dentry *ovl_lookup_real(struct super_block *sb,
428420 struct dentry *real,
429
- struct ovl_layer *layer);
421
+ const struct ovl_layer *layer);
430422
431423 /*
432424 * Lookup an indexed or hashed overlay dentry by real inode.
433425 */
434426 static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
435427 struct dentry *real,
436
- struct ovl_layer *layer)
428
+ const struct ovl_layer *layer)
437429 {
438430 struct ovl_fs *ofs = sb->s_fs_info;
439
- struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
440431 struct dentry *index = NULL;
441432 struct dentry *this = NULL;
442433 struct inode *inode;
....@@ -478,7 +469,7 @@
478469 * recursive call walks back from indexed upper to the topmost
479470 * connected/hashed upper parent (or up to root).
480471 */
481
- this = ovl_lookup_real(sb, upper, &upper_layer);
472
+ this = ovl_lookup_real(sb, upper, &ofs->layers[0]);
482473 dput(upper);
483474 }
484475
....@@ -499,7 +490,7 @@
499490 */
500491 static struct dentry *ovl_lookup_real_ancestor(struct super_block *sb,
501492 struct dentry *real,
502
- struct ovl_layer *layer)
493
+ const struct ovl_layer *layer)
503494 {
504495 struct dentry *next, *parent = NULL;
505496 struct dentry *ancestor = ERR_PTR(-EIO);
....@@ -552,7 +543,7 @@
552543 */
553544 static struct dentry *ovl_lookup_real(struct super_block *sb,
554545 struct dentry *real,
555
- struct ovl_layer *layer)
546
+ const struct ovl_layer *layer)
556547 {
557548 struct dentry *connected;
558549 int err = 0;
....@@ -643,7 +634,7 @@
643634 return connected;
644635
645636 fail:
646
- pr_warn_ratelimited("overlayfs: failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
637
+ pr_warn_ratelimited("failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
647638 real, layer->idx, connected, err);
648639 dput(connected);
649640 return ERR_PTR(err);
....@@ -658,8 +649,7 @@
658649 struct dentry *index)
659650 {
660651 struct ovl_fs *ofs = sb->s_fs_info;
661
- struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
662
- struct ovl_layer *layer = upper ? &upper_layer : lowerpath->layer;
652
+ const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer;
663653 struct dentry *real = upper ?: (index ?: lowerpath->dentry);
664654
665655 /*
....@@ -687,10 +677,10 @@
687677 struct dentry *dentry;
688678 struct dentry *upper;
689679
690
- if (!ofs->upper_mnt)
680
+ if (!ovl_upper_mnt(ofs))
691681 return ERR_PTR(-EACCES);
692682
693
- upper = ovl_decode_real_fh(fh, ofs->upper_mnt, true);
683
+ upper = ovl_decode_real_fh(fh, ovl_upper_mnt(ofs), true);
694684 if (IS_ERR_OR_NULL(upper))
695685 return upper;
696686
....@@ -762,7 +752,7 @@
762752 goto out_err;
763753 }
764754 if (index) {
765
- err = ovl_verify_origin(index, origin.dentry, false);
755
+ err = ovl_verify_origin(ofs, index, origin.dentry, false);
766756 if (err)
767757 goto out_err;
768758 }
....@@ -780,24 +770,48 @@
780770 goto out;
781771 }
782772
773
+static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type)
774
+{
775
+ struct ovl_fh *fh;
776
+
777
+ /* If on-wire inner fid is aligned - nothing to do */
778
+ if (fh_type == OVL_FILEID_V1)
779
+ return (struct ovl_fh *)fid;
780
+
781
+ if (fh_type != OVL_FILEID_V0)
782
+ return ERR_PTR(-EINVAL);
783
+
784
+ if (buflen <= OVL_FH_WIRE_OFFSET)
785
+ return ERR_PTR(-EINVAL);
786
+
787
+ fh = kzalloc(buflen, GFP_KERNEL);
788
+ if (!fh)
789
+ return ERR_PTR(-ENOMEM);
790
+
791
+ /* Copy unaligned inner fh into aligned buffer */
792
+ memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
793
+ return fh;
794
+}
795
+
783796 static struct dentry *ovl_fh_to_dentry(struct super_block *sb, struct fid *fid,
784797 int fh_len, int fh_type)
785798 {
786799 struct dentry *dentry = NULL;
787
- struct ovl_fh *fh = (struct ovl_fh *) fid;
800
+ struct ovl_fh *fh = NULL;
788801 int len = fh_len << 2;
789802 unsigned int flags = 0;
790803 int err;
791804
792
- err = -EINVAL;
793
- if (fh_type != OVL_FILEID)
805
+ fh = ovl_fid_to_fh(fid, len, fh_type);
806
+ err = PTR_ERR(fh);
807
+ if (IS_ERR(fh))
794808 goto out_err;
795809
796810 err = ovl_check_fh_len(fh, len);
797811 if (err)
798812 goto out_err;
799813
800
- flags = fh->flags;
814
+ flags = fh->fb.flags;
801815 dentry = (flags & OVL_FH_FLAG_PATH_UPPER) ?
802816 ovl_upper_fh_to_d(sb, fh) :
803817 ovl_lower_fh_to_d(sb, fh);
....@@ -805,18 +819,24 @@
805819 if (IS_ERR(dentry) && err != -ESTALE)
806820 goto out_err;
807821
822
+out:
823
+ /* We may have needed to re-align OVL_FILEID_V0 */
824
+ if (!IS_ERR_OR_NULL(fh) && fh != (void *)fid)
825
+ kfree(fh);
826
+
808827 return dentry;
809828
810829 out_err:
811
- pr_warn_ratelimited("overlayfs: failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
812
- len, fh_type, flags, err);
813
- return ERR_PTR(err);
830
+ pr_warn_ratelimited("failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
831
+ fh_len, fh_type, flags, err);
832
+ dentry = ERR_PTR(err);
833
+ goto out;
814834 }
815835
816836 static struct dentry *ovl_fh_to_parent(struct super_block *sb, struct fid *fid,
817837 int fh_len, int fh_type)
818838 {
819
- pr_warn_ratelimited("overlayfs: connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
839
+ pr_warn_ratelimited("connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
820840 return ERR_PTR(-EACCES);
821841 }
822842