summaryrefslogtreecommitdiff
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorChandan Rajendra <chandan@linux.vnet.ibm.com>2017-11-01 21:12:49 +0300
committerMiklos Szeredi <mszeredi@redhat.com>2017-11-09 12:23:27 +0300
commit2a9c6d066e98c1fe51a735b1439929f2f2afd891 (patch)
tree31f76a4243df12764b67ca8509da7b3ab1ed6ced /fs/overlayfs
parentb93436320c1e9089a055941523571cd7c037f7cb (diff)
downloadlinux-2a9c6d066e98c1fe51a735b1439929f2f2afd891.tar.xz
ovl: allocate anonymous devs for lowerdirs
Generate unique values of st_dev per lower layer for non-samefs overlay mount. The unique values are obtained by allocating anonymous bdevs for each of the lowerdirs in the overlayfs instance. The anonymous bdev is going to be returned by stat(2) for lowerdir non-dir entries in non-samefs case. [amir: split from ovl_getattr() and re-structure patches] Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/ovl_entry.h1
-rw-r--r--fs/overlayfs/super.c18
2 files changed, 17 insertions, 2 deletions
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index 1e28329b5db8..93eb6a044dd2 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -19,6 +19,7 @@ struct ovl_config {
struct ovl_layer {
struct vfsmount *mnt;
+ dev_t pseudo_dev;
};
struct ovl_path {
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index a10fff49194b..2c9f48096ff0 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -219,8 +219,10 @@ static void ovl_put_super(struct super_block *sb)
if (ufs->upper_mnt && ufs->upperdir_locked)
ovl_inuse_unlock(ufs->upper_mnt->mnt_root);
mntput(ufs->upper_mnt);
- for (i = 0; i < ufs->numlower; i++)
+ for (i = 0; i < ufs->numlower; i++) {
mntput(ufs->lower_layers[i].mnt);
+ free_anon_bdev(ufs->lower_layers[i].pseudo_dev);
+ }
kfree(ufs->lower_layers);
kfree(ufs->config.lowerdir);
@@ -1032,11 +1034,19 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
goto out_put_workdir;
for (i = 0; i < numlower; i++) {
struct vfsmount *mnt;
+ dev_t dev;
+
+ err = get_anon_bdev(&dev);
+ if (err) {
+ pr_err("overlayfs: failed to get anonymous bdev for lowerpath\n");
+ goto out_put_lower_layers;
+ }
mnt = clone_private_mount(&stack[i]);
err = PTR_ERR(mnt);
if (IS_ERR(mnt)) {
pr_err("overlayfs: failed to clone lowerpath\n");
+ free_anon_bdev(dev);
goto out_put_lower_layers;
}
/*
@@ -1046,6 +1056,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
ufs->lower_layers[ufs->numlower].mnt = mnt;
+ ufs->lower_layers[ufs->numlower].pseudo_dev = dev;
ufs->numlower++;
/* Check if all lower layers are on same sb */
@@ -1162,8 +1173,11 @@ out_put_indexdir:
out_free_oe:
kfree(oe);
out_put_lower_layers:
- for (i = 0; i < ufs->numlower; i++)
+ for (i = 0; i < ufs->numlower; i++) {
+ if (ufs->lower_layers[i].mnt)
+ free_anon_bdev(ufs->lower_layers[i].pseudo_dev);
mntput(ufs->lower_layers[i].mnt);
+ }
kfree(ufs->lower_layers);
out_put_workdir:
dput(ufs->workdir);