aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-07 18:23:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-07 18:23:25 -0500
commit01ffa3df223c061435dfaab8daba7c0109a3c6d5 (patch)
treeac7ace5912e080eda1d01b1539278273f5daa45e /fs
parent256faedcfd646161477d47a1a78c32a562d2e845 (diff)
parentb81de061fa59f17d2730aabb1b84419ef3913810 (diff)
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi: "Overlayfs bug fixes. All marked as -stable material" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: copy new uid/gid into overlayfs runtime inode ovl: ignore lower entries when checking purity of non-directory entries ovl: fix getcwd() failure after unsuccessful rmdir ovl: fix working on distributed fs as lower layer
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/dir.c10
-rw-r--r--fs/overlayfs/inode.c2
-rw-r--r--fs/overlayfs/super.c13
3 files changed, 19 insertions, 6 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index ed95272d57a6..52f6de5d40a9 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -618,7 +618,8 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir)
618 * sole user of this dentry. Too tricky... Just unhash for 618 * sole user of this dentry. Too tricky... Just unhash for
619 * now. 619 * now.
620 */ 620 */
621 d_drop(dentry); 621 if (!err)
622 d_drop(dentry);
622 inode_unlock(dir); 623 inode_unlock(dir);
623 624
624 return err; 625 return err;
@@ -903,6 +904,13 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old,
903 if (!overwrite && new_is_dir && !old_opaque && new_opaque) 904 if (!overwrite && new_is_dir && !old_opaque && new_opaque)
904 ovl_remove_opaque(newdentry); 905 ovl_remove_opaque(newdentry);
905 906
907 /*
908 * Old dentry now lives in different location. Dentries in
909 * lowerstack are stale. We cannot drop them here because
910 * access to them is lockless. This could be only pure upper
911 * or opaque directory - numlower is zero. Or upper non-dir
912 * entry - its pureness is tracked by flag opaque.
913 */
906 if (old_opaque != new_opaque) { 914 if (old_opaque != new_opaque) {
907 ovl_dentry_set_opaque(old, new_opaque); 915 ovl_dentry_set_opaque(old, new_opaque);
908 if (!overwrite) 916 if (!overwrite)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 49e204560655..a4ff5d0d7db9 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -65,6 +65,8 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
65 65
66 inode_lock(upperdentry->d_inode); 66 inode_lock(upperdentry->d_inode);
67 err = notify_change(upperdentry, attr, NULL); 67 err = notify_change(upperdentry, attr, NULL);
68 if (!err)
69 ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
68 inode_unlock(upperdentry->d_inode); 70 inode_unlock(upperdentry->d_inode);
69 } 71 }
70 ovl_drop_write(dentry); 72 ovl_drop_write(dentry);
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 8d826bd56b26..619ad4b016d2 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -76,12 +76,14 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
76 if (oe->__upperdentry) { 76 if (oe->__upperdentry) {
77 type = __OVL_PATH_UPPER; 77 type = __OVL_PATH_UPPER;
78 78
79 if (oe->numlower) { 79 /*
80 if (S_ISDIR(dentry->d_inode->i_mode)) 80 * Non-dir dentry can hold lower dentry from previous
81 type |= __OVL_PATH_MERGE; 81 * location. Its purity depends only on opaque flag.
82 } else if (!oe->opaque) { 82 */
83 if (oe->numlower && S_ISDIR(dentry->d_inode->i_mode))
84 type |= __OVL_PATH_MERGE;
85 else if (!oe->opaque)
83 type |= __OVL_PATH_PURE; 86 type |= __OVL_PATH_PURE;
84 }
85 } else { 87 } else {
86 if (oe->numlower > 1) 88 if (oe->numlower > 1)
87 type |= __OVL_PATH_MERGE; 89 type |= __OVL_PATH_MERGE;
@@ -341,6 +343,7 @@ static const struct dentry_operations ovl_dentry_operations = {
341 343
342static const struct dentry_operations ovl_reval_dentry_operations = { 344static const struct dentry_operations ovl_reval_dentry_operations = {
343 .d_release = ovl_dentry_release, 345 .d_release = ovl_dentry_release,
346 .d_select_inode = ovl_d_select_inode,
344 .d_revalidate = ovl_dentry_revalidate, 347 .d_revalidate = ovl_dentry_revalidate,
345 .d_weak_revalidate = ovl_dentry_weak_revalidate, 348 .d_weak_revalidate = ovl_dentry_weak_revalidate,
346}; 349};