summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2019-04-18 10:42:08 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2019-05-29 07:03:37 -0400
commit146d62e5a5867fbf84490d82455718bfb10fe824 (patch)
tree60bea762ab581345f62f150f4939f2fa36998dc2 /fs
parentb21d9c435f935014d3e3fa6914f2e4fbabb0e94d (diff)
ovl: detect overlapping layers
Overlapping overlay layers are not supported and can cause unexpected behavior, but overlayfs does not currently check or warn about these configurations. User is not supposed to specify the same directory for upper and lower dirs or for different lower layers and user is not supposed to specify directories that are descendants of each other for overlay layers, but that is exactly what this zysbot repro did: https://syzkaller.appspot.com/x/repro.syz?x=12c7a94f400000 Moving layer root directories into other layers while overlayfs is mounted could also result in unexpected behavior. This commit places "traps" in the overlay inode hash table. Those traps are dummy overlay inodes that are hashed by the layers root inodes. On mount, the hash table trap entries are used to verify that overlay layers are not overlapping. While at it, we also verify that overlay layers are not overlapping with directories "in-use" by other overlay instances as upperdir/workdir. On lookup, the trap entries are used to verify that overlay layers root inodes have not been moved into other layers after mount. Some examples: $ ./run --ov --samefs -s ... ( mkdir -p base/upper/0/u base/upper/0/w base/lower lower upper mnt mount -o bind base/lower lower mount -o bind base/upper upper mount -t overlay none mnt ... -o lowerdir=lower,upperdir=upper/0/u,workdir=upper/0/w) $ umount mnt $ mount -t overlay none mnt ... -o lowerdir=base,upperdir=upper/0/u,workdir=upper/0/w [ 94.434900] overlayfs: overlapping upperdir path mount: mount overlay on mnt failed: Too many levels of symbolic links $ mount -t overlay none mnt ... -o lowerdir=upper/0/u,upperdir=upper/0/u,workdir=upper/0/w [ 151.350132] overlayfs: conflicting lowerdir path mount: none is already mounted or mnt busy $ mount -t overlay none mnt ... -o lowerdir=lower:lower/a,upperdir=upper/0/u,workdir=upper/0/w [ 201.205045] overlayfs: overlapping lowerdir path mount: mount overlay on mnt failed: Too many levels of symbolic links $ mount -t overlay none mnt ... -o lowerdir=lower,upperdir=upper/0/u,workdir=upper/0/w $ mv base/upper/0/ base/lower/ $ find mnt/0 mnt/0 mnt/0/w find: 'mnt/0/w/work': Too many levels of symbolic links find: 'mnt/0/u': Too many levels of symbolic links Reported-by: syzbot+9c69c282adc4edd2b540@syzkaller.appspotmail.com Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/inode.c48
-rw-r--r--fs/overlayfs/namei.c8
-rw-r--r--fs/overlayfs/overlayfs.h3
-rw-r--r--fs/overlayfs/ovl_entry.h6
-rw-r--r--fs/overlayfs/super.c169
-rw-r--r--fs/overlayfs/util.c12
6 files changed, 229 insertions, 17 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index b48273e846ad..f7eba21effa5 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -777,6 +777,54 @@ struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
777 return inode; 777 return inode;
778} 778}
779 779
780bool ovl_lookup_trap_inode(struct super_block *sb, struct dentry *dir)
781{
782 struct inode *key = d_inode(dir);
783 struct inode *trap;
784 bool res;
785
786 trap = ilookup5(sb, (unsigned long) key, ovl_inode_test, key);
787 if (!trap)
788 return false;
789
790 res = IS_DEADDIR(trap) && !ovl_inode_upper(trap) &&
791 !ovl_inode_lower(trap);
792
793 iput(trap);
794 return res;
795}
796
797/*
798 * Create an inode cache entry for layer root dir, that will intentionally
799 * fail ovl_verify_inode(), so any lookup that will find some layer root
800 * will fail.
801 */
802struct inode *ovl_get_trap_inode(struct super_block *sb, struct dentry *dir)
803{
804 struct inode *key = d_inode(dir);
805 struct inode *trap;
806
807 if (!d_is_dir(dir))
808 return ERR_PTR(-ENOTDIR);
809
810 trap = iget5_locked(sb, (unsigned long) key, ovl_inode_test,
811 ovl_inode_set, key);
812 if (!trap)
813 return ERR_PTR(-ENOMEM);
814
815 if (!(trap->i_state & I_NEW)) {
816 /* Conflicting layer roots? */
817 iput(trap);
818 return ERR_PTR(-ELOOP);
819 }
820
821 trap->i_mode = S_IFDIR;
822 trap->i_flags = S_DEAD;
823 unlock_new_inode(trap);
824
825 return trap;
826}
827
780/* 828/*
781 * Does overlay inode need to be hashed by lower inode? 829 * Does overlay inode need to be hashed by lower inode?
782 */ 830 */
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index efd372312ef1..badf039267a2 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -18,6 +18,7 @@
18#include "overlayfs.h" 18#include "overlayfs.h"
19 19
20struct ovl_lookup_data { 20struct ovl_lookup_data {
21 struct super_block *sb;
21 struct qstr name; 22 struct qstr name;
22 bool is_dir; 23 bool is_dir;
23 bool opaque; 24 bool opaque;
@@ -244,6 +245,12 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
244 if (!d->metacopy || d->last) 245 if (!d->metacopy || d->last)
245 goto out; 246 goto out;
246 } else { 247 } else {
248 if (ovl_lookup_trap_inode(d->sb, this)) {
249 /* Caught in a trap of overlapping layers */
250 err = -ELOOP;
251 goto out_err;
252 }
253
247 if (last_element) 254 if (last_element)
248 d->is_dir = true; 255 d->is_dir = true;
249 if (d->last) 256 if (d->last)
@@ -819,6 +826,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
819 int err; 826 int err;
820 bool metacopy = false; 827 bool metacopy = false;
821 struct ovl_lookup_data d = { 828 struct ovl_lookup_data d = {
829 .sb = dentry->d_sb,
822 .name = dentry->d_name, 830 .name = dentry->d_name,
823 .is_dir = false, 831 .is_dir = false,
824 .opaque = false, 832 .opaque = false,
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index d26efed9f80a..cec40077b522 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -270,6 +270,7 @@ void ovl_clear_flag(unsigned long flag, struct inode *inode);
270bool ovl_test_flag(unsigned long flag, struct inode *inode); 270bool ovl_test_flag(unsigned long flag, struct inode *inode);
271bool ovl_inuse_trylock(struct dentry *dentry); 271bool ovl_inuse_trylock(struct dentry *dentry);
272void ovl_inuse_unlock(struct dentry *dentry); 272void ovl_inuse_unlock(struct dentry *dentry);
273bool ovl_is_inuse(struct dentry *dentry);
273bool ovl_need_index(struct dentry *dentry); 274bool ovl_need_index(struct dentry *dentry);
274int ovl_nlink_start(struct dentry *dentry); 275int ovl_nlink_start(struct dentry *dentry);
275void ovl_nlink_end(struct dentry *dentry); 276void ovl_nlink_end(struct dentry *dentry);
@@ -376,6 +377,8 @@ struct ovl_inode_params {
376struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev); 377struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev);
377struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real, 378struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
378 bool is_upper); 379 bool is_upper);
380bool ovl_lookup_trap_inode(struct super_block *sb, struct dentry *dir);
381struct inode *ovl_get_trap_inode(struct super_block *sb, struct dentry *dir);
379struct inode *ovl_get_inode(struct super_block *sb, 382struct inode *ovl_get_inode(struct super_block *sb,
380 struct ovl_inode_params *oip); 383 struct ovl_inode_params *oip);
381static inline void ovl_copyattr(struct inode *from, struct inode *to) 384static inline void ovl_copyattr(struct inode *from, struct inode *to)
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index ec237035333a..6ed1ace8f8b3 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -29,6 +29,8 @@ struct ovl_sb {
29 29
30struct ovl_layer { 30struct ovl_layer {
31 struct vfsmount *mnt; 31 struct vfsmount *mnt;
32 /* Trap in ovl inode cache */
33 struct inode *trap;
32 struct ovl_sb *fs; 34 struct ovl_sb *fs;
33 /* Index of this layer in fs root (upper idx == 0) */ 35 /* Index of this layer in fs root (upper idx == 0) */
34 int idx; 36 int idx;
@@ -65,6 +67,10 @@ struct ovl_fs {
65 /* Did we take the inuse lock? */ 67 /* Did we take the inuse lock? */
66 bool upperdir_locked; 68 bool upperdir_locked;
67 bool workdir_locked; 69 bool workdir_locked;
70 /* Traps in ovl inode cache */
71 struct inode *upperdir_trap;
72 struct inode *workdir_trap;
73 struct inode *indexdir_trap;
68 /* Inode numbers in all layers do not use the high xino_bits */ 74 /* Inode numbers in all layers do not use the high xino_bits */
69 unsigned int xino_bits; 75 unsigned int xino_bits;
70}; 76};
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 5ec4fc2f5d7e..746ea36f3171 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -215,6 +215,9 @@ static void ovl_free_fs(struct ovl_fs *ofs)
215{ 215{
216 unsigned i; 216 unsigned i;
217 217
218 iput(ofs->indexdir_trap);
219 iput(ofs->workdir_trap);
220 iput(ofs->upperdir_trap);
218 dput(ofs->indexdir); 221 dput(ofs->indexdir);
219 dput(ofs->workdir); 222 dput(ofs->workdir);
220 if (ofs->workdir_locked) 223 if (ofs->workdir_locked)
@@ -223,8 +226,10 @@ static void ovl_free_fs(struct ovl_fs *ofs)
223 if (ofs->upperdir_locked) 226 if (ofs->upperdir_locked)
224 ovl_inuse_unlock(ofs->upper_mnt->mnt_root); 227 ovl_inuse_unlock(ofs->upper_mnt->mnt_root);
225 mntput(ofs->upper_mnt); 228 mntput(ofs->upper_mnt);
226 for (i = 0; i < ofs->numlower; i++) 229 for (i = 0; i < ofs->numlower; i++) {
230 iput(ofs->lower_layers[i].trap);
227 mntput(ofs->lower_layers[i].mnt); 231 mntput(ofs->lower_layers[i].mnt);
232 }
228 for (i = 0; i < ofs->numlowerfs; i++) 233 for (i = 0; i < ofs->numlowerfs; i++)
229 free_anon_bdev(ofs->lower_fs[i].pseudo_dev); 234 free_anon_bdev(ofs->lower_fs[i].pseudo_dev);
230 kfree(ofs->lower_layers); 235 kfree(ofs->lower_layers);
@@ -983,7 +988,26 @@ static const struct xattr_handler *ovl_xattr_handlers[] = {
983 NULL 988 NULL
984}; 989};
985 990
986static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath) 991static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
992 struct inode **ptrap, const char *name)
993{
994 struct inode *trap;
995 int err;
996
997 trap = ovl_get_trap_inode(sb, dir);
998 err = PTR_ERR(trap);
999 if (IS_ERR(trap)) {
1000 if (err == -ELOOP)
1001 pr_err("overlayfs: conflicting %s path\n", name);
1002 return err;
1003 }
1004
1005 *ptrap = trap;
1006 return 0;
1007}
1008
1009static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
1010 struct path *upperpath)
987{ 1011{
988 struct vfsmount *upper_mnt; 1012 struct vfsmount *upper_mnt;
989 int err; 1013 int err;
@@ -1003,6 +1027,11 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath)
1003 if (err) 1027 if (err)
1004 goto out; 1028 goto out;
1005 1029
1030 err = ovl_setup_trap(sb, upperpath->dentry, &ofs->upperdir_trap,
1031 "upperdir");
1032 if (err)
1033 goto out;
1034
1006 upper_mnt = clone_private_mount(upperpath); 1035 upper_mnt = clone_private_mount(upperpath);
1007 err = PTR_ERR(upper_mnt); 1036 err = PTR_ERR(upper_mnt);
1008 if (IS_ERR(upper_mnt)) { 1037 if (IS_ERR(upper_mnt)) {
@@ -1029,7 +1058,8 @@ out:
1029 return err; 1058 return err;
1030} 1059}
1031 1060
1032static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) 1061static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
1062 struct path *workpath)
1033{ 1063{
1034 struct vfsmount *mnt = ofs->upper_mnt; 1064 struct vfsmount *mnt = ofs->upper_mnt;
1035 struct dentry *temp; 1065 struct dentry *temp;
@@ -1044,6 +1074,10 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
1044 if (!ofs->workdir) 1074 if (!ofs->workdir)
1045 goto out; 1075 goto out;
1046 1076
1077 err = ovl_setup_trap(sb, ofs->workdir, &ofs->workdir_trap, "workdir");
1078 if (err)
1079 goto out;
1080
1047 /* 1081 /*
1048 * Upper should support d_type, else whiteouts are visible. Given 1082 * Upper should support d_type, else whiteouts are visible. Given
1049 * workdir and upper are on same fs, we can do iterate_dir() on 1083 * workdir and upper are on same fs, we can do iterate_dir() on
@@ -1104,7 +1138,8 @@ out:
1104 return err; 1138 return err;
1105} 1139}
1106 1140
1107static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath) 1141static int ovl_get_workdir(struct super_block *sb, struct ovl_fs *ofs,
1142 struct path *upperpath)
1108{ 1143{
1109 int err; 1144 int err;
1110 struct path workpath = { }; 1145 struct path workpath = { };
@@ -1135,19 +1170,16 @@ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
1135 pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); 1170 pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n");
1136 } 1171 }
1137 1172
1138 err = ovl_make_workdir(ofs, &workpath); 1173 err = ovl_make_workdir(sb, ofs, &workpath);
1139 if (err)
1140 goto out;
1141 1174
1142 err = 0;
1143out: 1175out:
1144 path_put(&workpath); 1176 path_put(&workpath);
1145 1177
1146 return err; 1178 return err;
1147} 1179}
1148 1180
1149static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe, 1181static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
1150 struct path *upperpath) 1182 struct ovl_entry *oe, struct path *upperpath)
1151{ 1183{
1152 struct vfsmount *mnt = ofs->upper_mnt; 1184 struct vfsmount *mnt = ofs->upper_mnt;
1153 int err; 1185 int err;
@@ -1166,6 +1198,11 @@ static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
1166 1198
1167 ofs->indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true); 1199 ofs->indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true);
1168 if (ofs->indexdir) { 1200 if (ofs->indexdir) {
1201 err = ovl_setup_trap(sb, ofs->indexdir, &ofs->indexdir_trap,
1202 "indexdir");
1203 if (err)
1204 goto out;
1205
1169 /* 1206 /*
1170 * Verify upper root is exclusively associated with index dir. 1207 * Verify upper root is exclusively associated with index dir.
1171 * Older kernels stored upper fh in "trusted.overlay.origin" 1208 * Older kernels stored upper fh in "trusted.overlay.origin"
@@ -1253,8 +1290,8 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
1253 return ofs->numlowerfs; 1290 return ofs->numlowerfs;
1254} 1291}
1255 1292
1256static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack, 1293static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs,
1257 unsigned int numlower) 1294 struct path *stack, unsigned int numlower)
1258{ 1295{
1259 int err; 1296 int err;
1260 unsigned int i; 1297 unsigned int i;
@@ -1272,16 +1309,28 @@ static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack,
1272 1309
1273 for (i = 0; i < numlower; i++) { 1310 for (i = 0; i < numlower; i++) {
1274 struct vfsmount *mnt; 1311 struct vfsmount *mnt;
1312 struct inode *trap;
1275 int fsid; 1313 int fsid;
1276 1314
1277 err = fsid = ovl_get_fsid(ofs, &stack[i]); 1315 err = fsid = ovl_get_fsid(ofs, &stack[i]);
1278 if (err < 0) 1316 if (err < 0)
1279 goto out; 1317 goto out;
1280 1318
1319 err = -EBUSY;
1320 if (ovl_is_inuse(stack[i].dentry)) {
1321 pr_err("overlayfs: lowerdir is in-use as upperdir/workdir\n");
1322 goto out;
1323 }
1324
1325 err = ovl_setup_trap(sb, stack[i].dentry, &trap, "lowerdir");
1326 if (err)
1327 goto out;
1328
1281 mnt = clone_private_mount(&stack[i]); 1329 mnt = clone_private_mount(&stack[i]);
1282 err = PTR_ERR(mnt); 1330 err = PTR_ERR(mnt);
1283 if (IS_ERR(mnt)) { 1331 if (IS_ERR(mnt)) {
1284 pr_err("overlayfs: failed to clone lowerpath\n"); 1332 pr_err("overlayfs: failed to clone lowerpath\n");
1333 iput(trap);
1285 goto out; 1334 goto out;
1286 } 1335 }
1287 1336
@@ -1291,6 +1340,7 @@ static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack,
1291 */ 1340 */
1292 mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME; 1341 mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
1293 1342
1343 ofs->lower_layers[ofs->numlower].trap = trap;
1294 ofs->lower_layers[ofs->numlower].mnt = mnt; 1344 ofs->lower_layers[ofs->numlower].mnt = mnt;
1295 ofs->lower_layers[ofs->numlower].idx = i + 1; 1345 ofs->lower_layers[ofs->numlower].idx = i + 1;
1296 ofs->lower_layers[ofs->numlower].fsid = fsid; 1346 ofs->lower_layers[ofs->numlower].fsid = fsid;
@@ -1385,7 +1435,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
1385 goto out_err; 1435 goto out_err;
1386 } 1436 }
1387 1437
1388 err = ovl_get_lower_layers(ofs, stack, numlower); 1438 err = ovl_get_lower_layers(sb, ofs, stack, numlower);
1389 if (err) 1439 if (err)
1390 goto out_err; 1440 goto out_err;
1391 1441
@@ -1417,6 +1467,85 @@ out_err:
1417 goto out; 1467 goto out;
1418} 1468}
1419 1469
1470/*
1471 * Check if this layer root is a descendant of:
1472 * - another layer of this overlayfs instance
1473 * - upper/work dir of any overlayfs instance
1474 * - a disconnected dentry (detached root)
1475 */
1476static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
1477 const char *name)
1478{
1479 struct dentry *next, *parent;
1480 bool is_root = false;
1481 int err = 0;
1482
1483 if (!dentry || dentry == dentry->d_sb->s_root)
1484 return 0;
1485
1486 next = dget(dentry);
1487 /* Walk back ancestors to fs root (inclusive) looking for traps */
1488 do {
1489 parent = dget_parent(next);
1490 is_root = (parent == next);
1491 if (ovl_is_inuse(parent)) {
1492 err = -EBUSY;
1493 pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n",
1494 name);
1495 } else if (ovl_lookup_trap_inode(sb, parent)) {
1496 err = -ELOOP;
1497 pr_err("overlayfs: overlapping %s path\n", name);
1498 }
1499 dput(next);
1500 next = parent;
1501 } while (!err && !is_root);
1502
1503 /* Did we really walk to fs root or found a detached root? */
1504 if (!err && next != dentry->d_sb->s_root) {
1505 err = -ESTALE;
1506 pr_err("overlayfs: disconnected %s path\n", name);
1507 }
1508
1509 dput(next);
1510
1511 return err;
1512}
1513
1514/*
1515 * Check if any of the layers or work dirs overlap.
1516 */
1517static int ovl_check_overlapping_layers(struct super_block *sb,
1518 struct ovl_fs *ofs)
1519{
1520 int i, err;
1521
1522 if (ofs->upper_mnt) {
1523 err = ovl_check_layer(sb, ofs->upper_mnt->mnt_root, "upperdir");
1524 if (err)
1525 return err;
1526
1527 /*
1528 * Checking workbasedir avoids hitting ovl_is_inuse(parent) of
1529 * this instance and covers overlapping work and index dirs,
1530 * unless work or index dir have been moved since created inside
1531 * workbasedir. In that case, we already have their traps in
1532 * inode cache and we will catch that case on lookup.
1533 */
1534 err = ovl_check_layer(sb, ofs->workbasedir, "workdir");
1535 if (err)
1536 return err;
1537 }
1538
1539 for (i = 0; i < ofs->numlower; i++) {
1540 err = ovl_check_layer(sb, ofs->lower_layers[i].mnt->mnt_root,
1541 "lowerdir");
1542 if (err)
1543 return err;
1544 }
1545
1546 return 0;
1547}
1548
1420static int ovl_fill_super(struct super_block *sb, void *data, int silent) 1549static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1421{ 1550{
1422 struct path upperpath = { }; 1551 struct path upperpath = { };
@@ -1456,17 +1585,20 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1456 if (ofs->config.xino != OVL_XINO_OFF) 1585 if (ofs->config.xino != OVL_XINO_OFF)
1457 ofs->xino_bits = BITS_PER_LONG - 32; 1586 ofs->xino_bits = BITS_PER_LONG - 32;
1458 1587
1588 /* alloc/destroy_inode needed for setting up traps in inode cache */
1589 sb->s_op = &ovl_super_operations;
1590
1459 if (ofs->config.upperdir) { 1591 if (ofs->config.upperdir) {
1460 if (!ofs->config.workdir) { 1592 if (!ofs->config.workdir) {
1461 pr_err("overlayfs: missing 'workdir'\n"); 1593 pr_err("overlayfs: missing 'workdir'\n");
1462 goto out_err; 1594 goto out_err;
1463 } 1595 }
1464 1596
1465 err = ovl_get_upper(ofs, &upperpath); 1597 err = ovl_get_upper(sb, ofs, &upperpath);
1466 if (err) 1598 if (err)
1467 goto out_err; 1599 goto out_err;
1468 1600
1469 err = ovl_get_workdir(ofs, &upperpath); 1601 err = ovl_get_workdir(sb, ofs, &upperpath);
1470 if (err) 1602 if (err)
1471 goto out_err; 1603 goto out_err;
1472 1604
@@ -1487,7 +1619,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1487 sb->s_flags |= SB_RDONLY; 1619 sb->s_flags |= SB_RDONLY;
1488 1620
1489 if (!(ovl_force_readonly(ofs)) && ofs->config.index) { 1621 if (!(ovl_force_readonly(ofs)) && ofs->config.index) {
1490 err = ovl_get_indexdir(ofs, oe, &upperpath); 1622 err = ovl_get_indexdir(sb, ofs, oe, &upperpath);
1491 if (err) 1623 if (err)
1492 goto out_free_oe; 1624 goto out_free_oe;
1493 1625
@@ -1500,6 +1632,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1500 1632
1501 } 1633 }
1502 1634
1635 err = ovl_check_overlapping_layers(sb, ofs);
1636 if (err)
1637 goto out_free_oe;
1638
1503 /* Show index=off in /proc/mounts for forced r/o mount */ 1639 /* Show index=off in /proc/mounts for forced r/o mount */
1504 if (!ofs->indexdir) { 1640 if (!ofs->indexdir) {
1505 ofs->config.index = false; 1641 ofs->config.index = false;
@@ -1521,7 +1657,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1521 cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); 1657 cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
1522 1658
1523 sb->s_magic = OVERLAYFS_SUPER_MAGIC; 1659 sb->s_magic = OVERLAYFS_SUPER_MAGIC;
1524 sb->s_op = &ovl_super_operations;
1525 sb->s_xattr = ovl_xattr_handlers; 1660 sb->s_xattr = ovl_xattr_handlers;
1526 sb->s_fs_info = ofs; 1661 sb->s_fs_info = ofs;
1527 sb->s_flags |= SB_POSIXACL; 1662 sb->s_flags |= SB_POSIXACL;
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 4035e640f402..e135064e87ad 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -652,6 +652,18 @@ void ovl_inuse_unlock(struct dentry *dentry)
652 } 652 }
653} 653}
654 654
655bool ovl_is_inuse(struct dentry *dentry)
656{
657 struct inode *inode = d_inode(dentry);
658 bool inuse;
659
660 spin_lock(&inode->i_lock);
661 inuse = (inode->i_state & I_OVL_INUSE);
662 spin_unlock(&inode->i_lock);
663
664 return inuse;
665}
666
655/* 667/*
656 * Does this overlay dentry need to be indexed on copy up? 668 * Does this overlay dentry need to be indexed on copy up?
657 */ 669 */