Skip to content

Commit f736d93

Browse files
Christoph HellwigChristian Brauner
authored andcommitted
xfs: support idmapped mounts
Enable idmapped mounts for xfs. This basically just means passing down the user_namespace argument from the VFS methods down to where it is passed to the relevant helpers. Note that full-filesystem bulkstat is not supported from inside idmapped mounts as it is an administrative operation that acts on the whole file system. The limitation is not applied to the bulkstat single operation that just operates on a single inode. Link: https://lore.kernel.org/r/20210121131959.646623-40-christian.brauner@ubuntu.com Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
1 parent 14f3db5 commit f736d93

14 files changed

Lines changed: 110 additions & 65 deletions

fs/xfs/xfs_acl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ xfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
253253
return error;
254254

255255
if (type == ACL_TYPE_ACCESS) {
256-
error = posix_acl_update_mode(&init_user_ns, inode, &mode,
257-
&acl);
256+
error = posix_acl_update_mode(mnt_userns, inode, &mode, &acl);
258257
if (error)
259258
return error;
260259
set_mode = true;

fs/xfs/xfs_file.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/backing-dev.h>
3030
#include <linux/mman.h>
3131
#include <linux/fadvise.h>
32+
#include <linux/mount.h>
3233

3334
static const struct vm_operations_struct xfs_file_vm_ops;
3435

@@ -994,7 +995,8 @@ xfs_file_fallocate(
994995

995996
iattr.ia_valid = ATTR_SIZE;
996997
iattr.ia_size = new_size;
997-
error = xfs_vn_setattr_size(file_dentry(file), &iattr);
998+
error = xfs_vn_setattr_size(file_mnt_user_ns(file),
999+
file_dentry(file), &iattr);
9981000
if (error)
9991001
goto out_unlock;
10001002
}

fs/xfs/xfs_inode.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ xfs_inode_inherit_flags2(
766766
*/
767767
static int
768768
xfs_init_new_inode(
769+
struct user_namespace *mnt_userns,
769770
struct xfs_trans *tp,
770771
struct xfs_inode *pip,
771772
xfs_ino_t ino,
@@ -806,7 +807,7 @@ xfs_init_new_inode(
806807
inode = VFS_I(ip);
807808
inode->i_mode = mode;
808809
set_nlink(inode, nlink);
809-
inode->i_uid = current_fsuid();
810+
inode->i_uid = fsuid_into_mnt(mnt_userns);
810811
inode->i_rdev = rdev;
811812
ip->i_d.di_projid = prid;
812813

@@ -815,7 +816,7 @@ xfs_init_new_inode(
815816
if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode))
816817
inode->i_mode |= S_ISGID;
817818
} else {
818-
inode->i_gid = current_fsgid();
819+
inode->i_gid = fsgid_into_mnt(mnt_userns);
819820
}
820821

821822
/*
@@ -824,7 +825,8 @@ xfs_init_new_inode(
824825
* (and only if the irix_sgid_inherit compatibility variable is set).
825826
*/
826827
if (irix_sgid_inherit &&
827-
(inode->i_mode & S_ISGID) && !in_group_p(inode->i_gid))
828+
(inode->i_mode & S_ISGID) &&
829+
!in_group_p(i_gid_into_mnt(mnt_userns, inode)))
828830
inode->i_mode &= ~S_ISGID;
829831

830832
ip->i_d.di_size = 0;
@@ -901,6 +903,7 @@ xfs_init_new_inode(
901903
*/
902904
int
903905
xfs_dir_ialloc(
906+
struct user_namespace *mnt_userns,
904907
struct xfs_trans **tpp,
905908
struct xfs_inode *dp,
906909
umode_t mode,
@@ -933,7 +936,8 @@ xfs_dir_ialloc(
933936
return error;
934937
ASSERT(ino != NULLFSINO);
935938

936-
return xfs_init_new_inode(*tpp, dp, ino, mode, nlink, rdev, prid, ipp);
939+
return xfs_init_new_inode(mnt_userns, *tpp, dp, ino, mode, nlink, rdev,
940+
prid, ipp);
937941
}
938942

939943
/*
@@ -973,6 +977,7 @@ xfs_bumplink(
973977

974978
int
975979
xfs_create(
980+
struct user_namespace *mnt_userns,
976981
xfs_inode_t *dp,
977982
struct xfs_name *name,
978983
umode_t mode,
@@ -1047,7 +1052,8 @@ xfs_create(
10471052
* entry pointing to them, but a directory also the "." entry
10481053
* pointing to itself.
10491054
*/
1050-
error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, prid, &ip);
1055+
error = xfs_dir_ialloc(mnt_userns, &tp, dp, mode, is_dir ? 2 : 1, rdev,
1056+
prid, &ip);
10511057
if (error)
10521058
goto out_trans_cancel;
10531059

@@ -1128,6 +1134,7 @@ xfs_create(
11281134

11291135
int
11301136
xfs_create_tmpfile(
1137+
struct user_namespace *mnt_userns,
11311138
struct xfs_inode *dp,
11321139
umode_t mode,
11331140
struct xfs_inode **ipp)
@@ -1169,7 +1176,7 @@ xfs_create_tmpfile(
11691176
if (error)
11701177
goto out_trans_cancel;
11711178

1172-
error = xfs_dir_ialloc(&tp, dp, mode, 0, 0, prid, &ip);
1179+
error = xfs_dir_ialloc(mnt_userns, &tp, dp, mode, 0, 0, prid, &ip);
11731180
if (error)
11741181
goto out_trans_cancel;
11751182

@@ -2977,13 +2984,15 @@ xfs_cross_rename(
29772984
*/
29782985
static int
29792986
xfs_rename_alloc_whiteout(
2987+
struct user_namespace *mnt_userns,
29802988
struct xfs_inode *dp,
29812989
struct xfs_inode **wip)
29822990
{
29832991
struct xfs_inode *tmpfile;
29842992
int error;
29852993

2986-
error = xfs_create_tmpfile(dp, S_IFCHR | WHITEOUT_MODE, &tmpfile);
2994+
error = xfs_create_tmpfile(mnt_userns, dp, S_IFCHR | WHITEOUT_MODE,
2995+
&tmpfile);
29872996
if (error)
29882997
return error;
29892998

@@ -3005,6 +3014,7 @@ xfs_rename_alloc_whiteout(
30053014
*/
30063015
int
30073016
xfs_rename(
3017+
struct user_namespace *mnt_userns,
30083018
struct xfs_inode *src_dp,
30093019
struct xfs_name *src_name,
30103020
struct xfs_inode *src_ip,
@@ -3036,7 +3046,7 @@ xfs_rename(
30363046
*/
30373047
if (flags & RENAME_WHITEOUT) {
30383048
ASSERT(!(flags & (RENAME_NOREPLACE | RENAME_EXCHANGE)));
3039-
error = xfs_rename_alloc_whiteout(target_dp, &wip);
3049+
error = xfs_rename_alloc_whiteout(mnt_userns, target_dp, &wip);
30403050
if (error)
30413051
return error;
30423052

fs/xfs/xfs_inode.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,15 +369,18 @@ int xfs_release(struct xfs_inode *ip);
369369
void xfs_inactive(struct xfs_inode *ip);
370370
int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
371371
struct xfs_inode **ipp, struct xfs_name *ci_name);
372-
int xfs_create(struct xfs_inode *dp, struct xfs_name *name,
372+
int xfs_create(struct user_namespace *mnt_userns,
373+
struct xfs_inode *dp, struct xfs_name *name,
373374
umode_t mode, dev_t rdev, struct xfs_inode **ipp);
374-
int xfs_create_tmpfile(struct xfs_inode *dp, umode_t mode,
375+
int xfs_create_tmpfile(struct user_namespace *mnt_userns,
376+
struct xfs_inode *dp, umode_t mode,
375377
struct xfs_inode **ipp);
376378
int xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
377379
struct xfs_inode *ip);
378380
int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
379381
struct xfs_name *target_name);
380-
int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
382+
int xfs_rename(struct user_namespace *mnt_userns,
383+
struct xfs_inode *src_dp, struct xfs_name *src_name,
381384
struct xfs_inode *src_ip, struct xfs_inode *target_dp,
382385
struct xfs_name *target_name,
383386
struct xfs_inode *target_ip, unsigned int flags);
@@ -407,9 +410,10 @@ void xfs_lock_two_inodes(struct xfs_inode *ip0, uint ip0_mode,
407410
xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip);
408411
xfs_extlen_t xfs_get_cowextsz_hint(struct xfs_inode *ip);
409412

410-
int xfs_dir_ialloc(struct xfs_trans **tpp, struct xfs_inode *dp, umode_t mode,
411-
xfs_nlink_t nlink, dev_t dev, prid_t prid,
412-
struct xfs_inode **ipp);
413+
int xfs_dir_ialloc(struct user_namespace *mnt_userns,
414+
struct xfs_trans **tpp, struct xfs_inode *dp,
415+
umode_t mode, xfs_nlink_t nlink, dev_t dev,
416+
prid_t prid, struct xfs_inode **ipp);
413417

414418
static inline int
415419
xfs_itruncate_extents(

fs/xfs/xfs_ioctl.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,8 @@ xfs_ioc_space(
693693

694694
iattr.ia_valid = ATTR_SIZE;
695695
iattr.ia_size = bf->l_start;
696-
error = xfs_vn_setattr_size(file_dentry(filp), &iattr);
696+
error = xfs_vn_setattr_size(file_mnt_user_ns(filp), file_dentry(filp),
697+
&iattr);
697698
if (error)
698699
goto out_unlock;
699700

@@ -734,13 +735,15 @@ xfs_fsinumbers_fmt(
734735

735736
STATIC int
736737
xfs_ioc_fsbulkstat(
737-
xfs_mount_t *mp,
738+
struct file *file,
738739
unsigned int cmd,
739740
void __user *arg)
740741
{
742+
struct xfs_mount *mp = XFS_I(file_inode(file))->i_mount;
741743
struct xfs_fsop_bulkreq bulkreq;
742744
struct xfs_ibulk breq = {
743745
.mp = mp,
746+
.mnt_userns = file_mnt_user_ns(file),
744747
.ocount = 0,
745748
};
746749
xfs_ino_t lastino;
@@ -908,13 +911,15 @@ xfs_bulk_ireq_teardown(
908911
/* Handle the v5 bulkstat ioctl. */
909912
STATIC int
910913
xfs_ioc_bulkstat(
911-
struct xfs_mount *mp,
914+
struct file *file,
912915
unsigned int cmd,
913916
struct xfs_bulkstat_req __user *arg)
914917
{
918+
struct xfs_mount *mp = XFS_I(file_inode(file))->i_mount;
915919
struct xfs_bulk_ireq hdr;
916920
struct xfs_ibulk breq = {
917921
.mp = mp,
922+
.mnt_userns = file_mnt_user_ns(file),
918923
};
919924
int error;
920925

@@ -1275,8 +1280,9 @@ xfs_ioctl_setattr_prepare_dax(
12751280
*/
12761281
static struct xfs_trans *
12771282
xfs_ioctl_setattr_get_trans(
1278-
struct xfs_inode *ip)
1283+
struct file *file)
12791284
{
1285+
struct xfs_inode *ip = XFS_I(file_inode(file));
12801286
struct xfs_mount *mp = ip->i_mount;
12811287
struct xfs_trans *tp;
12821288
int error = -EROFS;
@@ -1300,7 +1306,7 @@ xfs_ioctl_setattr_get_trans(
13001306
* The user ID of the calling process must be equal to the file owner
13011307
* ID, except in cases where the CAP_FSETID capability is applicable.
13021308
*/
1303-
if (!inode_owner_or_capable(&init_user_ns, VFS_I(ip))) {
1309+
if (!inode_owner_or_capable(file_mnt_user_ns(file), VFS_I(ip))) {
13041310
error = -EPERM;
13051311
goto out_cancel;
13061312
}
@@ -1428,9 +1434,11 @@ xfs_ioctl_setattr_check_projid(
14281434

14291435
STATIC int
14301436
xfs_ioctl_setattr(
1431-
xfs_inode_t *ip,
1437+
struct file *file,
14321438
struct fsxattr *fa)
14331439
{
1440+
struct user_namespace *mnt_userns = file_mnt_user_ns(file);
1441+
struct xfs_inode *ip = XFS_I(file_inode(file));
14341442
struct fsxattr old_fa;
14351443
struct xfs_mount *mp = ip->i_mount;
14361444
struct xfs_trans *tp;
@@ -1462,7 +1470,7 @@ xfs_ioctl_setattr(
14621470

14631471
xfs_ioctl_setattr_prepare_dax(ip, fa);
14641472

1465-
tp = xfs_ioctl_setattr_get_trans(ip);
1473+
tp = xfs_ioctl_setattr_get_trans(file);
14661474
if (IS_ERR(tp)) {
14671475
code = PTR_ERR(tp);
14681476
goto error_free_dquots;
@@ -1502,7 +1510,7 @@ xfs_ioctl_setattr(
15021510
*/
15031511

15041512
if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
1505-
!capable_wrt_inode_uidgid(&init_user_ns, VFS_I(ip), CAP_FSETID))
1513+
!capable_wrt_inode_uidgid(mnt_userns, VFS_I(ip), CAP_FSETID))
15061514
VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
15071515

15081516
/* Change the ownerships and register project quota modifications */
@@ -1549,7 +1557,6 @@ xfs_ioctl_setattr(
15491557

15501558
STATIC int
15511559
xfs_ioc_fssetxattr(
1552-
xfs_inode_t *ip,
15531560
struct file *filp,
15541561
void __user *arg)
15551562
{
@@ -1562,7 +1569,7 @@ xfs_ioc_fssetxattr(
15621569
error = mnt_want_write_file(filp);
15631570
if (error)
15641571
return error;
1565-
error = xfs_ioctl_setattr(ip, &fa);
1572+
error = xfs_ioctl_setattr(filp, &fa);
15661573
mnt_drop_write_file(filp);
15671574
return error;
15681575
}
@@ -1608,7 +1615,7 @@ xfs_ioc_setxflags(
16081615

16091616
xfs_ioctl_setattr_prepare_dax(ip, &fa);
16101617

1611-
tp = xfs_ioctl_setattr_get_trans(ip);
1618+
tp = xfs_ioctl_setattr_get_trans(filp);
16121619
if (IS_ERR(tp)) {
16131620
error = PTR_ERR(tp);
16141621
goto out_drop_write;
@@ -2119,10 +2126,10 @@ xfs_file_ioctl(
21192126
case XFS_IOC_FSBULKSTAT_SINGLE:
21202127
case XFS_IOC_FSBULKSTAT:
21212128
case XFS_IOC_FSINUMBERS:
2122-
return xfs_ioc_fsbulkstat(mp, cmd, arg);
2129+
return xfs_ioc_fsbulkstat(filp, cmd, arg);
21232130

21242131
case XFS_IOC_BULKSTAT:
2125-
return xfs_ioc_bulkstat(mp, cmd, arg);
2132+
return xfs_ioc_bulkstat(filp, cmd, arg);
21262133
case XFS_IOC_INUMBERS:
21272134
return xfs_ioc_inumbers(mp, cmd, arg);
21282135

@@ -2144,7 +2151,7 @@ xfs_file_ioctl(
21442151
case XFS_IOC_FSGETXATTRA:
21452152
return xfs_ioc_fsgetxattr(ip, 1, arg);
21462153
case XFS_IOC_FSSETXATTR:
2147-
return xfs_ioc_fssetxattr(ip, filp, arg);
2154+
return xfs_ioc_fssetxattr(filp, arg);
21482155
case XFS_IOC_GETXFLAGS:
21492156
return xfs_ioc_getxflags(ip, arg);
21502157
case XFS_IOC_SETXFLAGS:

fs/xfs/xfs_ioctl32.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,16 @@ xfs_fsbulkstat_one_fmt_compat(
209209
/* copied from xfs_ioctl.c */
210210
STATIC int
211211
xfs_compat_ioc_fsbulkstat(
212-
xfs_mount_t *mp,
212+
struct file *file,
213213
unsigned int cmd,
214214
struct compat_xfs_fsop_bulkreq __user *p32)
215215
{
216+
struct xfs_mount *mp = XFS_I(file_inode(file))->i_mount;
216217
u32 addr;
217218
struct xfs_fsop_bulkreq bulkreq;
218219
struct xfs_ibulk breq = {
219220
.mp = mp,
221+
.mnt_userns = file_mnt_user_ns(file),
220222
.ocount = 0,
221223
};
222224
xfs_ino_t lastino;
@@ -507,7 +509,7 @@ xfs_file_compat_ioctl(
507509
case XFS_IOC_FSBULKSTAT_32:
508510
case XFS_IOC_FSBULKSTAT_SINGLE_32:
509511
case XFS_IOC_FSINUMBERS_32:
510-
return xfs_compat_ioc_fsbulkstat(mp, cmd, arg);
512+
return xfs_compat_ioc_fsbulkstat(filp, cmd, arg);
511513
case XFS_IOC_FD_TO_HANDLE_32:
512514
case XFS_IOC_PATH_TO_HANDLE_32:
513515
case XFS_IOC_PATH_TO_FSHANDLE_32: {

0 commit comments

Comments
 (0)