diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-07 18:23:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-07 18:23:25 -0500 |
commit | 01ffa3df223c061435dfaab8daba7c0109a3c6d5 (patch) | |
tree | ac7ace5912e080eda1d01b1539278273f5daa45e /fs | |
parent | 256faedcfd646161477d47a1a78c32a562d2e845 (diff) | |
parent | b81de061fa59f17d2730aabb1b84419ef3913810 (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.c | 10 | ||||
-rw-r--r-- | fs/overlayfs/inode.c | 2 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 13 |
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 | ||
342 | static const struct dentry_operations ovl_reval_dentry_operations = { | 344 | static 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 | }; |