Commit 01ffa3df authored by Linus Torvalds's avatar Linus Torvalds

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
parents 256faedc b81de061
...@@ -618,6 +618,7 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir) ...@@ -618,6 +618,7 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir)
* sole user of this dentry. Too tricky... Just unhash for * sole user of this dentry. Too tricky... Just unhash for
* now. * now.
*/ */
if (!err)
d_drop(dentry); d_drop(dentry);
inode_unlock(dir); inode_unlock(dir);
...@@ -903,6 +904,13 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, ...@@ -903,6 +904,13 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old,
if (!overwrite && new_is_dir && !old_opaque && new_opaque) if (!overwrite && new_is_dir && !old_opaque && new_opaque)
ovl_remove_opaque(newdentry); ovl_remove_opaque(newdentry);
/*
* Old dentry now lives in different location. Dentries in
* lowerstack are stale. We cannot drop them here because
* access to them is lockless. This could be only pure upper
* or opaque directory - numlower is zero. Or upper non-dir
* entry - its pureness is tracked by flag opaque.
*/
if (old_opaque != new_opaque) { if (old_opaque != new_opaque) {
ovl_dentry_set_opaque(old, new_opaque); ovl_dentry_set_opaque(old, new_opaque);
if (!overwrite) if (!overwrite)
......
...@@ -65,6 +65,8 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -65,6 +65,8 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
inode_lock(upperdentry->d_inode); inode_lock(upperdentry->d_inode);
err = notify_change(upperdentry, attr, NULL); err = notify_change(upperdentry, attr, NULL);
if (!err)
ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
inode_unlock(upperdentry->d_inode); inode_unlock(upperdentry->d_inode);
} }
ovl_drop_write(dentry); ovl_drop_write(dentry);
......
...@@ -76,12 +76,14 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry) ...@@ -76,12 +76,14 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
if (oe->__upperdentry) { if (oe->__upperdentry) {
type = __OVL_PATH_UPPER; type = __OVL_PATH_UPPER;
if (oe->numlower) { /*
if (S_ISDIR(dentry->d_inode->i_mode)) * Non-dir dentry can hold lower dentry from previous
* location. Its purity depends only on opaque flag.
*/
if (oe->numlower && S_ISDIR(dentry->d_inode->i_mode))
type |= __OVL_PATH_MERGE; type |= __OVL_PATH_MERGE;
} else if (!oe->opaque) { else if (!oe->opaque)
type |= __OVL_PATH_PURE; type |= __OVL_PATH_PURE;
}
} else { } else {
if (oe->numlower > 1) if (oe->numlower > 1)
type |= __OVL_PATH_MERGE; type |= __OVL_PATH_MERGE;
...@@ -341,6 +343,7 @@ static const struct dentry_operations ovl_dentry_operations = { ...@@ -341,6 +343,7 @@ static const struct dentry_operations ovl_dentry_operations = {
static const struct dentry_operations ovl_reval_dentry_operations = { static const struct dentry_operations ovl_reval_dentry_operations = {
.d_release = ovl_dentry_release, .d_release = ovl_dentry_release,
.d_select_inode = ovl_d_select_inode,
.d_revalidate = ovl_dentry_revalidate, .d_revalidate = ovl_dentry_revalidate,
.d_weak_revalidate = ovl_dentry_weak_revalidate, .d_weak_revalidate = ovl_dentry_weak_revalidate,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment