Skip to content

Commit 35faf31

Browse files
committed
fs: port to iattr ownership update helpers
Earlier we introduced new helpers to abstract ownership update and remove code duplication. This converts all filesystems supporting idmapped mounts to make use of these new helpers. For now we always pass the initial idmapping which makes the idmapping functions these helpers call nops. This is done because we currently always pass the actual value to be written to i_{g,u}id via struct iattr. While this allowed us to treat the {g,u}id values in struct iattr as values that can be directly written to inode->i_{g,u}id it also increases the potential for confusion for filesystems. Now that we are have dedicated types to prevent this confusion we will ultimately only map the value from the idmapped mount into a filesystem value that can be written to inode->i_{g,u}id when the filesystem actually updates the inode. So pass down the initial idmapping until we finished that conversion at which point we pass down the mount's idmapping. No functional changes intended. Link: https://lore.kernel.org/r/[email protected] Cc: Seth Forshee <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Aleksa Sarai <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Al Viro <[email protected]> CC: [email protected] Reviewed-by: Seth Forshee <[email protected]> Signed-off-by: Christian Brauner (Microsoft) <[email protected]>
1 parent 1f36146 commit 35faf31

File tree

8 files changed

+25
-35
lines changed

8 files changed

+25
-35
lines changed

fs/attr.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,8 @@ void setattr_copy(struct user_namespace *mnt_userns, struct inode *inode,
242242
{
243243
unsigned int ia_valid = attr->ia_valid;
244244

245-
if (ia_valid & ATTR_UID)
246-
inode->i_uid = attr->ia_uid;
247-
if (ia_valid & ATTR_GID)
248-
inode->i_gid = attr->ia_gid;
245+
i_uid_update(&init_user_ns, attr, inode);
246+
i_gid_update(&init_user_ns, attr, inode);
249247
if (ia_valid & ATTR_ATIME)
250248
inode->i_atime = attr->ia_atime;
251249
if (ia_valid & ATTR_MTIME)

fs/ext2/inode.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1684,8 +1684,8 @@ int ext2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
16841684
if (error)
16851685
return error;
16861686
}
1687-
if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
1688-
(iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
1687+
if (i_uid_needs_update(&init_user_ns, iattr, inode) ||
1688+
i_gid_needs_update(&init_user_ns, iattr, inode)) {
16891689
error = dquot_transfer(inode, iattr);
16901690
if (error)
16911691
return error;

fs/ext4/inode.c

+4-6
Original file line numberDiff line numberDiff line change
@@ -5356,8 +5356,8 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
53565356
return error;
53575357
}
53585358

5359-
if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
5360-
(ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
5359+
if (i_uid_needs_update(&init_user_ns, attr, inode) ||
5360+
i_gid_needs_update(&init_user_ns, attr, inode)) {
53615361
handle_t *handle;
53625362

53635363
/* (user+group)*(old+new) structure, inode write (sb,
@@ -5383,10 +5383,8 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
53835383
}
53845384
/* Update corresponding info in inode so that everything is in
53855385
* one transaction */
5386-
if (attr->ia_valid & ATTR_UID)
5387-
inode->i_uid = attr->ia_uid;
5388-
if (attr->ia_valid & ATTR_GID)
5389-
inode->i_gid = attr->ia_gid;
5386+
i_uid_update(&init_user_ns, attr, inode);
5387+
i_gid_update(&init_user_ns, attr, inode);
53905388
error = ext4_mark_inode_dirty(handle, inode);
53915389
ext4_journal_stop(handle);
53925390
if (unlikely(error)) {

fs/f2fs/file.c

+6-12
Original file line numberDiff line numberDiff line change
@@ -861,10 +861,8 @@ static void __setattr_copy(struct user_namespace *mnt_userns,
861861
{
862862
unsigned int ia_valid = attr->ia_valid;
863863

864-
if (ia_valid & ATTR_UID)
865-
inode->i_uid = attr->ia_uid;
866-
if (ia_valid & ATTR_GID)
867-
inode->i_gid = attr->ia_gid;
864+
i_uid_update(&init_user_ns, attr, inode);
865+
i_gid_update(&init_user_ns, attr, inode);
868866
if (ia_valid & ATTR_ATIME)
869867
inode->i_atime = attr->ia_atime;
870868
if (ia_valid & ATTR_MTIME)
@@ -922,10 +920,8 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
922920
if (err)
923921
return err;
924922
}
925-
if ((attr->ia_valid & ATTR_UID &&
926-
!uid_eq(attr->ia_uid, inode->i_uid)) ||
927-
(attr->ia_valid & ATTR_GID &&
928-
!gid_eq(attr->ia_gid, inode->i_gid))) {
923+
if (i_uid_needs_update(&init_user_ns, attr, inode) ||
924+
i_gid_needs_update(&init_user_ns, attr, inode)) {
929925
f2fs_lock_op(F2FS_I_SB(inode));
930926
err = dquot_transfer(inode, attr);
931927
if (err) {
@@ -938,10 +934,8 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
938934
* update uid/gid under lock_op(), so that dquot and inode can
939935
* be updated atomically.
940936
*/
941-
if (attr->ia_valid & ATTR_UID)
942-
inode->i_uid = attr->ia_uid;
943-
if (attr->ia_valid & ATTR_GID)
944-
inode->i_gid = attr->ia_gid;
937+
i_uid_update(&init_user_ns, attr, inode);
938+
i_gid_update(&init_user_ns, attr, inode);
945939
f2fs_mark_inode_dirty_sync(inode, true);
946940
f2fs_unlock_op(F2FS_I_SB(inode));
947941
}

fs/quota/dquot.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
20952095
if (!dquot_active(inode))
20962096
return 0;
20972097

2098-
if (iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)){
2098+
if (i_uid_needs_update(&init_user_ns, iattr, inode)) {
20992099
dquot = dqget(sb, make_kqid_uid(iattr->ia_uid));
21002100
if (IS_ERR(dquot)) {
21012101
if (PTR_ERR(dquot) != -ESRCH) {
@@ -2106,7 +2106,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
21062106
}
21072107
transfer_to[USRQUOTA] = dquot;
21082108
}
2109-
if (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)){
2109+
if (i_gid_needs_update(&init_user_ns, iattr, inode)) {
21102110
dquot = dqget(sb, make_kqid_gid(iattr->ia_gid));
21112111
if (IS_ERR(dquot)) {
21122112
if (PTR_ERR(dquot) != -ESRCH) {

fs/xfs/xfs_iops.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -704,13 +704,13 @@ xfs_setattr_nonsize(
704704
* didn't have the inode locked, inode's dquot(s) would have changed
705705
* also.
706706
*/
707-
if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp) &&
708-
!uid_eq(inode->i_uid, iattr->ia_uid)) {
707+
if (XFS_IS_UQUOTA_ON(mp) &&
708+
i_uid_needs_update(&init_user_ns, iattr, inode)) {
709709
ASSERT(udqp);
710710
old_udqp = xfs_qm_vop_chown(tp, ip, &ip->i_udquot, udqp);
711711
}
712-
if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp) &&
713-
!gid_eq(inode->i_gid, iattr->ia_gid)) {
712+
if (XFS_IS_GQUOTA_ON(mp) &&
713+
i_gid_needs_update(&init_user_ns, iattr, inode)) {
714714
ASSERT(xfs_has_pquotino(mp) || !XFS_IS_PQUOTA_ON(mp));
715715
ASSERT(gdqp);
716716
old_gdqp = xfs_qm_vop_chown(tp, ip, &ip->i_gdquot, gdqp);

include/linux/quotaops.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
2222
/* i_mutex must being held */
2323
static inline bool is_quota_modification(struct inode *inode, struct iattr *ia)
2424
{
25-
return (ia->ia_valid & ATTR_SIZE) ||
26-
(ia->ia_valid & ATTR_UID && !uid_eq(ia->ia_uid, inode->i_uid)) ||
27-
(ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid));
25+
return ((ia->ia_valid & ATTR_SIZE) ||
26+
i_uid_needs_update(&init_user_ns, ia, inode) ||
27+
i_gid_needs_update(&init_user_ns, ia, inode));
2828
}
2929

3030
#if defined(CONFIG_QUOTA)

security/integrity/evm/evm_main.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,8 @@ static int evm_attr_change(struct dentry *dentry, struct iattr *attr)
760760
struct inode *inode = d_backing_inode(dentry);
761761
unsigned int ia_valid = attr->ia_valid;
762762

763-
if ((!(ia_valid & ATTR_UID) || uid_eq(attr->ia_uid, inode->i_uid)) &&
764-
(!(ia_valid & ATTR_GID) || gid_eq(attr->ia_gid, inode->i_gid)) &&
763+
if (!i_uid_needs_update(&init_user_ns, attr, inode) &&
764+
!i_gid_needs_update(&init_user_ns, attr, inode) &&
765765
(!(ia_valid & ATTR_MODE) || attr->ia_mode == inode->i_mode))
766766
return 0;
767767

0 commit comments

Comments
 (0)