Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8cd93ea authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents fb7b26e4 2788cc47
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -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;
+6 −17
Original line number Original line Diff line number Diff line
@@ -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 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
 * 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);
+8 −11
Original line number Original line Diff line number Diff line
@@ -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;


	err = ovl_copy_up(dentry);
	if (!err) {
		upperdentry = ovl_dentry_upper(dentry);
		upperdentry = ovl_dentry_upper(dentry);
	if (upperdentry) {

		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);
+1 −2
Original line number Original line Diff line number Diff line
@@ -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);