未验证 提交 71e7b535 编写于 作者: C Christian Brauner 提交者: Christian Brauner (Microsoft)

quota: port quota helpers mount ids

Port the is_quota_modification() and dqout_transfer() helper to type
safe vfs{g,u}id_t. Since these helpers are only called by a few
filesystems don't introduce a new helper but simply extend the existing
helpers to pass down the mount's idmapping.

Note, that this is a non-functional change, i.e. nothing will have
happened here or at the end of this series to how quota are done! This
a change necessary because we will at the end of this series make
ownership changes easier to reason about by keeping the original value
in struct iattr for both non-idmapped and idmapped mounts.

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.

Since struct iattr uses an anonymous union with overlapping types as
supported by the C standard, filesystems that haven't converted to
ia_vfs{g,u}id won't see any difference and things will continue to work
as before. In other words, no functional changes intended with this
change.

Link: https://lore.kernel.org/r/20220621141454.2914719-7-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jan Kara <jack@suse.cz>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
CC: linux-fsdevel@vger.kernel.org
Reviewed-by: NJan Kara <jack@suse.cz>
Reviewed-by: NSeth Forshee <sforshee@digitalocean.com>
Signed-off-by: NChristian Brauner (Microsoft) <brauner@kernel.org>
上级 35faf310
...@@ -1679,14 +1679,14 @@ int ext2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -1679,14 +1679,14 @@ int ext2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
if (error) if (error)
return error; return error;
if (is_quota_modification(inode, iattr)) { if (is_quota_modification(&init_user_ns, inode, iattr)) {
error = dquot_initialize(inode); error = dquot_initialize(inode);
if (error) if (error)
return error; return error;
} }
if (i_uid_needs_update(&init_user_ns, iattr, inode) || if (i_uid_needs_update(&init_user_ns, iattr, inode) ||
i_gid_needs_update(&init_user_ns, iattr, inode)) { i_gid_needs_update(&init_user_ns, iattr, inode)) {
error = dquot_transfer(inode, iattr); error = dquot_transfer(&init_user_ns, inode, iattr);
if (error) if (error)
return error; return error;
} }
......
...@@ -5350,7 +5350,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -5350,7 +5350,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
if (error) if (error)
return error; return error;
if (is_quota_modification(inode, attr)) { if (is_quota_modification(&init_user_ns, inode, attr)) {
error = dquot_initialize(inode); error = dquot_initialize(inode);
if (error) if (error)
return error; return error;
...@@ -5374,7 +5374,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -5374,7 +5374,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
* counts xattr inode references. * counts xattr inode references.
*/ */
down_read(&EXT4_I(inode)->xattr_sem); down_read(&EXT4_I(inode)->xattr_sem);
error = dquot_transfer(inode, attr); error = dquot_transfer(&init_user_ns, inode, attr);
up_read(&EXT4_I(inode)->xattr_sem); up_read(&EXT4_I(inode)->xattr_sem);
if (error) { if (error) {
......
...@@ -915,7 +915,7 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -915,7 +915,7 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
if (err) if (err)
return err; return err;
if (is_quota_modification(inode, attr)) { if (is_quota_modification(&init_user_ns, inode, attr)) {
err = f2fs_dquot_initialize(inode); err = f2fs_dquot_initialize(inode);
if (err) if (err)
return err; return err;
...@@ -923,7 +923,7 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -923,7 +923,7 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
if (i_uid_needs_update(&init_user_ns, attr, inode) || if (i_uid_needs_update(&init_user_ns, attr, inode) ||
i_gid_needs_update(&init_user_ns, attr, inode)) { i_gid_needs_update(&init_user_ns, attr, inode)) {
f2fs_lock_op(F2FS_I_SB(inode)); f2fs_lock_op(F2FS_I_SB(inode));
err = dquot_transfer(inode, attr); err = dquot_transfer(&init_user_ns, inode, attr);
if (err) { if (err) {
set_sbi_flag(F2FS_I_SB(inode), set_sbi_flag(F2FS_I_SB(inode),
SBI_QUOTA_NEED_REPAIR); SBI_QUOTA_NEED_REPAIR);
......
...@@ -266,7 +266,7 @@ static int recover_quota_data(struct inode *inode, struct page *page) ...@@ -266,7 +266,7 @@ static int recover_quota_data(struct inode *inode, struct page *page)
if (!attr.ia_valid) if (!attr.ia_valid)
return 0; return 0;
err = dquot_transfer(inode, &attr); err = dquot_transfer(&init_user_ns, inode, &attr);
if (err) if (err)
set_sbi_flag(F2FS_I_SB(inode), SBI_QUOTA_NEED_REPAIR); set_sbi_flag(F2FS_I_SB(inode), SBI_QUOTA_NEED_REPAIR);
return err; return err;
......
...@@ -95,14 +95,14 @@ int jfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -95,14 +95,14 @@ int jfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
if (rc) if (rc)
return rc; return rc;
if (is_quota_modification(inode, iattr)) { if (is_quota_modification(&init_user_ns, inode, iattr)) {
rc = dquot_initialize(inode); rc = dquot_initialize(inode);
if (rc) if (rc)
return rc; return rc;
} }
if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) || if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
(iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) { (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
rc = dquot_transfer(inode, iattr); rc = dquot_transfer(&init_user_ns, inode, iattr);
if (rc) if (rc)
return rc; return rc;
} }
......
...@@ -1146,7 +1146,7 @@ int ocfs2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -1146,7 +1146,7 @@ int ocfs2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
if (status) if (status)
return status; return status;
if (is_quota_modification(inode, attr)) { if (is_quota_modification(&init_user_ns, inode, attr)) {
status = dquot_initialize(inode); status = dquot_initialize(inode);
if (status) if (status)
return status; return status;
......
...@@ -2085,7 +2085,8 @@ EXPORT_SYMBOL(__dquot_transfer); ...@@ -2085,7 +2085,8 @@ EXPORT_SYMBOL(__dquot_transfer);
/* Wrapper for transferring ownership of an inode for uid/gid only /* Wrapper for transferring ownership of an inode for uid/gid only
* Called from FSXXX_setattr() * Called from FSXXX_setattr()
*/ */
int dquot_transfer(struct inode *inode, struct iattr *iattr) int dquot_transfer(struct user_namespace *mnt_userns, struct inode *inode,
struct iattr *iattr)
{ {
struct dquot *transfer_to[MAXQUOTAS] = {}; struct dquot *transfer_to[MAXQUOTAS] = {};
struct dquot *dquot; struct dquot *dquot;
......
...@@ -3284,7 +3284,7 @@ int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -3284,7 +3284,7 @@ int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
/* must be turned off for recursive notify_change calls */ /* must be turned off for recursive notify_change calls */
ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
if (is_quota_modification(inode, attr)) { if (is_quota_modification(&init_user_ns, inode, attr)) {
error = dquot_initialize(inode); error = dquot_initialize(inode);
if (error) if (error)
return error; return error;
...@@ -3367,7 +3367,7 @@ int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -3367,7 +3367,7 @@ int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
reiserfs_write_unlock(inode->i_sb); reiserfs_write_unlock(inode->i_sb);
if (error) if (error)
goto out; goto out;
error = dquot_transfer(inode, attr); error = dquot_transfer(&init_user_ns, inode, attr);
reiserfs_write_lock(inode->i_sb); reiserfs_write_lock(inode->i_sb);
if (error) { if (error) {
journal_end(&th); journal_end(&th);
......
...@@ -616,7 +616,7 @@ static int zonefs_inode_setattr(struct user_namespace *mnt_userns, ...@@ -616,7 +616,7 @@ static int zonefs_inode_setattr(struct user_namespace *mnt_userns,
!uid_eq(iattr->ia_uid, inode->i_uid)) || !uid_eq(iattr->ia_uid, inode->i_uid)) ||
((iattr->ia_valid & ATTR_GID) && ((iattr->ia_valid & ATTR_GID) &&
!gid_eq(iattr->ia_gid, inode->i_gid))) { !gid_eq(iattr->ia_gid, inode->i_gid))) {
ret = dquot_transfer(inode, iattr); ret = dquot_transfer(&init_user_ns, inode, iattr);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -20,7 +20,8 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb) ...@@ -20,7 +20,8 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
} }
/* i_mutex must being held */ /* i_mutex must being held */
static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) static inline bool is_quota_modification(struct user_namespace *mnt_userns,
struct inode *inode, struct iattr *ia)
{ {
return ((ia->ia_valid & ATTR_SIZE) || return ((ia->ia_valid & ATTR_SIZE) ||
i_uid_needs_update(&init_user_ns, ia, inode) || i_uid_needs_update(&init_user_ns, ia, inode) ||
...@@ -115,7 +116,8 @@ int dquot_set_dqblk(struct super_block *sb, struct kqid id, ...@@ -115,7 +116,8 @@ int dquot_set_dqblk(struct super_block *sb, struct kqid id,
struct qc_dqblk *di); struct qc_dqblk *di);
int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); int __dquot_transfer(struct inode *inode, struct dquot **transfer_to);
int dquot_transfer(struct inode *inode, struct iattr *iattr); int dquot_transfer(struct user_namespace *mnt_userns, struct inode *inode,
struct iattr *iattr);
static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
{ {
...@@ -234,7 +236,8 @@ static inline void dquot_free_inode(struct inode *inode) ...@@ -234,7 +236,8 @@ static inline void dquot_free_inode(struct inode *inode)
{ {
} }
static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) static inline int dquot_transfer(struct user_namespace *mnt_userns,
struct inode *inode, struct iattr *iattr)
{ {
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册