From: Christian Brauner <christian.brauner@ubuntu.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
Christoph Hellwig <hch@infradead.org>,
linux-fsdevel@vger.kernel.org
Cc: Lennart Poettering <lennart@poettering.net>,
Mimi Zohar <zohar@linux.ibm.com>,
James Bottomley <James.Bottomley@hansenpartnership.com>,
Andreas Dilger <adilger.kernel@dilger.ca>,
containers@lists.linux-foundation.org,
Tycho Andersen <tycho@tycho.ws>,
Miklos Szeredi <miklos@szeredi.hu>,
smbarber@chromium.org, linux-ext4@vger.kernel.org,
Mrunal Patel <mpatel@redhat.com>,
Kees Cook <keescook@chromium.org>, Arnd Bergmann <arnd@arndb.de>,
Jann Horn <jannh@google.com>,
selinux@vger.kernel.org, Josh Triplett <josh@joshtriplett.org>,
Seth Forshee <seth.forshee@canonical.com>,
Andy Lutomirski <luto@kernel.org>,
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>,
Geoffrey Thomas <geofft@ldpreload.com>,
David Howells <dhowells@redhat.com>,
John Johansen <john.johansen@canonical.com>,
Theodore Tso <tytso@mit.edu>,
Dmitry Kasatkin <dmitry.kasatkin@gmail.com>,
Stephen Smalley <stephen.smalley.work@gmail.com>,
Jonathan Corbet <corbet@lwn.net>,
linux-unionfs@vger.kernel.org,
linux-security-module@vger.kernel.org, linux-audit@redhat.com,
"Eric W. Biederman" <ebiederm@xmission.com>,
linux-api@vger.kernel.org,
Casey Schaufler <casey@schaufler-ca.com>,
Alban Crequy <alban@kinvolk.io>,
linux-integrity@vger.kernel.org, Todd Kjos <tkjos@google.com>
Subject: [PATCH 17/34] namei: introduce struct renamedata
Date: Thu, 29 Oct 2020 01:32:35 +0100 [thread overview]
Message-ID: <20201029003252.2128653-18-christian.brauner@ubuntu.com> (raw)
In-Reply-To: <20201029003252.2128653-1-christian.brauner@ubuntu.com>
In order to handle idmapped mounts we will extend the vfs rename helper
to take two new arguments in follow up patches. Since this operations already
takes a bunch of arguments add a simple struct renamedata (based on struct
nameidata) and make the current helper to use it before we extend it.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
fs/namei.c | 144 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 88 insertions(+), 56 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 76ee4d52bd5e..781f11795a22 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4221,62 +4221,24 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
}
-/**
- * vfs_rename - rename a filesystem object
- * @old_dir: parent of source
- * @old_dentry: source
- * @new_dir: parent of destination
- * @new_dentry: destination
- * @delegated_inode: returns an inode needing a delegation break
- * @flags: rename flags
- *
- * The caller must hold multiple mutexes--see lock_rename()).
- *
- * If vfs_rename discovers a delegation in need of breaking at either
- * the source or destination, it will return -EWOULDBLOCK and return a
- * reference to the inode in delegated_inode. The caller should then
- * break the delegation and retry. Because breaking a delegation may
- * take a long time, the caller should drop all locks before doing
- * so.
- *
- * Alternatively, a caller may pass NULL for delegated_inode. This may
- * be appropriate for callers that expect the underlying filesystem not
- * to be NFS exported.
- *
- * The worst of all namespace operations - renaming directory. "Perverted"
- * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
- * Problems:
- *
- * a) we can get into loop creation.
- * b) race potential - two innocent renames can create a loop together.
- * That's where 4.4 screws up. Current fix: serialization on
- * sb->s_vfs_rename_mutex. We might be more accurate, but that's another
- * story.
- * c) we have to lock _four_ objects - parents and victim (if it exists),
- * and source (if it is not a directory).
- * And that - after we got ->i_mutex on parents (until then we don't know
- * whether the target exists). Solution: try to be smart with locking
- * order for inodes. We rely on the fact that tree topology may change
- * only under ->s_vfs_rename_mutex _and_ that parent of the object we
- * move will be locked. Thus we can rank directories by the tree
- * (ancestors first) and rank all non-directories after them.
- * That works since everybody except rename does "lock parent, lookup,
- * lock child" and rename is under ->s_vfs_rename_mutex.
- * HOWEVER, it relies on the assumption that any object with ->lookup()
- * has no more than 1 dentry. If "hybrid" objects will ever appear,
- * we'd better make sure that there's no link(2) for them.
- * d) conversion from fhandle to dentry may come in the wrong moment - when
- * we are removing the target. Solution: we will have to grab ->i_mutex
- * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
- * ->i_mutex on parents, which works but leads to some truly excessive
- * locking].
- */
-int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry,
- struct inode **delegated_inode, unsigned int flags)
+struct renamedata {
+ struct inode *old_dir;
+ struct dentry *old_dentry;
+ struct inode *new_dir;
+ struct dentry *new_dentry;
+ struct inode **delegated_inode;
+ unsigned int flags;
+} __randomize_layout;
+
+static int __vfs_rename(struct renamedata *rd)
{
int error;
struct user_namespace *user_ns = &init_user_ns;
+ struct inode *old_dir = rd->old_dir, *new_dir = rd->new_dir;
+ struct dentry *old_dentry = rd->old_dentry,
+ *new_dentry = rd->new_dentry;
+ struct inode **delegated_inode = rd->delegated_inode;
+ unsigned int flags = rd->flags;
bool is_dir = d_is_dir(old_dentry);
struct inode *source = old_dentry->d_inode;
struct inode *target = new_dentry->d_inode;
@@ -4395,11 +4357,76 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
return error;
}
+
+/**
+ * vfs_rename - rename a filesystem object
+ * @old_dir: parent of source
+ * @old_dentry: source
+ * @new_dir: parent of destination
+ * @new_dentry: destination
+ * @delegated_inode: returns an inode needing a delegation break
+ * @flags: rename flags
+ *
+ * The caller must hold multiple mutexes--see lock_rename()).
+ *
+ * If vfs_rename discovers a delegation in need of breaking at either
+ * the source or destination, it will return -EWOULDBLOCK and return a
+ * reference to the inode in delegated_inode. The caller should then
+ * break the delegation and retry. Because breaking a delegation may
+ * take a long time, the caller should drop all locks before doing
+ * so.
+ *
+ * Alternatively, a caller may pass NULL for delegated_inode. This may
+ * be appropriate for callers that expect the underlying filesystem not
+ * to be NFS exported.
+ *
+ * The worst of all namespace operations - renaming directory. "Perverted"
+ * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
+ * Problems:
+ *
+ * a) we can get into loop creation.
+ * b) race potential - two innocent renames can create a loop together.
+ * That's where 4.4 screws up. Current fix: serialization on
+ * sb->s_vfs_rename_mutex. We might be more accurate, but that's another
+ * story.
+ * c) we have to lock _four_ objects - parents and victim (if it exists),
+ * and source (if it is not a directory).
+ * And that - after we got ->i_mutex on parents (until then we don't know
+ * whether the target exists). Solution: try to be smart with locking
+ * order for inodes. We rely on the fact that tree topology may change
+ * only under ->s_vfs_rename_mutex _and_ that parent of the object we
+ * move will be locked. Thus we can rank directories by the tree
+ * (ancestors first) and rank all non-directories after them.
+ * That works since everybody except rename does "lock parent, lookup,
+ * lock child" and rename is under ->s_vfs_rename_mutex.
+ * HOWEVER, it relies on the assumption that any object with ->lookup()
+ * has no more than 1 dentry. If "hybrid" objects will ever appear,
+ * we'd better make sure that there's no link(2) for them.
+ * d) conversion from fhandle to dentry may come in the wrong moment - when
+ * we are removing the target. Solution: we will have to grab ->i_mutex
+ * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
+ * ->i_mutex on parents, which works but leads to some truly excessive
+ * locking].
+ */
+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry,
+ struct inode **delegated_inode, unsigned int flags)
+{
+ struct renamedata rd = {
+ .old_dir = old_dir,
+ .new_dir = new_dir,
+ .old_dentry = old_dentry,
+ .delegated_inode = delegated_inode,
+ .flags = flags,
+ };
+ return __vfs_rename(&rd);
+}
EXPORT_SYMBOL(vfs_rename);
static int do_renameat2(int olddfd, const char __user *oldname, int newdfd,
const char __user *newname, unsigned int flags)
{
+ struct renamedata rd;
struct dentry *old_dentry, *new_dentry;
struct dentry *trap;
struct path old_path, new_path;
@@ -4505,9 +4532,14 @@ static int do_renameat2(int olddfd, const char __user *oldname, int newdfd,
&new_path, new_dentry, flags);
if (error)
goto exit5;
- error = vfs_rename(old_path.dentry->d_inode, old_dentry,
- new_path.dentry->d_inode, new_dentry,
- &delegated_inode, flags);
+
+ rd.old_dir = old_path.dentry->d_inode;
+ rd.old_dentry = old_dentry;
+ rd.new_dir = new_path.dentry->d_inode;
+ rd.new_dentry = new_dentry;
+ rd.delegated_inode = &delegated_inode;
+ rd.flags = flags;
+ error = __vfs_rename(&rd);
exit5:
dput(new_dentry);
exit4:
--
2.29.0
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
next prev parent reply other threads:[~2020-10-29 0:36 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-29 0:32 [PATCH 00/34] fs: idmapped mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 01/34] namespace: take lock_mount_hash() directly when changing flags Christian Brauner
2020-11-01 14:41 ` Christoph Hellwig
2020-11-02 13:33 ` Christian Brauner
2020-10-29 0:32 ` [PATCH 02/34] namespace: only take read lock in do_reconfigure_mnt() Christian Brauner
2020-10-29 0:32 ` [PATCH 03/34] fs: add mount_setattr() Christian Brauner
2020-11-01 14:42 ` Christoph Hellwig
2020-11-02 13:34 ` Christian Brauner
2020-10-29 0:32 ` [PATCH 04/34] tests: add mount_setattr() selftests Christian Brauner
2020-10-29 0:32 ` [PATCH 05/34] fs: introduce MOUNT_ATTR_IDMAP Christian Brauner
2020-11-01 14:45 ` Christoph Hellwig
2020-11-02 13:29 ` Christian Brauner
2020-10-29 0:32 ` [PATCH 06/34] fs: add id translation helpers Christian Brauner
2020-11-01 14:46 ` Christoph Hellwig
2020-11-02 13:25 ` Christian Brauner
2020-10-29 0:32 ` [PATCH 07/34] capability: handle idmapped mounts Christian Brauner
2020-11-01 14:48 ` Christoph Hellwig
2020-11-02 13:23 ` Christian Brauner
2020-10-29 0:32 ` [PATCH 08/34] namei: add idmapped mount aware permission helpers Christian Brauner
2020-10-29 0:32 ` [PATCH 09/34] inode: add idmapped mount aware init and " Christian Brauner
2020-10-29 0:32 ` [PATCH 10/34] attr: handle idmapped mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 11/34] acl: " Christian Brauner
2020-10-29 0:32 ` [PATCH 12/34] xattr: " Christian Brauner
2020-10-29 0:32 ` [PATCH 13/34] selftests: add idmapped mounts xattr selftest Christian Brauner
2020-10-29 0:32 ` [PATCH 14/34] commoncap: handle idmapped mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 15/34] stat: add mapped_generic_fillattr() Christian Brauner
2020-10-29 0:32 ` [PATCH 16/34] namei: handle idmapped mounts in may_*() helpers Christian Brauner
2020-10-29 0:32 ` Christian Brauner [this message]
2020-10-29 0:32 ` [PATCH 18/34] namei: prepare for idmapped mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 19/34] namei: add lookup helpers with idmapped mounts aware permission checking Christian Brauner
2020-10-29 0:32 ` [PATCH 20/34] open: handle idmapped mounts in do_truncate() Christian Brauner
2020-10-29 0:32 ` [PATCH 21/34] open: handle idmapped mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 22/34] af_unix: " Christian Brauner
2020-10-29 0:32 ` [PATCH 23/34] utimes: " Christian Brauner
2020-10-29 0:32 ` [PATCH 24/34] would_dump: " Christian Brauner
2020-10-29 0:32 ` [PATCH 25/34] exec: " Christian Brauner
2020-10-29 0:32 ` [PATCH 26/34] fs: add helpers for idmap mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 27/34] apparmor: handle idmapped mounts Christian Brauner
2020-10-29 0:32 ` [PATCH 28/34] audit: " Christian Brauner
2020-10-29 0:32 ` [PATCH 29/34] ima: " Christian Brauner
2020-10-29 0:32 ` [PATCH 30/34] ext4: support " Christian Brauner
2020-10-29 0:32 ` [PATCH 31/34] expfs: handle " Christian Brauner
2020-10-29 0:32 ` [PATCH 32/34] overlayfs: handle idmapped lower directories Christian Brauner
2020-10-30 11:10 ` Amir Goldstein
2020-10-30 11:52 ` Christian Brauner
2020-10-29 0:32 ` [PATCH 33/34] overlayfs: handle idmapped merged mounts Christian Brauner
2020-10-30 9:57 ` Amir Goldstein
2020-10-29 0:32 ` [PATCH 34/34] fat: handle idmapped mounts Christian Brauner
2020-10-29 2:27 ` [PATCH 00/34] fs: " Dave Chinner
2020-10-29 16:19 ` Christian Brauner
2020-10-29 21:06 ` Tycho Andersen
2020-10-29 7:20 ` Sargun Dhillon
2020-10-29 15:47 ` Eric W. Biederman
2020-10-29 15:51 ` Aleksa Sarai
2020-10-29 16:37 ` Eric W. Biederman
2020-10-30 2:18 ` Serge E. Hallyn
2020-10-30 15:07 ` Seth Forshee
2020-10-30 16:03 ` Serge E. Hallyn
2020-11-03 14:10 ` Alban Crequy
2020-10-29 16:05 ` Lennart Poettering
2020-10-29 16:36 ` Sargun Dhillon
2020-10-29 16:54 ` Eric W. Biederman
2020-10-29 16:12 ` Tycho Andersen
2020-10-29 16:23 ` Serge E. Hallyn
2020-10-29 16:44 ` Eric W. Biederman
2020-10-29 18:04 ` Stéphane Graber
2020-10-29 21:03 ` Tycho Andersen
2020-10-29 21:58 ` Andy Lutomirski
2020-10-30 12:01 ` Christian Brauner
2020-10-30 16:17 ` Serge E. Hallyn
2020-10-31 17:43 ` Andy Lutomirski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201029003252.2128653-18-christian.brauner@ubuntu.com \
--to=christian.brauner@ubuntu.com \
--cc=James.Bottomley@hansenpartnership.com \
--cc=adilger.kernel@dilger.ca \
--cc=alban@kinvolk.io \
--cc=arnd@arndb.de \
--cc=casey@schaufler-ca.com \
--cc=containers@lists.linux-foundation.org \
--cc=corbet@lwn.net \
--cc=dhowells@redhat.com \
--cc=dmitry.kasatkin@gmail.com \
--cc=ebiederm@xmission.com \
--cc=geofft@ldpreload.com \
--cc=hch@infradead.org \
--cc=hirofumi@mail.parknet.co.jp \
--cc=jannh@google.com \
--cc=john.johansen@canonical.com \
--cc=josh@joshtriplett.org \
--cc=keescook@chromium.org \
--cc=lennart@poettering.net \
--cc=linux-api@vger.kernel.org \
--cc=linux-audit@redhat.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=luto@kernel.org \
--cc=miklos@szeredi.hu \
--cc=mpatel@redhat.com \
--cc=selinux@vger.kernel.org \
--cc=seth.forshee@canonical.com \
--cc=smbarber@chromium.org \
--cc=stephen.smalley.work@gmail.com \
--cc=tkjos@google.com \
--cc=tycho@tycho.ws \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).