]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ovl: allocate anonymous devs for lowerdirs
authorChandan Rajendra <chandan@linux.vnet.ibm.com>
Wed, 1 Nov 2017 18:12:49 +0000 (20:12 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 9 Nov 2017 09:23:27 +0000 (10:23 +0100)
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>
fs/overlayfs/ovl_entry.h
fs/overlayfs/super.c

index 1e28329b5db88e08d36812d25a54a387ee74a98b..93eb6a044dd24e1230acf63a1ca82151983e9469 100644 (file)
@@ -19,6 +19,7 @@ struct ovl_config {
 
 struct ovl_layer {
        struct vfsmount *mnt;
+       dev_t pseudo_dev;
 };
 
 struct ovl_path {
index a10fff49194b9a75228a29b1d09a5435d904e906..2c9f48096ff03090348431ffe93ae6aa68fa5e39 100644 (file)
@@ -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 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 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);