diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/overlayfs/ovl_entry.h | 1 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 18 |
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); |