1 Subject: [PATCH] P: linux-5.14/ext4-projid-xattrs.patch
5 fs/ext4/ioctl.c | 4 +--
6 fs/ext4/xattr.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
7 3 files changed, 87 insertions(+), 2 deletions(-)
9 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
10 index afca42d..9ba2e8b 100644
13 @@ -3164,6 +3164,7 @@ extern int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
14 ext4_lblk_t start, ext4_lblk_t end);
17 +extern int ext4_ioctl_setproject(struct inode *, __u32);
18 extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
19 extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
20 int ext4_fileattr_set(struct user_namespace *mnt_userns,
21 diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
22 index 6eed617..88cb1fb 100644
25 @@ -461,7 +461,7 @@ flags_out:
29 -static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
30 +int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
32 struct super_block *sb = inode->i_sb;
33 struct ext4_inode_info *ei = EXT4_I(inode);
34 @@ -546,7 +546,7 @@ out_stop:
38 -static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
39 +int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
41 if (projid != EXT4_DEF_PROJID)
43 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
44 index aabc92e..442bfbd 100644
51 +#define EXT4_XATTR_PROJID "projid"
53 #ifdef EXT4_XATTR_DEBUG
54 # define ea_idebug(inode, fmt, ...) \
55 printk(KERN_DEBUG "inode %s:%lu: " fmt "\n", \
56 @@ -648,11 +650,30 @@ ext4_xattr_get(struct inode *inode, int name_index, const char *name,
59 down_read(&EXT4_I(inode)->xattr_sem);
60 + if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
61 + strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
62 + ext4_has_feature_project(inode->i_sb)) {
63 + /* 10 chars to hold u32 in decimal, plus ending \0 */
65 + __u32 projid = (__u32)from_kprojid(&init_user_ns,
66 + EXT4_I(inode)->i_projid);
67 + error = snprintf(value, sizeof(value), "%u", projid);
69 + if (error > buffer_size) {
73 + memcpy(buffer, value, error);
78 error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
80 if (error == -ENODATA)
81 error = ext4_xattr_block_get(inode, name_index, name, buffer,
84 up_read(&EXT4_I(inode)->xattr_sem);
87 @@ -775,7 +796,33 @@ ext4_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
88 ret = ext4_xattr_block_list(dentry, buffer, buffer_size);
96 + if (ext4_has_feature_project(dentry->d_sb)) {
97 + size_t prefix_len = strlen(XATTR_TRUSTED_PREFIX);
98 + size_t name_len = strlen(EXT4_XATTR_PROJID);
99 + size_t size = prefix_len + name_len + 1;
101 + if (__kprojid_val(EXT4_I(dentry->d_inode)->i_projid) ==
105 + if (size > buffer_size) {
109 + strncpy(buffer, XATTR_TRUSTED_PREFIX, prefix_len);
110 + buffer += prefix_len;
111 + strncpy(buffer, EXT4_XATTR_PROJID, name_len);
112 + buffer += name_len;
114 + buffer_size -= size;
119 up_read(&EXT4_I(d_inode(dentry))->xattr_sem);
121 @@ -2456,6 +2503,43 @@ ext4_xattr_set(struct inode *inode, int name_index, const char *name,
122 int error, retries = 0;
125 + if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
126 + strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
127 + ext4_has_feature_project(inode->i_sb)) {
128 + /* 10 chars to hold u32 in decimal, plus ending \0 */
133 + * Project Quota ID state is only allowed to change from within
134 + * the init namespace.
136 + if (current_user_ns() != &init_user_ns)
139 + if (value && value_len) {
140 + if (value_len >= sizeof(buffer))
142 + memcpy(buffer, value, value_len);
143 + buffer[value_len] = '\0';
144 + error = kstrtouint(buffer, 0, &projid);
148 + projid = EXT4_DEF_PROJID;
152 + * Caller is allowed to change the project ID. If it is being
153 + * changed, make sure that the new value is valid.
155 + if (!projid_valid(make_kprojid(&init_user_ns, projid)))
158 + error = ext4_ioctl_setproject(inode, projid);
162 error = dquot_initialize(inode);