fs: port ->symlink() to pass mnt_idmap

Convert to struct mnt_idmap.

Last cycle we merged the necessary infrastructure in
256c8aed2b ("fs: introduce dedicated idmap type for mounts").
This is just the conversion to struct mnt_idmap.

Currently we still pass around the plain namespace that was attached to a
mount. This is in general pretty convenient but it makes it easy to
conflate namespaces that are relevant on the filesystem with namespaces
that are relevent on the mount level. Especially for non-vfs developers
without detailed knowledge in this area this can be a potential source for
bugs.

Once the conversion to struct mnt_idmap is done all helpers down to the
really low-level helpers will take a struct mnt_idmap argument instead of
two namespace arguments. This way it becomes impossible to conflate the two
eliminating the possibility of any bugs. All of the vfs and all filesystems
only operate on struct mnt_idmap.

Acked-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
This commit is contained in:
Christian Brauner 2023-01-13 12:49:14 +01:00 committed by Christian Brauner (Microsoft)
parent 6c960e68aa
commit 7a77db9551
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
48 changed files with 60 additions and 54 deletions

View File

@ -60,7 +60,7 @@ prototypes::
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 (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,umode_t);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);

View File

@ -425,7 +425,7 @@ As of kernel 2.6.22, the following members are defined:
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 user_namespace *, struct inode *,struct dentry *,const char *);
int (*symlink) (struct mnt_idmap *, 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 user_namespace *, struct inode *,struct dentry *,umode_t,dev_t);

View File

@ -1300,7 +1300,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
/**
* v9fs_vfs_symlink - helper function to create symlinks
* @mnt_userns: The user namespace of the mount
* @idmap: idmap of the mount
* @dir: directory inode containing symlink
* @dentry: dentry for symlink
* @symname: symlink data
@ -1310,7 +1310,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
*/
static int
v9fs_vfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
v9fs_vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n",

View File

@ -688,7 +688,7 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
}
static int
v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int err;

View File

