hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
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,34 @@
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_init_reval(dentry, upper);
339328
340329 return d_instantiate_anon(dentry, inode);
341330
342331 nomem:
343
- iput(inode);
344332 dput(dentry);
345
- return ERR_PTR(-ENOMEM);
333
+ dentry = ERR_PTR(-ENOMEM);
334
+out_iput:
335
+ iput(inode);
336
+ return dentry;
346337 }
347338
348339 /* Get the upper or lower dentry in stach whose on layer @idx */
....@@ -370,7 +361,7 @@
370361 */
371362 static struct dentry *ovl_lookup_real_one(struct dentry *connected,
372363 struct dentry *real,
373
- struct ovl_layer *layer)
364
+ const struct ovl_layer *layer)
374365 {
375366 struct inode *dir = d_inode(connected);
376367 struct dentry *this, *parent = NULL;
....@@ -397,7 +388,8 @@
397388 * pointer because we hold no lock on the real dentry.
398389 */
399390 take_dentry_name_snapshot(&name, real);
400
- this = lookup_one_len(name.name, connected, strlen(name.name));
391
+ this = lookup_one_len(name.name.name, connected, name.name.len);
392
+ release_dentry_name_snapshot(&name);
401393 err = PTR_ERR(this);
402394 if (IS_ERR(this)) {
403395 goto fail;
....@@ -412,13 +404,12 @@
412404 }
413405
414406 out:
415
- release_dentry_name_snapshot(&name);
416407 dput(parent);
417408 inode_unlock(dir);
418409 return this;
419410
420411 fail:
421
- pr_warn_ratelimited("overlayfs: failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
412
+ pr_warn_ratelimited("failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
422413 real, layer->idx, connected, err);
423414 this = ERR_PTR(err);
424415 goto out;
....@@ -426,17 +417,16 @@
426417
427418 static struct dentry *ovl_lookup_real(struct super_block *sb,
428419 struct dentry *real,
429
- struct ovl_layer *layer);
420
+ const struct ovl_layer *layer);
430421
431422 /*
432423 * Lookup an indexed or hashed overlay dentry by real inode.
433424 */
434425 static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
435426 struct dentry *real,
436
- struct ovl_layer *layer)
427
+ const struct ovl_layer *layer)
437428 {
438429 struct ovl_fs *ofs = sb->s_fs_info;
439
- struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
440430 struct dentry *index = NULL;
441431 struct dentry *this = NULL;
442432 struct inode *inode;
....@@ -478,7 +468,7 @@
478468 * recursive call walks back from indexed upper to the topmost
479469 * connected/hashed upper parent (or up to root).
480470 */
481
- this = ovl_lookup_real(sb, upper, &upper_layer);
471
+ this = ovl_lookup_real(sb, upper, &ofs->layers[0]);
482472 dput(upper);
483473 }
484474
....@@ -499,7 +489,7 @@
499489 */
500490 static struct dentry *ovl_lookup_real_ancestor(struct super_block *sb,
501491 struct dentry *real,
502
- struct ovl_layer *layer)
492
+ const struct ovl_layer *layer)
503493 {
504494 struct dentry *next, *parent = NULL;
505495 struct dentry *ancestor = ERR_PTR(-EIO);
....@@ -552,7 +542,7 @@
552542 */
553543 static struct dentry *ovl_lookup_real(struct super_block *sb,
554544 struct dentry *real,
555
- struct ovl_layer *layer)
545
+ const struct ovl_layer *layer)
556546 {
557547 struct dentry *connected;
558548 int err = 0;
....@@ -643,7 +633,7 @@
643633 return connected;
644634
645635 fail:
646
- pr_warn_ratelimited("overlayfs: failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
636
+ pr_warn_ratelimited("failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
647637 real, layer->idx, connected, err);
648638 dput(connected);
649639 return ERR_PTR(err);
....@@ -658,8 +648,7 @@
658648 struct dentry *index)
659649 {
660650 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;
651
+ const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer;
663652 struct dentry *real = upper ?: (index ?: lowerpath->dentry);
664653
665654 /*
....@@ -687,10 +676,10 @@
687676 struct dentry *dentry;
688677 struct dentry *upper;
689678
690
- if (!ofs->upper_mnt)
679
+ if (!ovl_upper_mnt(ofs))
691680 return ERR_PTR(-EACCES);
692681
693
- upper = ovl_decode_real_fh(fh, ofs->upper_mnt, true);
682
+ upper = ovl_decode_real_fh(fh, ovl_upper_mnt(ofs), true);
694683 if (IS_ERR_OR_NULL(upper))
695684 return upper;
696685
....@@ -762,7 +751,7 @@
762751 goto out_err;
763752 }
764753 if (index) {
765
- err = ovl_verify_origin(index, origin.dentry, false);
754
+ err = ovl_verify_origin(ofs, index, origin.dentry, false);
766755 if (err)
767756 goto out_err;
768757 }
....@@ -780,24 +769,48 @@
780769 goto out;
781770 }
782771
772
+static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type)
773
+{
774
+ struct ovl_fh *fh;
775
+
776
+ /* If on-wire inner fid is aligned - nothing to do */
777
+ if (fh_type == OVL_FILEID_V1)
778
+ return (struct ovl_fh *)fid;
779
+
780
+ if (fh_type != OVL_FILEID_V0)
781
+ return ERR_PTR(-EINVAL);
782
+
783
+ if (buflen <= OVL_FH_WIRE_OFFSET)
784
+ return ERR_PTR(-EINVAL);
785
+
786
+ fh = kzalloc(buflen, GFP_KERNEL);
787
+ if (!fh)
788
+ return ERR_PTR(-ENOMEM);
789
+
790
+ /* Copy unaligned inner fh into aligned buffer */
791
+ memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
792
+ return fh;
793
+}
794
+
783795 static struct dentry *ovl_fh_to_dentry(struct super_block *sb, struct fid *fid,
784796 int fh_len, int fh_type)
785797 {
786798 struct dentry *dentry = NULL;
787
- struct ovl_fh *fh = (struct ovl_fh *) fid;
799
+ struct ovl_fh *fh = NULL;
788800 int len = fh_len << 2;
789801 unsigned int flags = 0;
790802 int err;
791803
792
- err = -EINVAL;
793
- if (fh_type != OVL_FILEID)
804
+ fh = ovl_fid_to_fh(fid, len, fh_type);
805
+ err = PTR_ERR(fh);
806
+ if (IS_ERR(fh))
794807 goto out_err;
795808
796809 err = ovl_check_fh_len(fh, len);
797810 if (err)
798811 goto out_err;
799812
800
- flags = fh->flags;
813
+ flags = fh->fb.flags;
801814 dentry = (flags & OVL_FH_FLAG_PATH_UPPER) ?
802815 ovl_upper_fh_to_d(sb, fh) :
803816 ovl_lower_fh_to_d(sb, fh);
....@@ -805,18 +818,24 @@
805818 if (IS_ERR(dentry) && err != -ESTALE)
806819 goto out_err;
807820
821
+out:
822
+ /* We may have needed to re-align OVL_FILEID_V0 */
823
+ if (!IS_ERR_OR_NULL(fh) && fh != (void *)fid)
824
+ kfree(fh);
825
+
808826 return dentry;
809827
810828 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);
829
+ pr_warn_ratelimited("failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
830
+ fh_len, fh_type, flags, err);
831
+ dentry = ERR_PTR(err);
832
+ goto out;
814833 }
815834
816835 static struct dentry *ovl_fh_to_parent(struct super_block *sb, struct fid *fid,
817836 int fh_len, int fh_type)
818837 {
819
- pr_warn_ratelimited("overlayfs: connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
838
+ pr_warn_ratelimited("connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
820839 return ERR_PTR(-EACCES);
821840 }
822841