ovl: check if all layers are on the same fs
authorAmir Goldstein <amir73il@gmail.com>
Wed, 22 Mar 2017 12:42:21 +0000 (08:42 -0400)
committerMiklos Szeredi <mszeredi@redhat.com>
Fri, 5 May 2017 09:38:57 +0000 (11:38 +0200)
Some features can only work when all layers are on the same fs.  Test this
condition during mount time, so features can check them later.

Add helper ovl_same_sb() to return the common super block in case all
layers are on the same fs.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/super.c
fs/overlayfs/util.c

index 741dc0b6931fe90fc62874989c93e659f7e7a4ef..c851158324e23678b5af3f07ab10db3b8a759050 100644 (file)
@@ -151,6 +151,7 @@ int ovl_want_write(struct dentry *dentry);
 void ovl_drop_write(struct dentry *dentry);
 struct dentry *ovl_workdir(struct dentry *dentry);
 const struct cred *ovl_override_creds(struct super_block *sb);
+struct super_block *ovl_same_sb(struct super_block *sb);
 struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
 bool ovl_dentry_remote(struct dentry *dentry);
 bool ovl_dentry_weird(struct dentry *dentry);
index 59614faa14c315fb8f6e5998f91bc7061f818bab..b2023ddb85323725b8bbfa687f31fc854c1ba5e9 100644 (file)
@@ -29,6 +29,8 @@ struct ovl_fs {
        const struct cred *creator_cred;
        bool tmpfile;
        wait_queue_head_t copyup_wq;
+       /* sb common to all layers */
+       struct super_block *same_sb;
 };
 
 /* private information held for every overlayfs dentry */
index 6faefa54cb5ed2437c5e3c9d57f8984cdb266a48..9828b7de89992e64a1900a277b58423dde7b992a 100644 (file)
@@ -914,11 +914,19 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
                ufs->lower_mnt[ufs->numlower] = mnt;
                ufs->numlower++;
+
+               /* Check if all lower layers are on same sb */
+               if (i == 0)
+                       ufs->same_sb = mnt->mnt_sb;
+               else if (ufs->same_sb != mnt->mnt_sb)
+                       ufs->same_sb = NULL;
        }
 
        /* If the upper fs is nonexistent, we mark overlayfs r/o too */
        if (!ufs->upper_mnt)
                sb->s_flags |= MS_RDONLY;
+       else if (ufs->upper_mnt->mnt_sb != ufs->same_sb)
+               ufs->same_sb = NULL;
 
        if (remote)
                sb->s_d_op = &ovl_reval_dentry_operations;
index 35b8959db5ee00e455d770da3363a4a94b52f8a1..2bd4c264ccbefca9caccf9c3613149068c5d6135 100644 (file)
@@ -41,6 +41,13 @@ const struct cred *ovl_override_creds(struct super_block *sb)
        return override_creds(ofs->creator_cred);
 }
 
+struct super_block *ovl_same_sb(struct super_block *sb)
+{
+       struct ovl_fs *ofs = sb->s_fs_info;
+
+       return ofs->same_sb;
+}
+
 struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
 {
        size_t size = offsetof(struct ovl_entry, lowerstack[numlower]);