@ -174,7 +174,7 @@ extern int affs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
extern int affs_rmdir(struct inode *dir, struct dentry *dentry);
extern int affs_link(struct dentry *olddentry, struct inode *dir,
struct dentry *dentry);
extern int affs_symlink(struct user_namespace *mnt_userns,
extern int affs_symlink(struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry,
const char *symname);
extern int affs_rename2(struct user_namespace *mnt_userns,

View File

@ -313,7 +313,7 @@ affs_rmdir(struct inode *dir, struct dentry *dentry)
}
int
affs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
affs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct super_block *sb = dir->i_sb;

View File

@ -36,7 +36,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry);
static int afs_unlink(struct inode *dir, struct dentry *dentry);
static int afs_link(struct dentry *from, struct inode *dir,
struct dentry *dentry);
static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int afs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *content);
static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
@ -1760,7 +1760,7 @@ static const struct afs_operation_ops afs_symlink_operation = {
/*
* create a symlink in an AFS filesystem
*/
static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int afs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *content)
{
struct afs_operation *op;

View File

@ -11,7 +11,7 @@
#include "autofs_i.h"
static int autofs_dir_permission(struct user_namespace *, struct inode *, int);
static int autofs_dir_symlink(struct user_namespace *, struct inode *,
static int autofs_dir_symlink(struct mnt_idmap *, struct inode *,
struct dentry *, const char *);
static int autofs_dir_unlink(struct inode *, struct dentry *);
static int autofs_dir_rmdir(struct inode *, struct dentry *);
@ -563,7 +563,7 @@ static int autofs_dir_permission(struct user_namespace *mnt_userns,
return generic_permission(mnt_userns, inode, mask);
}
static int autofs_dir_symlink(struct user_namespace *mnt_userns,
static int autofs_dir_symlink(struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry,
const char *symname)
{

View File

@ -51,7 +51,7 @@ static int bad_inode_unlink(struct inode *dir, struct dentry *dentry)
return -EIO;
}
static int bad_inode_symlink(struct user_namespace *mnt_userns,
static int bad_inode_symlink(struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry,
const char *symname)
{

View File

@ -9758,9 +9758,10 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr,
return ret;
}
static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(dir)->root;

View File

@ -912,7 +912,7 @@ static int ceph_create(struct mnt_idmap *idmap, struct inode *dir,
return ceph_mknod(mnt_userns, dir, dentry, mode, 0);
}
static int ceph_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int ceph_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *dest)
{
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);

View File

@ -124,7 +124,7 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
/* Functions related to symlinks */
extern const char *cifs_get_link(struct dentry *, struct inode *,
struct delayed_call *);
extern int cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
extern int cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
struct dentry *direntry, const char *symname);
#ifdef CONFIG_CIFS_XATTR

View File

@ -568,7 +568,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
}
int
cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
struct dentry *direntry, const char *symname)
{
int rc = -EOPNOTSUPP;

View File

@ -228,7 +228,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
}
static int coda_symlink(struct user_namespace *mnt_userns,
static int coda_symlink(struct mnt_idmap *idmap,
struct inode *dir_inode, struct dentry *de,
const char *symname)
{

View File

@ -91,7 +91,7 @@ extern const struct inode_operations configfs_root_inode_operations;
extern const struct inode_operations configfs_symlink_inode_operations;
extern const struct dentry_operations configfs_dentry_ops;
extern int configfs_symlink(struct user_namespace *mnt_userns,
extern int configfs_symlink(struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry,
const char *symname);
extern int configfs_unlink(struct inode *dir, struct dentry *dentry);

View File

@ -137,7 +137,7 @@ static int get_target(const char *symname, struct path *path,
}
int configfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int ret;

View File

@ -456,7 +456,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
return ecryptfs_do_unlink(dir, dentry, d_inode(dentry));
}
static int ecryptfs_symlink(struct user_namespace *mnt_userns,
static int ecryptfs_symlink(struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry,
const char *symname)
{

View File

@ -154,7 +154,7 @@ static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir,
return err;
}
static int ext2_symlink (struct user_namespace * mnt_userns, struct inode * dir,
static int ext2_symlink (struct mnt_idmap * idmap, struct inode * dir,
struct dentry * dentry, const char * symname)
{
struct super_block * sb = dir->i_sb;

View File

@ -3340,9 +3340,10 @@ static int ext4_init_symlink_block(handle_t *handle, struct inode *inode,
return err;
}
static int ext4_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int ext4_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
handle_t *handle;
struct inode *inode;
int err, len = strlen(symname);

View File

@ -660,9 +660,10 @@ static const char *f2fs_get_link(struct dentry *dentry,
return link;
}
static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int f2fs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
struct inode *inode;
size_t len = strlen(symname);

View File

@ -841,7 +841,7 @@ static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
return create_new_entry(fm, &args, dir, entry, S_IFDIR);
}
static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *entry, const char *link)
{
struct fuse_mount *fm = get_fuse_mount(dir);

View File

@ -1207,7 +1207,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
/**
* gfs2_symlink - Create a symlink
* @mnt_userns: User namespace of the mount the inode was found from
* @idmap: idmap of the mount the inode was found from
* @dir: The directory to create the symlink in
* @dentry: The dentry to put the symlink in
* @symname: The thing which the link points to
@ -1215,7 +1215,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
* Returns: errno
*/
static int gfs2_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int gfs2_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
unsigned int size;

View File

@ -434,7 +434,7 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
return res;
}
static int hfsplus_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int hfsplus_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb);

View File

@ -658,7 +658,7 @@ static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
return err;
}
static int hostfs_symlink(struct user_namespace *mnt_userns, struct inode *ino,
static int hostfs_symlink(struct mnt_idmap *idmap, struct inode *ino,
struct dentry *dentry, const char *to)
{
char *file;

View File

@ -292,7 +292,7 @@ static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
return err;
}
static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int hpfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symlink)
{
const unsigned char *name = dentry->d_name.name;

View File

@ -1064,7 +1064,7 @@ static int hugetlbfs_tmpfile(struct user_namespace *mnt_userns,
return finish_open_simple(file, 0);
}
static int hugetlbfs_symlink(struct user_namespace *mnt_userns,
static int hugetlbfs_symlink(struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry,
const char *symname)
{

View File

@ -30,7 +30,7 @@ static struct dentry *jffs2_lookup (struct inode *,struct dentry *,
unsigned int);
static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
static int jffs2_unlink (struct inode *,struct dentry *);
static int jffs2_symlink (struct user_namespace *, struct inode *,
static int jffs2_symlink (struct mnt_idmap *, struct inode *,
struct dentry *, const char *);
static int jffs2_mkdir (struct user_namespace *, struct inode *,struct dentry *,
umode_t);
@ -279,7 +279,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
/***********************************************************************/
static int jffs2_symlink (struct user_namespace *mnt_userns, struct inode *dir_i,
static int jffs2_symlink (struct mnt_idmap *idmap, struct inode *dir_i,
struct dentry *dentry, const char *target)
{
struct jffs2_inode_info *f, *dir_f;

View File

@ -869,7 +869,7 @@ static int jfs_link(struct dentry *old_dentry,
* an intermediate result whose length exceeds PATH_MAX [XPG4.2]
*/
static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip,
static int jfs_symlink(struct mnt_idmap *idmap, struct inode *dip,
struct dentry *dentry, const char *name)
{
int rc;

View File

@ -71,7 +71,7 @@ static int minix_create(struct mnt_idmap *idmap, struct inode *dir,
return minix_mknod(&init_user_ns, dir, dentry, mode, 0);
}
static int minix_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int minix_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int err = -ENAMETOOLONG;

View File

@ -4394,8 +4394,9 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *oldname)
{
struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
int error = may_create(mnt_userns, dir, dentry);
int error;
error = may_create(mnt_userns, dir, dentry);
if (error)
return error;
@ -4406,7 +4407,7 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
if (error)
return error;
error = dir->i_op->symlink(mnt_userns, dir, dentry, oldname);
error = dir->i_op->symlink(idmap, dir, dentry, oldname);
if (!error)
fsnotify_create(dir, dentry);
return error;

View File

@ -2524,7 +2524,7 @@ EXPORT_SYMBOL_GPL(nfs_unlink);
* now have a new file handle and can instantiate an in-core NFS inode
* and move the raw page into its mapping.
*/
int nfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct page *page;

View File

@ -390,7 +390,7 @@ int nfs_mkdir(struct user_namespace *, struct inode *, struct dentry *,
umode_t);
int nfs_rmdir(struct inode *, struct dentry *);
int nfs_unlink(struct inode *, struct dentry *);
int nfs_symlink(struct user_namespace *, struct inode *, struct dentry *,
int nfs_symlink(struct mnt_idmap *, struct inode *, struct dentry *,
const char *);
int nfs_link(struct dentry *, struct inode *, struct dentry *);
int nfs_mknod(struct user_namespace *, struct inode *, struct dentry *, umode_t,

View File

@ -125,7 +125,7 @@ nilfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
return err;
}
static int nilfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int nilfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct nilfs_transaction_info ti;

View File

@ -184,9 +184,10 @@ static int ntfs_unlink(struct inode *dir, struct dentry *dentry)
/*
* ntfs_symlink - inode_operations::symlink
*/
static int ntfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
u32 size = strlen(symname);
struct inode *inode;

View File

@ -1784,7 +1784,7 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
return status;
}
static int ocfs2_symlink(struct user_namespace *mnt_userns,
static int ocfs2_symlink(struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
const char *symname)

View File

@ -216,7 +216,7 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
return ret;
}
static int orangefs_symlink(struct user_namespace *mnt_userns,
static int orangefs_symlink(struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
const char *symname)

View File

@ -677,7 +677,7 @@ static int ovl_mknod(struct user_namespace *mnt_userns, struct inode *dir,
return ovl_create_object(dentry, mode, rdev, NULL);
}
static int ovl_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int ovl_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *link)
{
return ovl_create_object(dentry, S_IFLNK, 0, link);

View File

@ -125,7 +125,7 @@ static int ramfs_create(struct mnt_idmap *idmap, struct inode *dir,
return ramfs_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0);
}
static int ramfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int ramfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct inode *inode;

View File

@ -1099,7 +1099,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
return retval;
}
static int reiserfs_symlink(struct user_namespace *mnt_userns,
static int reiserfs_symlink(struct mnt_idmap *idmap,
struct inode *parent_dir, struct dentry *dentry,
const char *symname)
{

View File

@ -67,7 +67,7 @@ static int sysv_create(struct mnt_idmap *idmap, struct inode *dir,
return sysv_mknod(&init_user_ns, dir, dentry, mode, 0);
}
static int sysv_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int sysv_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int err = -ENAMETOOLONG;

View File

@ -1141,7 +1141,7 @@ static int ubifs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
return err;
}
static int ubifs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int ubifs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct inode *inode;

View File

@ -881,7 +881,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
return retval;
}
static int udf_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int udf_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct inode *inode = udf_new_inode(dir, S_IFLNK | 0777);

View File

@ -106,7 +106,7 @@ static int ufs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
return err;
}
static int ufs_symlink (struct user_namespace * mnt_userns, struct inode * dir,
static int ufs_symlink (struct mnt_idmap * idmap, struct inode * dir,
struct dentry * dentry, const char * symname)
{
struct super_block * sb = dir->i_sb;

View File

@ -430,7 +430,7 @@ static int vboxsf_dir_rename(struct user_namespace *mnt_userns,
return err;
}
static int vboxsf_dir_symlink(struct user_namespace *mnt_userns,
static int vboxsf_dir_symlink(struct mnt_idmap *idmap,
struct inode *parent, struct dentry *dentry,
const char *symname)
{

View File

@ -401,11 +401,12 @@ xfs_vn_unlink(
STATIC int
xfs_vn_symlink(
struct user_namespace *mnt_userns,
struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
const char *symname)
{
struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
struct inode *inode;
struct xfs_inode *cip = NULL;
struct xfs_name name;

View File

@ -2143,7 +2143,7 @@ struct inode_operations {
umode_t, bool);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct user_namespace *, struct inode *,struct dentry *,
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,
const char *);
int (*mkdir) (struct user_namespace *, struct inode *,struct dentry *,
umode_t);

View File

@ -382,7 +382,7 @@ bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags)
return simple_lookup(dir, dentry, flags);
}
static int bpf_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int bpf_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *target)
{
char *link = kstrdup(target, GFP_USER | __GFP_NOWARN);

View File

@ -3124,7 +3124,7 @@ static int shmem_rename2(struct user_namespace *mnt_userns,
return 0;
}
static int shmem_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static int shmem_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int error;