瀏覽代碼

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>
Chandan Rajendra 8 年之前
父節點
當前提交
2a9c6d066e
共有 2 個文件被更改,包括 17 次插入2 次删除
  1. 1 0
      fs/overlayfs/ovl_entry.h
  2. 16 2
      fs/overlayfs/super.c

+ 1 - 0
fs/overlayfs/ovl_entry.h

@@ -19,6 +19,7 @@ struct ovl_config {
 
 
 struct ovl_layer {
 struct ovl_layer {
 	struct vfsmount *mnt;
 	struct vfsmount *mnt;
+	dev_t pseudo_dev;
 };
 };
 
 
 struct ovl_path {
 struct ovl_path {

+ 16 - 2
fs/overlayfs/super.c

@@ -219,8 +219,10 @@ static void ovl_put_super(struct super_block *sb)
 	if (ufs->upper_mnt && ufs->upperdir_locked)
 	if (ufs->upper_mnt && ufs->upperdir_locked)
 		ovl_inuse_unlock(ufs->upper_mnt->mnt_root);
 		ovl_inuse_unlock(ufs->upper_mnt->mnt_root);
 	mntput(ufs->upper_mnt);
 	mntput(ufs->upper_mnt);
-	for (i = 0; i < ufs->numlower; i++)
+	for (i = 0; i < ufs->numlower; i++) {
 		mntput(ufs->lower_layers[i].mnt);
 		mntput(ufs->lower_layers[i].mnt);
+		free_anon_bdev(ufs->lower_layers[i].pseudo_dev);
+	}
 	kfree(ufs->lower_layers);
 	kfree(ufs->lower_layers);
 
 
 	kfree(ufs->config.lowerdir);
 	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;
 		goto out_put_workdir;
 	for (i = 0; i < numlower; i++) {
 	for (i = 0; i < numlower; i++) {
 		struct vfsmount *mnt;
 		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]);
 		mnt = clone_private_mount(&stack[i]);
 		err = PTR_ERR(mnt);
 		err = PTR_ERR(mnt);
 		if (IS_ERR(mnt)) {
 		if (IS_ERR(mnt)) {
 			pr_err("overlayfs: failed to clone lowerpath\n");
 			pr_err("overlayfs: failed to clone lowerpath\n");
+			free_anon_bdev(dev);
 			goto out_put_lower_layers;
 			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;
 		mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
 
 
 		ufs->lower_layers[ufs->numlower].mnt = mnt;
 		ufs->lower_layers[ufs->numlower].mnt = mnt;
+		ufs->lower_layers[ufs->numlower].pseudo_dev = dev;
 		ufs->numlower++;
 		ufs->numlower++;
 
 
 		/* Check if all lower layers are on same sb */
 		/* Check if all lower layers are on same sb */
@@ -1162,8 +1173,11 @@ out_put_indexdir:
 out_free_oe:
 out_free_oe:
 	kfree(oe);
 	kfree(oe);
 out_put_lower_layers:
 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);
 		mntput(ufs->lower_layers[i].mnt);
+	}
 	kfree(ufs->lower_layers);
 	kfree(ufs->lower_layers);
 out_put_workdir:
 out_put_workdir:
 	dput(ufs->workdir);
 	dput(ufs->workdir);