diff mbox series

[02/24] namei: handle mappings in lookup_one_len_unlocked()

Message ID 20210713111344.1149376-3-brauner@kernel.org (mailing list archive)
State New, archived
Headers show
Series btrfs: support idmapped mounts | expand

Commit Message

Christian Brauner July 13, 2021, 11:13 a.m. UTC
From: Christian Brauner <christian.brauner@ubuntu.com>

Various filesystems use the lookup_one_len_unlocked() helper to lookup a single
path component relative to a well-known starting point. Allow such filesystems
to support idmapped mounts by enabling lookup_one_len_unlocked() to take the
idmap into account when calling inode_permission().

Cc: Christoph Hellwig <hch@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
 fs/ecryptfs/inode.c   | 3 ++-
 fs/exportfs/expfs.c   | 3 ++-
 fs/namei.c            | 9 +++++----
 fs/overlayfs/namei.c  | 3 ++-
 include/linux/namei.h | 3 ++-
 5 files changed, 13 insertions(+), 8 deletions(-)

Comments

Al Viro July 13, 2021, 1:34 p.m. UTC | #1
On Tue, Jul 13, 2021 at 01:13:22PM +0200, Christian Brauner wrote:
> From: Christian Brauner <christian.brauner@ubuntu.com>
> 
> Various filesystems use the lookup_one_len_unlocked() helper to lookup a single
> path component relative to a well-known starting point. Allow such filesystems
> to support idmapped mounts by enabling lookup_one_len_unlocked() to take the
> idmap into account when calling inode_permission().

Ditto.  The same applies to the rest of primitives you modify - if you need
a new variant, *add* *that* *variant*.
diff mbox series

Patch

diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 16d50dface59..755975a214a9 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -405,7 +405,8 @@  static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
 		name = encrypted_and_encoded_name;
 	}
 
-	lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len);
+	lower_dentry = lookup_one_len_unlocked(&init_user_ns, name,
+					       lower_dir_dentry, len);
 	if (IS_ERR(lower_dentry)) {
 		ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
 				"[%ld] on lower_dentry = [%s]\n", __func__,
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 9ba408594094..0e35efba2bc5 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -145,7 +145,8 @@  static struct dentry *reconnect_one(struct vfsmount *mnt,
 	if (err)
 		goto out_err;
 	dprintk("%s: found name: %s\n", __func__, nbuf);
-	tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf));
+	tmp = lookup_one_len_unlocked(&init_user_ns, nbuf,
+				      parent, strlen(nbuf));
 	if (IS_ERR(tmp)) {
 		dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp));
 		err = PTR_ERR(tmp);
diff --git a/fs/namei.c b/fs/namei.c
index 5a3e8188585e..53561311b492 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2679,14 +2679,15 @@  EXPORT_SYMBOL(lookup_one_len);
  * Unlike lookup_one_len, it should be called without the parent
  * i_mutex held, and will take the i_mutex itself if necessary.
  */
-struct dentry *lookup_one_len_unlocked(const char *name,
-				       struct dentry *base, int len)
+struct dentry *lookup_one_len_unlocked(struct user_namespace *mnt_userns,
+				       const char *name, struct dentry *base,
+				       int len)
 {
 	struct qstr this;
 	int err;
 	struct dentry *ret;
 
-	err = lookup_one_len_common(&init_user_ns, name, base, len, &this);
+	err = lookup_one_len_common(mnt_userns, name, base, len, &this);
 	if (err)
 		return ERR_PTR(err);
 
@@ -2708,7 +2709,7 @@  EXPORT_SYMBOL(lookup_one_len_unlocked);
 struct dentry *lookup_positive_unlocked(const char *name,
 				       struct dentry *base, int len)
 {
-	struct dentry *ret = lookup_one_len_unlocked(name, base, len);
+	struct dentry *ret = lookup_one_len_unlocked(&init_user_ns, name, base, len);
 	if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
 		dput(ret);
 		ret = ERR_PTR(-ENOENT);
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 210cd6f66e28..291985b79a6d 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -202,7 +202,8 @@  static struct dentry *ovl_lookup_positive_unlocked(const char *name,
 						   struct dentry *base, int len,
 						   bool drop_negative)
 {
-	struct dentry *ret = lookup_one_len_unlocked(name, base, len);
+	struct dentry *ret = lookup_one_len_unlocked(&init_user_ns, name,
+						     base, len);
 
 	if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
 		if (drop_negative && ret->d_lockref.count == 1) {
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 7f8b58b43075..b4073e36450a 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -67,7 +67,8 @@  extern struct dentry *kern_path_locked(const char *, struct path *);
 extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int);
 extern struct dentry *lookup_one_len(struct user_namespace *mnt_userns,
 				     const char *, struct dentry *, int);
-extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int);
+extern struct dentry *lookup_one_len_unlocked(struct user_namespace *,
+					      const char *, struct dentry *, int);
 extern struct dentry *lookup_positive_unlocked(const char *, struct dentry *, int);
 
 extern int follow_down_one(struct path *);