ovl: mark parent impure on ovl_link()
authorAmir Goldstein <amir73il@gmail.com>
Tue, 11 Jul 2017 12:58:34 +0000 (15:58 +0300)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 13 Jul 2017 20:06:45 +0000 (22:06 +0200)
When linking a file with copy up origin into a new parent, mark the
new parent dir "impure".

Fixes: ee1d6d37b6b8 ("ovl: mark upper dir with type origin entries "impure"")
Cc: <stable@vger.kernel.org> # v4.12
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/dir.c

index 641d9ee97f91fcc3a92b456e7007578dbe269d2e..48b70e6490f32e9c7f9c34f8dcb20735279b3946 100644 (file)
@@ -481,17 +481,30 @@ out_cleanup:
 }
 
 static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
-                             struct cattr *attr, struct dentry *hardlink)
+                             struct cattr *attr, struct dentry *hardlink,
+                             bool origin)
 {
        int err;
        const struct cred *old_cred;
        struct cred *override_cred;
+       struct dentry *parent = dentry->d_parent;
 
-       err = ovl_copy_up(dentry->d_parent);
+       err = ovl_copy_up(parent);
        if (err)
                return err;
 
        old_cred = ovl_override_creds(dentry->d_sb);
+
+       /*
+        * When linking a file with copy up origin into a new parent, mark the
+        * new parent dir "impure".
+        */
+       if (origin) {
+               err = ovl_set_impure(parent, ovl_dentry_upper(parent));
+               if (err)
+                       goto out_revert_creds;
+       }
+
        err = -ENOMEM;
        override_cred = prepare_creds();
        if (override_cred) {
@@ -550,7 +563,7 @@ static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
        inode_init_owner(inode, dentry->d_parent->d_inode, mode);
        attr.mode = inode->i_mode;
 
-       err = ovl_create_or_link(dentry, inode, &attr, NULL);
+       err = ovl_create_or_link(dentry, inode, &attr, NULL, false);
        if (err)
                iput(inode);
 
@@ -609,7 +622,8 @@ static int ovl_link(struct dentry *old, struct inode *newdir,
        inode = d_inode(old);
        ihold(inode);
 
-       err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old));
+       err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old),
+                                ovl_type_origin(old));
        if (err)
                iput(inode);