aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/overlayfs/inode.c16
-rw-r--r--fs/overlayfs/super.c15
2 files changed, 14 insertions, 17 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 60f7b8f092f2..79e8994e3bc1 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -121,13 +121,12 @@ static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid)
*/
stat->dev = dentry->d_sb->s_dev;
stat->ino = dentry->d_inode->i_ino;
- } else if (fsid) {
+ } else {
/*
* For non-samefs setup, if we cannot map all layers st_ino
* to a unified address space, we need to make sure that st_dev
- * is unique per lower fs. Upper layer uses real st_dev and
- * lower layers use the unique anonymous bdev assigned to the
- * lower fs.
+ * is unique per underlying fs, so we use the unique anonymous
+ * bdev assigned to the underlying fs.
*/
stat->dev = OVL_FS(dentry->d_sb)->fs[fsid].pseudo_dev;
}
@@ -143,7 +142,6 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
struct path realpath;
const struct cred *old_cred;
bool is_dir = S_ISDIR(dentry->d_inode->i_mode);
- bool samefs = ovl_same_fs(dentry->d_sb);
int fsid = 0;
int err;
bool metacopy_blocks = false;
@@ -198,13 +196,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
(!ovl_verify_lower(dentry->d_sb) &&
(is_dir || lowerstat.nlink == 1))) {
fsid = ovl_layer_lower(dentry)->fsid;
- /*
- * Cannot use origin st_dev;st_ino because
- * origin inode content may differ from overlay
- * inode content.
- */
- if (samefs || fsid)
- stat->ino = lowerstat.ino;
+ stat->ino = lowerstat.ino;
}
/*
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 7cf543608b9f..dcdcb4e3003a 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -229,8 +229,7 @@ static void ovl_free_fs(struct ovl_fs *ofs)
mntput(ofs->layers[i].mnt);
}
kfree(ofs->layers);
- /* fs[0].pseudo_dev is either null or real upper st_dev */
- for (i = 1; i < ofs->numfs; i++)
+ for (i = 0; i < ofs->numfs; i++)
free_anon_bdev(ofs->fs[i].pseudo_dev);
kfree(ofs->fs);
@@ -1341,13 +1340,19 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
ofs->numlayer = 1;
/*
- * All lower layers that share the same fs as upper layer, use the real
- * upper st_dev.
+ * All lower layers that share the same fs as upper layer, use the same
+ * pseudo_dev as upper layer. Allocate fs[0].pseudo_dev even for lower
+ * only overlay to simplify ovl_fs_free().
* is_lower will be set if upper fs is shared with a lower layer.
*/
+ err = get_anon_bdev(&ofs->fs[0].pseudo_dev);
+ if (err) {
+ pr_err("failed to get anonymous bdev for upper fs\n");
+ goto out;
+ }
+
if (ofs->upper_mnt) {
ofs->fs[0].sb = ofs->upper_mnt->mnt_sb;
- ofs->fs[0].pseudo_dev = ofs->upper_mnt->mnt_sb->s_dev;
ofs->fs[0].is_lower = false;
}