summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-07-11 08:58:34 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2017-07-13 16:06:45 -0400
commitea3dad18dc5f778cfd931311a91a9315aa0065a3 (patch)
treed2a1a3e51e877eb9c0ad249e5dcf4c17a33f01a5 /fs
parent8fc646b44385ff0a9853f6590497e43049eeb311 (diff)
ovl: mark parent impure on ovl_link()
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/dir.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 641d9ee97f91..48b70e6490f3 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -481,17 +481,30 @@ out_cleanup:
481} 481}
482 482
483static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, 483static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
484 struct cattr *attr, struct dentry *hardlink) 484 struct cattr *attr, struct dentry *hardlink,
485 bool origin)
485{ 486{
486 int err; 487 int err;
487 const struct cred *old_cred; 488 const struct cred *old_cred;
488 struct cred *override_cred; 489 struct cred *override_cred;
490 struct dentry *parent = dentry->d_parent;
489 491
490 err = ovl_copy_up(dentry->d_parent); 492 err = ovl_copy_up(parent);
491 if (err) 493 if (err)
492 return err; 494 return err;
493 495
494 old_cred = ovl_override_creds(dentry->d_sb); 496 old_cred = ovl_override_creds(dentry->d_sb);
497
498 /*
499 * When linking a file with copy up origin into a new parent, mark the
500 * new parent dir "impure".
501 */
502 if (origin) {
503 err = ovl_set_impure(parent, ovl_dentry_upper(parent));
504 if (err)
505 goto out_revert_creds;
506 }
507
495 err = -ENOMEM; 508 err = -ENOMEM;
496 override_cred = prepare_creds(); 509 override_cred = prepare_creds();
497 if (override_cred) { 510 if (override_cred) {
@@ -550,7 +563,7 @@ static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
550 inode_init_owner(inode, dentry->d_parent->d_inode, mode); 563 inode_init_owner(inode, dentry->d_parent->d_inode, mode);
551 attr.mode = inode->i_mode; 564 attr.mode = inode->i_mode;
552 565
553 err = ovl_create_or_link(dentry, inode, &attr, NULL); 566 err = ovl_create_or_link(dentry, inode, &attr, NULL, false);
554 if (err) 567 if (err)
555 iput(inode); 568 iput(inode);
556 569
@@ -609,7 +622,8 @@ static int ovl_link(struct dentry *old, struct inode *newdir,
609 inode = d_inode(old); 622 inode = d_inode(old);
610 ihold(inode); 623 ihold(inode);
611 624
612 err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old)); 625 err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old),
626 ovl_type_origin(old));
613 if (err) 627 if (err)
614 iput(inode); 628 iput(inode);
615 629