forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
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,9 @@
245266
246267 ovl_dir_modified(dentry->d_parent, false);
247268 ovl_dentry_set_upper_alias(dentry);
269
+ ovl_dentry_update_reval(dentry, newdentry,
270
+ DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
271
+
248272 if (!hardlink) {
249273 /*
250274 * ovl_obtain_alias() can be called after ovl_create_real()
....@@ -261,6 +285,8 @@
261285 inode = ovl_get_inode(dentry->d_sb, &oip);
262286 if (IS_ERR(inode))
263287 return PTR_ERR(inode);
288
+ if (inode == oip.newinode)
289
+ ovl_set_flag(OVL_UPPERDATA, inode);
264290 } else {
265291 WARN_ON(ovl_inode_real(inode) != d_inode(newdentry));
266292 dput(newdentry);
....@@ -269,7 +295,7 @@
269295
270296 d_instantiate(dentry, inode);
271297 if (inode != oip.newinode) {
272
- pr_warn_ratelimited("overlayfs: newly created inode found in cache (%pd2)\n",
298
+ pr_warn_ratelimited("newly created inode found in cache (%pd2)\n",
273299 dentry);
274300 }
275301
....@@ -367,7 +393,7 @@
367393 if (IS_ERR(opaquedir))
368394 goto out_unlock;
369395
370
- err = ovl_copy_xattr(upper, opaquedir);
396
+ err = ovl_copy_xattr(dentry->d_sb, upper, opaquedir);
371397 if (err)
372398 goto out_cleanup;
373399
....@@ -413,13 +439,12 @@
413439 if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !acl)
414440 return 0;
415441
416
- size = posix_acl_to_xattr(NULL, acl, NULL, 0);
442
+ size = posix_acl_xattr_size(acl->a_count);
417443 buffer = kmalloc(size, GFP_KERNEL);
418444 if (!buffer)
419445 return -ENOMEM;
420446
421
- size = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
422
- err = size;
447
+ err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
423448 if (err < 0)
424449 goto out_free;
425450
....@@ -585,7 +610,7 @@
585610 err = ovl_create_over_whiteout(dentry, inode, attr);
586611 }
587612 out_revert_creds:
588
- ovl_revert_creds(old_cred ?: hold_cred);
613
+ ovl_revert_creds(dentry->d_sb, old_cred ?: hold_cred);
589614 if (old_cred && hold_cred)
590615 put_cred(hold_cred);
591616 return err;
....@@ -663,7 +688,7 @@
663688
664689 old_cred = ovl_override_creds(dentry->d_sb);
665690 err = ovl_set_redirect(dentry, false);
666
- ovl_revert_creds(old_cred);
691
+ ovl_revert_creds(dentry->d_sb, old_cred);
667692
668693 return err;
669694 }
....@@ -672,7 +697,6 @@
672697 struct dentry *new)
673698 {
674699 int err;
675
- bool locked = false;
676700 struct inode *inode;
677701
678702 err = ovl_want_write(old);
....@@ -693,7 +717,7 @@
693717 goto out_drop_write;
694718 }
695719
696
- err = ovl_nlink_start(old, &locked);
720
+ err = ovl_nlink_start(old);
697721 if (err)
698722 goto out_drop_write;
699723
....@@ -706,7 +730,7 @@
706730 if (err)
707731 iput(inode);
708732
709
- ovl_nlink_end(old, locked);
733
+ ovl_nlink_end(old);
710734 out_drop_write:
711735 ovl_drop_write(old);
712736 out:
....@@ -721,6 +745,7 @@
721745 static int ovl_remove_and_whiteout(struct dentry *dentry,
722746 struct list_head *list)
723747 {
748
+ struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
724749 struct dentry *workdir = ovl_workdir(dentry);
725750 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
726751 struct dentry *upper;
....@@ -754,7 +779,7 @@
754779 goto out_dput_upper;
755780 }
756781
757
- err = ovl_cleanup_and_whiteout(workdir, d_inode(upperdir), upper);
782
+ err = ovl_cleanup_and_whiteout(ofs, d_inode(upperdir), upper);
758783 if (err)
759784 goto out_d_drop;
760785
....@@ -828,10 +853,31 @@
828853 !ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
829854 }
830855
856
+static void ovl_drop_nlink(struct dentry *dentry)
857
+{
858
+ struct inode *inode = d_inode(dentry);
859
+ struct dentry *alias;
860
+
861
+ /* Try to find another, hashed alias */
862
+ spin_lock(&inode->i_lock);
863
+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
864
+ if (alias != dentry && !d_unhashed(alias))
865
+ break;
866
+ }
867
+ spin_unlock(&inode->i_lock);
868
+
869
+ /*
870
+ * Changes to underlying layers may cause i_nlink to lose sync with
871
+ * reality. In this case prevent the link count from going to zero
872
+ * prematurely.
873
+ */
874
+ if (inode->i_nlink > !!alias)
875
+ drop_nlink(inode);
876
+}
877
+
831878 static int ovl_do_remove(struct dentry *dentry, bool is_dir)
832879 {
833880 int err;
834
- bool locked = false;
835881 const struct cred *old_cred;
836882 struct dentry *upperdentry;
837883 bool lower_positive = ovl_lower_positive(dentry);
....@@ -852,7 +898,7 @@
852898 if (err)
853899 goto out_drop_write;
854900
855
- err = ovl_nlink_start(dentry, &locked);
901
+ err = ovl_nlink_start(dentry);
856902 if (err)
857903 goto out_drop_write;
858904
....@@ -861,14 +907,14 @@
861907 err = ovl_remove_upper(dentry, is_dir, &list);
862908 else
863909 err = ovl_remove_and_whiteout(dentry, &list);
864
- ovl_revert_creds(old_cred);
910
+ ovl_revert_creds(dentry->d_sb, old_cred);
865911 if (!err) {
866912 if (is_dir)
867913 clear_nlink(dentry->d_inode);
868914 else
869
- drop_nlink(dentry->d_inode);
915
+ ovl_drop_nlink(dentry);
870916 }
871
- ovl_nlink_end(dentry, locked);
917
+ ovl_nlink_end(dentry);
872918
873919 /*
874920 * Copy ctime
....@@ -1019,7 +1065,7 @@
10191065 spin_unlock(&dentry->d_lock);
10201066 } else {
10211067 kfree(redirect);
1022
- pr_warn_ratelimited("overlayfs: failed to set redirect (%i)\n",
1068
+ pr_warn_ratelimited("failed to set redirect (%i)\n",
10231069 err);
10241070 /* Fall back to userspace copy-up */
10251071 err = -EXDEV;
....@@ -1032,7 +1078,6 @@
10321078 unsigned int flags)
10331079 {
10341080 int err;
1035
- bool locked = false;
10361081 struct dentry *old_upperdir;
10371082 struct dentry *new_upperdir;
10381083 struct dentry *olddentry;
....@@ -1041,6 +1086,7 @@
10411086 bool old_opaque;
10421087 bool new_opaque;
10431088 bool cleanup_whiteout = false;
1089
+ bool update_nlink = false;
10441090 bool overwrite = !(flags & RENAME_EXCHANGE);
10451091 bool is_dir = d_is_dir(old);
10461092 bool new_is_dir = d_is_dir(new);
....@@ -1098,10 +1144,12 @@
10981144 err = ovl_copy_up(new);
10991145 if (err)
11001146 goto out_drop_write;
1101
- } else {
1102
- err = ovl_nlink_start(new, &locked);
1147
+ } else if (d_inode(new)) {
1148
+ err = ovl_nlink_start(new);
11031149 if (err)
11041150 goto out_drop_write;
1151
+
1152
+ update_nlink = true;
11051153 }
11061154
11071155 old_cred = ovl_override_creds(old->d_sb);
....@@ -1213,7 +1261,7 @@
12131261 if (new_is_dir)
12141262 clear_nlink(d_inode(new));
12151263 else
1216
- drop_nlink(d_inode(new));
1264
+ ovl_drop_nlink(new);
12171265 }
12181266
12191267 ovl_dir_modified(old->d_parent, ovl_type_origin(old) ||
....@@ -1233,8 +1281,9 @@
12331281 out_unlock:
12341282 unlock_rename(new_upperdir, old_upperdir);
12351283 out_revert_creds:
1236
- ovl_revert_creds(old_cred);
1237
- ovl_nlink_end(new, locked);
1284
+ ovl_revert_creds(old->d_sb, old_cred);
1285
+ if (update_nlink)
1286
+ ovl_nlink_end(new);
12381287 out_drop_write:
12391288 ovl_drop_write(old);
12401289 out: