Unverified Commit 549c7297 authored by Christian Brauner's avatar Christian Brauner
Browse files

fs: make helpers idmap mount aware

Extend some inode methods with an additional user namespace argument. A
filesystem that is aware of idmapped mounts will receive the user
namespace the mount has been marked with. This can be used for
additional permission checking and also to enable filesystems to
translate between uids and gids if they need to. We have implemented all
relevant helpers in earlier patches.

As requested we simply extend the exisiting inode method instead of
introducing new ones. This is a little more code churn but it's mostly
mechanical and doesnt't leave us with additional inode methods.

Link: https://lore.kernel.org/r/20210121131959.646623-25-christian.brauner@ubuntu.com


Cc: Christoph Hellwig <hch@lst.de>
Cc: David Howells <dhowells@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 1ab29965
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -415,28 +415,29 @@ As of kernel 2.6.22, the following members are defined:
.. code-block:: c

	struct inode_operations {
		int (*create) (struct inode *,struct dentry *, umode_t, bool);
		int (*create) (struct user_namespace *, struct inode *,struct dentry *, umode_t, bool);
		struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
		int (*link) (struct dentry *,struct inode *,struct dentry *);
		int (*unlink) (struct inode *,struct dentry *);
		int (*symlink) (struct inode *,struct dentry *,const char *);
		int (*mkdir) (struct inode *,struct dentry *,umode_t);
		int (*symlink) (struct user_namespace *, struct inode *,struct dentry *,const char *);
		int (*mkdir) (struct user_namespace *, struct inode *,struct dentry *,umode_t);
		int (*rmdir) (struct inode *,struct dentry *);
		int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
		int (*rename) (struct inode *, struct dentry *,
		int (*mknod) (struct user_namespace *, struct inode *,struct dentry *,umode_t,dev_t);
		int (*rename) (struct user_namespace *, struct inode *, struct dentry *,
			       struct inode *, struct dentry *, unsigned int);
		int (*readlink) (struct dentry *, char __user *,int);
		const char *(*get_link) (struct dentry *, struct inode *,
					 struct delayed_call *);
		int (*permission) (struct inode *, int);
		int (*permission) (struct user_namespace *, struct inode *, int);
		int (*get_acl)(struct inode *, int);
		int (*setattr) (struct dentry *, struct iattr *);
		int (*getattr) (const struct path *, struct kstat *, u32, unsigned int);
		int (*setattr) (struct user_namespace *, struct dentry *, struct iattr *);
		int (*getattr) (struct user_namespace *, const struct path *, struct kstat *, u32, unsigned int);
		ssize_t (*listxattr) (struct dentry *, char *, size_t);
		void (*update_time)(struct inode *, struct timespec *, int);
		int (*atomic_open)(struct inode *, struct dentry *, struct file *,
				   unsigned open_flag, umode_t create_mode);
		int (*tmpfile) (struct inode *, struct dentry *, umode_t);
		int (*tmpfile) (struct user_namespace *, struct inode *, struct dentry *, umode_t);
	        int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int);
	};

Again, all methods are called without any locks being held, unless
+2 −1
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@ spufs_new_inode(struct super_block *sb, umode_t mode)
}

static int
spufs_setattr(struct dentry *dentry, struct iattr *attr)
spufs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
	      struct iattr *attr)
{
	struct inode *inode = d_inode(dentry);

+4 −2
Original line number Diff line number Diff line
@@ -355,7 +355,8 @@ static inline bool is_binderfs_control_device(const struct dentry *dentry)
	return info->control_dentry == dentry;
}

static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry,
static int binderfs_rename(struct user_namespace *mnt_userns,
			   struct inode *old_dir, struct dentry *old_dentry,
			   struct inode *new_dir, struct dentry *new_dentry,
			   unsigned int flags)
{
@@ -363,7 +364,8 @@ static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	    is_binderfs_control_device(new_dentry))
		return -EPERM;

	return simple_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
	return simple_rename(&init_user_ns, old_dir, old_dentry, new_dir,
			     new_dentry, flags);
}

static int binderfs_unlink(struct inode *dir, struct dentry *dentry)
+2 −2
Original line number Diff line number Diff line
@@ -280,7 +280,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
			struct iattr iattr = { 0 };
			struct posix_acl *old_acl = acl;

			retval = posix_acl_update_mode(mnt_userns, inode,
			retval = posix_acl_update_mode(&init_user_ns, inode,
						       &iattr.ia_mode, &acl);
			if (retval)
				goto err_out;
@@ -299,7 +299,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
			 * What is the following setxattr update the
			 * mode ?
			 */
			v9fs_vfs_setattr_dotl(dentry, &iattr);
			v9fs_vfs_setattr_dotl(&init_user_ns, dentry, &iattr);
		}
		break;
	case ACL_TYPE_DEFAULT:
+2 −1
Original line number Diff line number Diff line
@@ -135,7 +135,8 @@ extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
			unsigned int flags);
extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
extern int v9fs_vfs_rename(struct user_namespace *mnt_userns,
			   struct inode *old_dir, struct dentry *old_dentry,
			   struct inode *new_dir, struct dentry *new_dentry,
			   unsigned int flags);
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
Loading