hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
kernel/fs/overlayfs/dir.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 *
34 * Copyright (C) 2011 Novell Inc.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms of the GNU General Public License version 2 as published by
7
- * the Free Software Foundation.
85 */
96
107 #include <linux/fs.h>
....@@ -21,7 +18,7 @@
2118
2219 static unsigned short ovl_redirect_max = 256;
2320 module_param_named(redirect_max, ovl_redirect_max, ushort, 0644);
24
-MODULE_PARM_DESC(ovl_redirect_max,
21
+MODULE_PARM_DESC(redirect_max,
2522 "Maximum length of absolute redirect xattr value");
2623
2724 static int ovl_set_redirect(struct dentry *dentry, bool samedir);
....@@ -38,14 +35,14 @@
3835 dput(wdentry);
3936
4037 if (err) {
41
- pr_err("overlayfs: cleanup of '%pd2' failed (%i)\n",
38
+ pr_err("cleanup of '%pd2' failed (%i)\n",
4239 wdentry, err);
4340 }
4441
4542 return err;
4643 }
4744
48
-static struct dentry *ovl_lookup_temp(struct dentry *workdir)
45
+struct dentry *ovl_lookup_temp(struct dentry *workdir)
4946 {
5047 struct dentry *temp;
5148 char name[20];
....@@ -56,7 +53,7 @@
5653
5754 temp = lookup_one_len(name, workdir, strlen(name));
5855 if (!IS_ERR(temp) && temp->d_inode) {
59
- pr_err("overlayfs: workdir/%s already exists\n", name);
56
+ pr_err("workdir/%s already exists\n", name);
6057 dput(temp);
6158 temp = ERR_PTR(-EIO);
6259 }
....@@ -65,35 +62,59 @@
6562 }
6663
6764 /* caller holds i_mutex on workdir */
68
-static struct dentry *ovl_whiteout(struct dentry *workdir)
65
+static struct dentry *ovl_whiteout(struct ovl_fs *ofs)
6966 {
7067 int err;
7168 struct dentry *whiteout;
69
+ struct dentry *workdir = ofs->workdir;
7270 struct inode *wdir = workdir->d_inode;
7371
74
- whiteout = ovl_lookup_temp(workdir);
75
- if (IS_ERR(whiteout))
76
- return whiteout;
72
+ if (!ofs->whiteout) {
73
+ whiteout = ovl_lookup_temp(workdir);
74
+ if (IS_ERR(whiteout))
75
+ goto out;
7776
78
- err = ovl_do_whiteout(wdir, whiteout);
79
- if (err) {
80
- dput(whiteout);
81
- whiteout = ERR_PTR(err);
77
+ err = ovl_do_whiteout(wdir, whiteout);
78
+ if (err) {
79
+ dput(whiteout);
80
+ whiteout = ERR_PTR(err);
81
+ goto out;
82
+ }
83
+ ofs->whiteout = whiteout;
8284 }
8385
86
+ if (ofs->share_whiteout) {
87
+ whiteout = ovl_lookup_temp(workdir);
88
+ if (IS_ERR(whiteout))
89
+ goto out;
90
+
91
+ err = ovl_do_link(ofs->whiteout, wdir, whiteout);
92
+ if (!err)
93
+ goto out;
94
+
95
+ if (err != -EMLINK) {
96
+ pr_warn("Failed to link whiteout - disabling whiteout inode sharing(nlink=%u, err=%i)\n",
97
+ ofs->whiteout->d_inode->i_nlink, err);
98
+ ofs->share_whiteout = false;
99
+ }
100
+ dput(whiteout);
101
+ }
102
+ whiteout = ofs->whiteout;
103
+ ofs->whiteout = NULL;
104
+out:
84105 return whiteout;
85106 }
86107
87108 /* Caller must hold i_mutex on both workdir and dir */
88
-int ovl_cleanup_and_whiteout(struct dentry *workdir, struct inode *dir,
109
+int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct inode *dir,
89110 struct dentry *dentry)
90111 {
91
- struct inode *wdir = workdir->d_inode;
112
+ struct inode *wdir = ofs->workdir->d_inode;
92113 struct dentry *whiteout;
93114 int err;
94115 int flags = 0;
95116
96
- whiteout = ovl_whiteout(workdir);
117
+ whiteout = ovl_whiteout(ofs);
97118 err = PTR_ERR(whiteout);
98119 if (IS_ERR(whiteout))
99120 return err;
....@@ -136,7 +157,7 @@
136157 d = lookup_one_len(dentry->d_name.name, dentry->d_parent,
137158 dentry->d_name.len);
138159 if (IS_ERR(d)) {
139
- pr_warn("overlayfs: failed lookup after mkdir (%pd2, err=%i).\n",
160
+ pr_warn("failed lookup after mkdir (%pd2, err=%i).\n",
140161 dentry, err);
141162 return PTR_ERR(d);
142163 }
....@@ -245,6 +266,8 @@
245266
246267 ovl_dir_modified(dentry->d_parent, false);
247268 ovl_dentry_set_upper_alias(dentry);
269
+ ovl_dentry_init_reval(dentry, newdentry);
270
+
248271 if (!hardlink) {
249272 /*
250273 * ovl_obtain_alias() can be called after ovl_create_real()
....@@ -261,6 +284,8 @@
261284 inode = ovl_get_inode(dentry->d_sb, &oip);
262285 if (IS_ERR(inode))
263286 return PTR_ERR(inode);
287
+ if (inode == oip.newinode)
288
+ ovl_set_flag(OVL_UPPERDATA, inode);
264289 } else {
265290 WARN_ON(ovl_inode_real(inode) != d_inode(newdentry));
266291 dput(newdentry);
....@@ -269,7 +294,7 @@
269294
270295 d_instantiate(dentry, inode);
271296 if (inode != oip.newinode) {
272
- pr_warn_ratelimited("overlayfs: newly created inode found in cache (%pd2)\n",
297
+ pr_warn_ratelimited("newly created inode found in cache (%pd2)\n",
273298 dentry);
274299 }
275300
....@@ -367,7 +392,7 @@
367392 if (IS_ERR(opaquedir))
368393 goto out_unlock;
369394
370
- err = ovl_copy_xattr(upper, opaquedir);
395
+ err = ovl_copy_xattr(dentry->d_sb, upper, opaquedir);
371396 if (err)
372397 goto out_cleanup;
373398
....@@ -413,13 +438,12 @@
413438 if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !acl)
414439 return 0;
415440
416
- size = posix_acl_to_xattr(NULL, acl, NULL, 0);
441
+ size = posix_acl_xattr_size(acl->a_count);
417442 buffer = kmalloc(size, GFP_KERNEL);
418443 if (!buffer)
419444 return -ENOMEM;
420445
421
- size = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
422
- err = size;
446
+ err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
423447 if (err < 0)
424448 goto out_free;
425449
....@@ -561,31 +585,45 @@
561585 goto out_revert_creds;
562586 }
563587
564
- err = -ENOMEM;
565
- override_cred = prepare_creds();
566
- if (override_cred) {
588
+ if (!attr->hardlink) {
589
+ err = -ENOMEM;
590
+ override_cred = prepare_creds();
591
+ if (!override_cred)
592
+ goto out_revert_creds;
593
+ /*
594
+ * In the creation cases(create, mkdir, mknod, symlink),
595
+ * ovl should transfer current's fs{u,g}id to underlying
596
+ * fs. Because underlying fs want to initialize its new
597
+ * inode owner using current's fs{u,g}id. And in this
598
+ * case, the @inode is a new inode that is initialized
599
+ * in inode_init_owner() to current's fs{u,g}id. So use
600
+ * the inode's i_{u,g}id to override the cred's fs{u,g}id.
601
+ *
602
+ * But in the other hardlink case, ovl_link() does not
603
+ * create a new inode, so just use the ovl mounter's
604
+ * fs{u,g}id.
605
+ */
567606 override_cred->fsuid = inode->i_uid;
568607 override_cred->fsgid = inode->i_gid;
569
- if (!attr->hardlink) {
570
- err = security_dentry_create_files_as(dentry,
571
- attr->mode, &dentry->d_name,
572
- old_cred ? old_cred : current_cred(),
573
- override_cred);
574
- if (err) {
575
- put_cred(override_cred);
576
- goto out_revert_creds;
577
- }
608
+ err = security_dentry_create_files_as(dentry,
609
+ attr->mode, &dentry->d_name,
610
+ old_cred ? old_cred : current_cred(),
611
+ override_cred);
612
+ if (err) {
613
+ put_cred(override_cred);
614
+ goto out_revert_creds;
578615 }
579616 hold_cred = override_creds(override_cred);
580617 put_cred(override_cred);
581
-
582
- if (!ovl_dentry_is_whiteout(dentry))
583
- err = ovl_create_upper(dentry, inode, attr);
584
- else
585
- err = ovl_create_over_whiteout(dentry, inode, attr);
586618 }
619
+
620
+ if (!ovl_dentry_is_whiteout(dentry))
621
+ err = ovl_create_upper(dentry, inode, attr);
622
+ else
623
+ err = ovl_create_over_whiteout(dentry, inode, attr);
624
+
587625 out_revert_creds:
588
- ovl_revert_creds(old_cred ?: hold_cred);
626
+ ovl_revert_creds(dentry->d_sb, old_cred ?: hold_cred);
589627 if (old_cred && hold_cred)
590628 put_cred(hold_cred);
591629 return err;
....@@ -663,7 +701,7 @@
663701
664702 old_cred = ovl_override_creds(dentry->d_sb);
665703 err = ovl_set_redirect(dentry, false);
666
- ovl_revert_creds(old_cred);
704
+ ovl_revert_creds(dentry->d_sb, old_cred);
667705
668706 return err;
669707 }
....@@ -672,7 +710,6 @@
672710 struct dentry *new)
673711 {
674712 int err;
675
- bool locked = false;
676713 struct inode *inode;
677714
678715 err = ovl_want_write(old);
....@@ -693,7 +730,7 @@
693730 goto out_drop_write;
694731 }
695732
696
- err = ovl_nlink_start(old, &locked);
733
+ err = ovl_nlink_start(old);
697734 if (err)
698735 goto out_drop_write;
699736
....@@ -706,7 +743,7 @@
706743 if (err)
707744 iput(inode);
708745
709
- ovl_nlink_end(old, locked);
746
+ ovl_nlink_end(old);
710747 out_drop_write:
711748 ovl_drop_write(old);
712749 out:
....@@ -721,6 +758,7 @@
721758 static int ovl_remove_and_whiteout(struct dentry *dentry,
722759 struct list_head *list)
723760 {
761
+ struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
724762 struct dentry *workdir = ovl_workdir(dentry);
725763 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
726764 struct dentry *upper;
....@@ -754,7 +792,7 @@
754792 goto out_dput_upper;
755793 }
756794
757
- err = ovl_cleanup_and_whiteout(workdir, d_inode(upperdir), upper);
795
+ err = ovl_cleanup_and_whiteout(ofs, d_inode(upperdir), upper);
758796 if (err)
759797 goto out_d_drop;
760798
....@@ -828,10 +866,31 @@
828866 !ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
829867 }
830868
869
+static void ovl_drop_nlink(struct dentry *dentry)
870
+{
871
+ struct inode *inode = d_inode(dentry);
872
+ struct dentry *alias;
873
+
874
+ /* Try to find another, hashed alias */
875
+ spin_lock(&inode->i_lock);
876
+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
877
+ if (alias != dentry && !d_unhashed(alias))
878
+ break;
879
+ }
880
+ spin_unlock(&inode->i_lock);
881
+
882
+ /*
883
+ * Changes to underlying layers may cause i_nlink to lose sync with
884
+ * reality. In this case prevent the link count from going to zero
885
+ * prematurely.
886
+ */
887
+ if (inode->i_nlink > !!alias)
888
+ drop_nlink(inode);
889
+}
890
+
831891 static int ovl_do_remove(struct dentry *dentry, bool is_dir)
832892 {
833893 int err;
834
- bool locked = false;
835894 const struct cred *old_cred;
836895 struct dentry *upperdentry;
837896 bool lower_positive = ovl_lower_positive(dentry);
....@@ -852,7 +911,7 @@
852911 if (err)
853912 goto out_drop_write;
854913
855
- err = ovl_nlink_start(dentry, &locked);
914
+ err = ovl_nlink_start(dentry);
856915 if (err)
857916 goto out_drop_write;
858917
....@@ -861,14 +920,14 @@
861920 err = ovl_remove_upper(dentry, is_dir, &list);
862921 else
863922 err = ovl_remove_and_whiteout(dentry, &list);
864
- ovl_revert_creds(old_cred);
923
+ ovl_revert_creds(dentry->d_sb, old_cred);
865924 if (!err) {
866925 if (is_dir)
867926 clear_nlink(dentry->d_inode);
868927 else
869
- drop_nlink(dentry->d_inode);
928
+ ovl_drop_nlink(dentry);
870929 }
871
- ovl_nlink_end(dentry, locked);
930
+ ovl_nlink_end(dentry);
872931
873932 /*
874933 * Copy ctime
....@@ -1019,7 +1078,7 @@
10191078 spin_unlock(&dentry->d_lock);
10201079 } else {
10211080 kfree(redirect);
1022
- pr_warn_ratelimited("overlayfs: failed to set redirect (%i)\n",
1081
+ pr_warn_ratelimited("failed to set redirect (%i)\n",
10231082 err);
10241083 /* Fall back to userspace copy-up */
10251084 err = -EXDEV;
....@@ -1032,7 +1091,6 @@
10321091 unsigned int flags)
10331092 {
10341093 int err;
1035
- bool locked = false;
10361094 struct dentry *old_upperdir;
10371095 struct dentry *new_upperdir;
10381096 struct dentry *olddentry;
....@@ -1041,6 +1099,7 @@
10411099 bool old_opaque;
10421100 bool new_opaque;
10431101 bool cleanup_whiteout = false;
1102
+ bool update_nlink = false;
10441103 bool overwrite = !(flags & RENAME_EXCHANGE);
10451104 bool is_dir = d_is_dir(old);
10461105 bool new_is_dir = d_is_dir(new);
....@@ -1098,10 +1157,12 @@
10981157 err = ovl_copy_up(new);
10991158 if (err)
11001159 goto out_drop_write;
1101
- } else {
1102
- err = ovl_nlink_start(new, &locked);
1160
+ } else if (d_inode(new)) {
1161
+ err = ovl_nlink_start(new);
11031162 if (err)
11041163 goto out_drop_write;
1164
+
1165
+ update_nlink = true;
11051166 }
11061167
11071168 old_cred = ovl_override_creds(old->d_sb);
....@@ -1213,7 +1274,7 @@
12131274 if (new_is_dir)
12141275 clear_nlink(d_inode(new));
12151276 else
1216
- drop_nlink(d_inode(new));
1277
+ ovl_drop_nlink(new);
12171278 }
12181279
12191280 ovl_dir_modified(old->d_parent, ovl_type_origin(old) ||
....@@ -1233,8 +1294,9 @@
12331294 out_unlock:
12341295 unlock_rename(new_upperdir, old_upperdir);
12351296 out_revert_creds:
1236
- ovl_revert_creds(old_cred);
1237
- ovl_nlink_end(new, locked);
1297
+ ovl_revert_creds(old->d_sb, old_cred);
1298
+ if (update_nlink)
1299
+ ovl_nlink_end(new);
12381300 out_drop_write:
12391301 ovl_drop_write(old);
12401302 out: