Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "A couple of fixes (-stable fodder) + dead code removal after the overlayfs fix. I agree that it's better to separate from the fix part to make backporting easier, but IMO it's not worth delaying said dead code removal until the next window" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: Don't reset ->total_link_count on nested calls of vfs_path_lookup() ovl: get rid of the dead code left from broken (and disabled) optimizations ovl: fix permission checking for setattr
This commit is contained in:
commit
d8cd93ea67
|
@ -1996,7 +1996,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
|
||||||
nd->last_type = LAST_ROOT; /* if there are only slashes... */
|
nd->last_type = LAST_ROOT; /* if there are only slashes... */
|
||||||
nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT;
|
nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT;
|
||||||
nd->depth = 0;
|
nd->depth = 0;
|
||||||
nd->total_link_count = 0;
|
|
||||||
if (flags & LOOKUP_ROOT) {
|
if (flags & LOOKUP_ROOT) {
|
||||||
struct dentry *root = nd->root.dentry;
|
struct dentry *root = nd->root.dentry;
|
||||||
struct inode *inode = root->d_inode;
|
struct inode *inode = root->d_inode;
|
||||||
|
|
|
@ -195,8 +195,7 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
|
||||||
|
|
||||||
static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
||||||
struct dentry *dentry, struct path *lowerpath,
|
struct dentry *dentry, struct path *lowerpath,
|
||||||
struct kstat *stat, struct iattr *attr,
|
struct kstat *stat, const char *link)
|
||||||
const char *link)
|
|
||||||
{
|
{
|
||||||
struct inode *wdir = workdir->d_inode;
|
struct inode *wdir = workdir->d_inode;
|
||||||
struct inode *udir = upperdir->d_inode;
|
struct inode *udir = upperdir->d_inode;
|
||||||
|
@ -240,8 +239,6 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
||||||
|
|
||||||
mutex_lock(&newdentry->d_inode->i_mutex);
|
mutex_lock(&newdentry->d_inode->i_mutex);
|
||||||
err = ovl_set_attr(newdentry, stat);
|
err = ovl_set_attr(newdentry, stat);
|
||||||
if (!err && attr)
|
|
||||||
err = notify_change(newdentry, attr, NULL);
|
|
||||||
mutex_unlock(&newdentry->d_inode->i_mutex);
|
mutex_unlock(&newdentry->d_inode->i_mutex);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_cleanup;
|
goto out_cleanup;
|
||||||
|
@ -286,8 +283,7 @@ out_cleanup:
|
||||||
* that point the file will have already been copied up anyway.
|
* that point the file will have already been copied up anyway.
|
||||||
*/
|
*/
|
||||||
int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
|
int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
|
||||||
struct path *lowerpath, struct kstat *stat,
|
struct path *lowerpath, struct kstat *stat)
|
||||||
struct iattr *attr)
|
|
||||||
{
|
{
|
||||||
struct dentry *workdir = ovl_workdir(dentry);
|
struct dentry *workdir = ovl_workdir(dentry);
|
||||||
int err;
|
int err;
|
||||||
|
@ -345,26 +341,19 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
upperdentry = ovl_dentry_upper(dentry);
|
upperdentry = ovl_dentry_upper(dentry);
|
||||||
if (upperdentry) {
|
if (upperdentry) {
|
||||||
unlock_rename(workdir, upperdir);
|
/* Raced with another copy-up? Nothing to do, then... */
|
||||||
err = 0;
|
err = 0;
|
||||||
/* Raced with another copy-up? Do the setattr here */
|
goto out_unlock;
|
||||||
if (attr) {
|
|
||||||
mutex_lock(&upperdentry->d_inode->i_mutex);
|
|
||||||
err = notify_change(upperdentry, attr, NULL);
|
|
||||||
mutex_unlock(&upperdentry->d_inode->i_mutex);
|
|
||||||
}
|
|
||||||
goto out_put_cred;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ovl_copy_up_locked(workdir, upperdir, dentry, lowerpath,
|
err = ovl_copy_up_locked(workdir, upperdir, dentry, lowerpath,
|
||||||
stat, attr, link);
|
stat, link);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
/* Restore timestamps on parent (best effort) */
|
/* Restore timestamps on parent (best effort) */
|
||||||
ovl_set_timestamps(upperdir, &pstat);
|
ovl_set_timestamps(upperdir, &pstat);
|
||||||
}
|
}
|
||||||
out_unlock:
|
out_unlock:
|
||||||
unlock_rename(workdir, upperdir);
|
unlock_rename(workdir, upperdir);
|
||||||
out_put_cred:
|
|
||||||
revert_creds(old_cred);
|
revert_creds(old_cred);
|
||||||
put_cred(override_cred);
|
put_cred(override_cred);
|
||||||
|
|
||||||
|
@ -406,7 +395,7 @@ int ovl_copy_up(struct dentry *dentry)
|
||||||
ovl_path_lower(next, &lowerpath);
|
ovl_path_lower(next, &lowerpath);
|
||||||
err = vfs_getattr(&lowerpath, &stat);
|
err = vfs_getattr(&lowerpath, &stat);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = ovl_copy_up_one(parent, next, &lowerpath, &stat, NULL);
|
err = ovl_copy_up_one(parent, next, &lowerpath, &stat);
|
||||||
|
|
||||||
dput(parent);
|
dput(parent);
|
||||||
dput(next);
|
dput(next);
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
#include "overlayfs.h"
|
#include "overlayfs.h"
|
||||||
|
|
||||||
static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
|
static int ovl_copy_up_truncate(struct dentry *dentry)
|
||||||
bool no_data)
|
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct dentry *parent;
|
struct dentry *parent;
|
||||||
|
@ -30,10 +29,8 @@ static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
|
||||||
if (err)
|
if (err)
|
||||||
goto out_dput_parent;
|
goto out_dput_parent;
|
||||||
|
|
||||||
if (no_data)
|
stat.size = 0;
|
||||||
stat.size = 0;
|
err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
|
||||||
|
|
||||||
err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat, attr);
|
|
||||||
|
|
||||||
out_dput_parent:
|
out_dput_parent:
|
||||||
dput(parent);
|
dput(parent);
|
||||||
|
@ -49,13 +46,13 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
upperdentry = ovl_dentry_upper(dentry);
|
err = ovl_copy_up(dentry);
|
||||||
if (upperdentry) {
|
if (!err) {
|
||||||
|
upperdentry = ovl_dentry_upper(dentry);
|
||||||
|
|
||||||
mutex_lock(&upperdentry->d_inode->i_mutex);
|
mutex_lock(&upperdentry->d_inode->i_mutex);
|
||||||
err = notify_change(upperdentry, attr, NULL);
|
err = notify_change(upperdentry, attr, NULL);
|
||||||
mutex_unlock(&upperdentry->d_inode->i_mutex);
|
mutex_unlock(&upperdentry->d_inode->i_mutex);
|
||||||
} else {
|
|
||||||
err = ovl_copy_up_last(dentry, attr, false);
|
|
||||||
}
|
}
|
||||||
ovl_drop_write(dentry);
|
ovl_drop_write(dentry);
|
||||||
out:
|
out:
|
||||||
|
@ -353,7 +350,7 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
if (file_flags & O_TRUNC)
|
if (file_flags & O_TRUNC)
|
||||||
err = ovl_copy_up_last(dentry, NULL, true);
|
err = ovl_copy_up_truncate(dentry);
|
||||||
else
|
else
|
||||||
err = ovl_copy_up(dentry);
|
err = ovl_copy_up(dentry);
|
||||||
ovl_drop_write(dentry);
|
ovl_drop_write(dentry);
|
||||||
|
|
|
@ -194,7 +194,6 @@ void ovl_cleanup(struct inode *dir, struct dentry *dentry);
|
||||||
/* copy_up.c */
|
/* copy_up.c */
|
||||||
int ovl_copy_up(struct dentry *dentry);
|
int ovl_copy_up(struct dentry *dentry);
|
||||||
int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
|
int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
|
||||||
struct path *lowerpath, struct kstat *stat,
|
struct path *lowerpath, struct kstat *stat);
|
||||||
struct iattr *attr);
|
|
||||||
int ovl_copy_xattr(struct dentry *old, struct dentry *new);
|
int ovl_copy_xattr(struct dentry *old, struct dentry *new);
|
||||||
int ovl_set_attr(struct dentry *upper, struct kstat *stat);
|
int ovl_set_attr(struct dentry *upper, struct kstat *stat);
|
||||||
|
|
Loading…
Reference in New Issue