bcachefs: support idmap mounts
We enable idmapped mounts for bcachefs. Here, we just pass down the user_namespace argument from the VFS methods to the relevant helpers. The idmap test in bcachefs is as following: ``` 1. losetup /dev/loop1 bcachefs.img 2. ./bcachefs format /dev/loop1 3. mount -t bcachefs /dev/loop1 /mnt/bcachefs/ 4. ./mount-idmapped --map-mount b:0:1000:1 /mnt/bcachefs /mnt/idmapped1/ ll /mnt/bcachefs total 2 drwx------. 2 root root 0 Jun 14 14:10 lost+found -rw-r--r--. 1 root root 1945 Jun 14 14:12 profile ll /mnt/idmapped1/ total 2 drwx------. 2 1000 1000 0 Jun 14 14:10 lost+found -rw-r--r--. 1 1000 1000 1945 Jun 14 14:12 profile Signed-off-by: Hongbo Li <lihongbo22@huawei.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
86e92eeeb2
commit
c24adfa0df
@ -385,6 +385,8 @@ __bch2_create(struct mnt_idmap *idmap,
|
||||
subvol_inum inum;
|
||||
struct bch_subvolume subvol;
|
||||
u64 journal_seq = 0;
|
||||
kuid_t kuid;
|
||||
kgid_t kgid;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@ -411,13 +413,15 @@ __bch2_create(struct mnt_idmap *idmap,
|
||||
retry:
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
kuid = mapped_fsuid(idmap, i_user_ns(&dir->v));
|
||||
kgid = mapped_fsgid(idmap, i_user_ns(&dir->v));
|
||||
ret = bch2_subvol_is_ro_trans(trans, dir->ei_inum.subvol) ?:
|
||||
bch2_create_trans(trans,
|
||||
inode_inum(dir), &dir_u, &inode_u,
|
||||
!(flags & BCH_CREATE_TMPFILE)
|
||||
? &dentry->d_name : NULL,
|
||||
from_kuid(i_user_ns(&dir->v), current_fsuid()),
|
||||
from_kgid(i_user_ns(&dir->v), current_fsgid()),
|
||||
from_kuid(i_user_ns(&dir->v), kuid),
|
||||
from_kgid(i_user_ns(&dir->v), kgid),
|
||||
mode, rdev,
|
||||
default_acl, acl, snapshot_src, flags) ?:
|
||||
bch2_quota_acct(c, bch_qid(&inode_u), Q_INO, 1,
|
||||
@ -840,11 +844,17 @@ static void bch2_setattr_copy(struct mnt_idmap *idmap,
|
||||
{
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
kuid_t kuid;
|
||||
kgid_t kgid;
|
||||
|
||||
if (ia_valid & ATTR_UID)
|
||||
bi->bi_uid = from_kuid(i_user_ns(&inode->v), attr->ia_uid);
|
||||
if (ia_valid & ATTR_GID)
|
||||
bi->bi_gid = from_kgid(i_user_ns(&inode->v), attr->ia_gid);
|
||||
if (ia_valid & ATTR_UID) {
|
||||
kuid = from_vfsuid(idmap, i_user_ns(&inode->v), attr->ia_vfsuid);
|
||||
bi->bi_uid = from_kuid(i_user_ns(&inode->v), kuid);
|
||||
}
|
||||
if (ia_valid & ATTR_GID) {
|
||||
kgid = from_vfsgid(idmap, i_user_ns(&inode->v), attr->ia_vfsgid);
|
||||
bi->bi_gid = from_kgid(i_user_ns(&inode->v), kgid);
|
||||
}
|
||||
|
||||
if (ia_valid & ATTR_SIZE)
|
||||
bi->bi_size = attr->ia_size;
|
||||
@ -859,11 +869,11 @@ static void bch2_setattr_copy(struct mnt_idmap *idmap,
|
||||
if (ia_valid & ATTR_MODE) {
|
||||
umode_t mode = attr->ia_mode;
|
||||
kgid_t gid = ia_valid & ATTR_GID
|
||||
? attr->ia_gid
|
||||
? kgid
|
||||
: inode->v.i_gid;
|
||||
|
||||
if (!in_group_p(gid) &&
|
||||
!capable_wrt_inode_uidgid(idmap, &inode->v, CAP_FSETID))
|
||||
if (!in_group_or_capable(idmap, &inode->v,
|
||||
make_vfsgid(idmap, i_user_ns(&inode->v), gid)))
|
||||
mode &= ~S_ISGID;
|
||||
bi->bi_mode = mode;
|
||||
}
|
||||
@ -879,17 +889,23 @@ int bch2_setattr_nonsize(struct mnt_idmap *idmap,
|
||||
struct btree_iter inode_iter = { NULL };
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct posix_acl *acl = NULL;
|
||||
kuid_t kuid;
|
||||
kgid_t kgid;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&inode->ei_update_lock);
|
||||
|
||||
qid = inode->ei_qid;
|
||||
|
||||
if (attr->ia_valid & ATTR_UID)
|
||||
qid.q[QTYP_USR] = from_kuid(i_user_ns(&inode->v), attr->ia_uid);
|
||||
if (attr->ia_valid & ATTR_UID) {
|
||||
kuid = from_vfsuid(idmap, i_user_ns(&inode->v), attr->ia_vfsuid);
|
||||
qid.q[QTYP_USR] = from_kuid(i_user_ns(&inode->v), kuid);
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_GID)
|
||||
qid.q[QTYP_GRP] = from_kgid(i_user_ns(&inode->v), attr->ia_gid);
|
||||
if (attr->ia_valid & ATTR_GID) {
|
||||
kgid = from_vfsgid(idmap, i_user_ns(&inode->v), attr->ia_vfsgid);
|
||||
qid.q[QTYP_GRP] = from_kgid(i_user_ns(&inode->v), kgid);
|
||||
}
|
||||
|
||||
ret = bch2_fs_quota_transfer(c, inode, qid, ~0,
|
||||
KEY_TYPE_QUOTA_PREALLOC);
|
||||
@ -945,13 +961,15 @@ static int bch2_getattr(struct mnt_idmap *idmap,
|
||||
{
|
||||
struct bch_inode_info *inode = to_bch_ei(d_inode(path->dentry));
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, &inode->v);
|
||||
vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, &inode->v);
|
||||
|
||||
stat->dev = inode->v.i_sb->s_dev;
|
||||
stat->ino = inode->v.i_ino;
|
||||
stat->mode = inode->v.i_mode;
|
||||
stat->nlink = inode->v.i_nlink;
|
||||
stat->uid = inode->v.i_uid;
|
||||
stat->gid = inode->v.i_gid;
|
||||
stat->uid = vfsuid_into_kuid(vfsuid);
|
||||
stat->gid = vfsgid_into_kgid(vfsgid);
|
||||
stat->rdev = inode->v.i_rdev;
|
||||
stat->size = i_size_read(&inode->v);
|
||||
stat->atime = inode_get_atime(&inode->v);
|
||||
@ -2225,7 +2243,7 @@ static struct file_system_type bcache_fs_type = {
|
||||
.name = "bcachefs",
|
||||
.init_fs_context = bch2_init_fs_context,
|
||||
.kill_sb = bch2_kill_sb,
|
||||
.fs_flags = FS_REQUIRES_DEV,
|
||||
.fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
|
||||
};
|
||||
|
||||
MODULE_ALIAS_FS("bcachefs");
|
||||
|
Loading…
Reference in New Issue
Block a user