--- /dev/null
+Index: linux-4.18.0-348.2.1.el8_5/fs/ext4/ext4.h
+===================================================================
+--- linux-4.18.0-348.2.1.el8_5.orig/fs/ext4/ext4.h
++++ linux-4.18.0-348.2.1.el8_5/fs/ext4/ext4.h
+@@ -2770,6 +2770,7 @@ extern int ext4_ind_remove_space(handle_
+ /* ioctl.c */
+ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
+ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
++extern int ext4_ioctl_setproject(struct inode *, __u32);
+
+ /* migrate.c */
+ extern int ext4_ext_migrate(struct inode *);
+Index: linux-4.18.0-348.2.1.el8_5/fs/ext4/ioctl.c
+===================================================================
+--- linux-4.18.0-348.2.1.el8_5.orig/fs/ext4/ioctl.c
++++ linux-4.18.0-348.2.1.el8_5/fs/ext4/ioctl.c
+@@ -446,9 +446,8 @@ flags_out:
+ }
+
+ #ifdef CONFIG_QUOTA
+-static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
++int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ {
+- struct inode *inode = file_inode(filp);
+ struct super_block *sb = inode->i_sb;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ int err, rc;
+@@ -532,7 +531,7 @@ out_stop:
+ return err;
+ }
+ #else
+-static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
++static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ {
+ if (projid != EXT4_DEF_PROJID)
+ return -EOPNOTSUPP;
+@@ -1184,7 +1183,7 @@ resizefs_out:
+ err = ext4_ioctl_setflags(inode, flags);
+ if (err)
+ goto out;
+- err = ext4_ioctl_setproject(filp, fa.fsx_projid);
++ err = ext4_ioctl_setproject(inode, fa.fsx_projid);
+ out:
+ inode_unlock(inode);
+ mnt_drop_write_file(filp);
+Index: linux-4.18.0-348.2.1.el8_5/fs/ext4/xattr.c
+===================================================================
+--- linux-4.18.0-348.2.1.el8_5.orig/fs/ext4/xattr.c
++++ linux-4.18.0-348.2.1.el8_5/fs/ext4/xattr.c
+@@ -62,6 +62,8 @@
+ #include "xattr.h"
+ #include "acl.h"
+
++#define EXT4_XATTR_PROJID "projid"
++
+ #ifdef EXT4_XATTR_DEBUG
+ # define ea_idebug(inode, fmt, ...) \
+ printk(KERN_DEBUG "inode %s:%lu: " fmt "\n", \
+@@ -646,11 +648,30 @@ ext4_xattr_get(struct inode *inode, int
+ return -ERANGE;
+
+ down_read(&EXT4_I(inode)->xattr_sem);
++ if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
++ strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
++ ext4_has_feature_project(inode->i_sb)) {
++ /* 10 chars to hold u32 in decimal, plus ending \0 */
++ char value[11];
++ __u32 projid = (__u32)from_kprojid(&init_user_ns,
++ EXT4_I(inode)->i_projid);
++ error = snprintf(value, sizeof(value), "%u", projid);
++ if (buffer) {
++ if (error > buffer_size) {
++ error = -ERANGE;
++ goto out;
++ }
++ memcpy(buffer, value, error);
++ }
++ goto out;
++ }
++
+ error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
+ buffer_size);
+ if (error == -ENODATA)
+ error = ext4_xattr_block_get(inode, name_index, name, buffer,
+ buffer_size);
++out:
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
+@@ -772,7 +793,33 @@ ext4_listxattr(struct dentry *dentry, ch
+ ret = ext4_xattr_block_list(dentry, buffer, buffer_size);
+ if (ret < 0)
+ goto errout;
++ if (buffer) {
++ buffer += ret;
++ buffer_size -= ret;
++ }
+ ret += ret2;
++ if (ext4_has_feature_project(dentry->d_sb)) {
++ size_t prefix_len = strlen(XATTR_TRUSTED_PREFIX);
++ size_t name_len = strlen(EXT4_XATTR_PROJID);
++ size_t size = prefix_len + name_len + 1;
++
++ if (__kprojid_val(EXT4_I(dentry->d_inode)->i_projid) ==
++ EXT4_DEF_PROJID)
++ goto errout;
++ if (buffer) {
++ if (size > buffer_size) {
++ ret = -ERANGE;
++ goto errout;
++ }
++ strncpy(buffer, XATTR_TRUSTED_PREFIX, prefix_len);
++ buffer += prefix_len;
++ strncpy(buffer, EXT4_XATTR_PROJID, name_len);
++ buffer += name_len;
++ *buffer++ = 0;
++ buffer_size -= size;
++ }
++ ret += size;
++ }
+ errout:
+ up_read(&EXT4_I(d_inode(dentry))->xattr_sem);
+ return ret;
+@@ -2464,6 +2511,43 @@ ext4_xattr_set(struct inode *inode, int
+ int error, retries = 0;
+ int credits;
+
++ if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
++ strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
++ ext4_has_feature_project(inode->i_sb)) {
++ /* 10 chars to hold u32 in decimal, plus ending \0 */
++ char buffer[11];
++ __u32 projid;
++
++ /*
++ * Project Quota ID state is only allowed to change from within
++ * the init namespace.
++ */
++ if (current_user_ns() != &init_user_ns)
++ return -EINVAL;
++
++ if (value && value_len) {
++ if (value_len >= sizeof(buffer))
++ return -EINVAL;
++ memcpy(buffer, value, value_len);
++ buffer[value_len] = '\0';
++ error = kstrtouint(buffer, 0, &projid);
++ if (error)
++ return error;
++ } else {
++ projid = EXT4_DEF_PROJID;
++ }
++
++ /*
++ * Caller is allowed to change the project ID. If it is being
++ * changed, make sure that the new value is valid.
++ */
++ if (!projid_valid(make_kprojid(&init_user_ns, projid)))
++ return -EINVAL;
++
++ error = ext4_ioctl_setproject(inode, projid);
++ return error;
++ }
++
+ error = dquot_initialize(inode);
+ if (error)
+ return error;
--- /dev/null
+Index: linux-3.10.0-1160.45.1.el7/fs/ext4/xattr.c
+===================================================================
+--- linux-3.10.0-1160.45.1.el7.orig/fs/ext4/xattr.c
++++ linux-3.10.0-1160.45.1.el7/fs/ext4/xattr.c
+@@ -61,6 +61,8 @@
+ #include "xattr.h"
+ #include "acl.h"
+
++#define EXT4_XATTR_PROJID "projid"
++
+ #ifdef EXT4_XATTR_DEBUG
+ # define ea_idebug(inode, f...) do { \
+ printk(KERN_DEBUG "inode %s:%lu: ", \
+@@ -531,11 +533,31 @@ ext4_xattr_get(struct inode *inode, int
+ return -ERANGE;
+
+ down_read(&EXT4_I(inode)->xattr_sem);
++ if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
++ strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
++ EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
++ EXT4_FEATURE_RO_COMPAT_PROJECT)) {
++ /* 10 chars to hold u32 in decimal, plus ending \0 */
++ char value[11];
++ __u32 projid = (__u32)from_kprojid(&init_user_ns,
++ EXT4_I(inode)->i_projid);
++ error = snprintf(value, sizeof(value), "%u", projid);
++ if (buffer) {
++ if (error > buffer_size) {
++ error = -ERANGE;
++ goto out;
++ }
++ memcpy(buffer, value, error);
++ }
++ goto out;
++ }
++
+ error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
+ buffer_size);
+ if (error == -ENODATA)
+ error = ext4_xattr_block_get(inode, name_index, name, buffer,
+ buffer_size);
++out:
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
+@@ -657,7 +679,34 @@ ext4_xattr_list(struct dentry *dentry, c
+ ret = ext4_xattr_block_list(dentry, buffer, buffer_size);
+ if (ret < 0)
+ goto errout;
++ if (buffer) {
++ buffer += ret;
++ buffer_size -= ret;
++ }
+ ret += ret2;
++ if (EXT4_HAS_RO_COMPAT_FEATURE(dentry->d_sb,
++ EXT4_FEATURE_RO_COMPAT_PROJECT)) {
++ size_t prefix_len = strlen(XATTR_TRUSTED_PREFIX);
++ size_t name_len = strlen(EXT4_XATTR_PROJID);
++ size_t size = prefix_len + name_len + 1;
++
++ if (__kprojid_val(EXT4_I(dentry->d_inode)->i_projid) ==
++ EXT4_DEF_PROJID)
++ goto errout;
++ if (buffer) {
++ if (size > buffer_size) {
++ ret = -ERANGE;
++ goto errout;
++ }
++ strncpy(buffer, XATTR_TRUSTED_PREFIX, prefix_len);
++ buffer += prefix_len;
++ strncpy(buffer, EXT4_XATTR_PROJID, name_len);
++ buffer += name_len;
++ *buffer++ = 0;
++ buffer_size -= size;
++ }
++ ret += size;
++ }
+ errout:
+ up_read(&EXT4_I(dentry->d_inode)->xattr_sem);
+ return ret;
+@@ -1552,6 +1601,44 @@ ext4_xattr_set(struct inode *inode, int
+ int error, retries = 0;
+ int credits = ext4_jbd2_credits_xattr(inode);
+
++ if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
++ strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
++ EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
++ EXT4_FEATURE_RO_COMPAT_PROJECT)) {
++ /* 10 chars to hold u32 in decimal, plus ending \0 */
++ char buffer[11];
++ __u32 projid;
++
++ /*
++ * Project Quota ID state is only allowed to change from within
++ * the init namespace.
++ */
++ if (current_user_ns() != &init_user_ns)
++ return -EINVAL;
++
++ if (value && value_len) {
++ if (value_len >= sizeof(buffer))
++ return -EINVAL;
++ memcpy(buffer, value, value_len);
++ buffer[value_len] = '\0';
++ error = kstrtouint(buffer, 0, &projid);
++ if (error)
++ return error;
++ } else {
++ projid = EXT4_DEF_PROJID;
++ }
++
++ /*
++ * Caller is allowed to change the project ID. If it is being
++ * changed, make sure that the new value is valid.
++ */
++ if (!projid_valid(make_kprojid(&init_user_ns, projid)))
++ return -EINVAL;
++
++ error = ext4_ioctl_setproject(inode, projid);
++ return error;
++ }
++
+ if ((value_len >= EXT4_XATTR_MIN_LARGE_EA_SIZE(sb->s_blocksize)) &&
+ EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EA_INODE)) {
+ int nrblocks = (value_len + sb->s_blocksize - 1) >>
+Index: linux-3.10.0-1160.45.1.el7/fs/ext4/ioctl.c
+===================================================================
+--- linux-3.10.0-1160.45.1.el7.orig/fs/ext4/ioctl.c
++++ linux-3.10.0-1160.45.1.el7/fs/ext4/ioctl.c
+@@ -302,9 +302,8 @@ flags_out:
+ }
+
+ #ifdef CONFIG_QUOTA
+-static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
++int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ {
+- struct inode *inode = file_inode(filp);
+ struct super_block *sb = inode->i_sb;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ int err, rc;
+@@ -332,25 +331,20 @@ static int ext4_ioctl_setproject(struct
+ if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
+ return 0;
+
+- err = mnt_want_write_file(filp);
+- if (err)
+- return err;
+-
+ err = -EPERM;
+- mutex_lock(&inode->i_mutex);
+ /* Is it quota file? Do not allow user to mess with it */
+ if (IS_NOQUOTA(inode))
+- goto out_unlock;
++ goto out;
+
+ err = ext4_get_inode_loc(inode, &iloc);
+ if (err)
+- goto out_unlock;
++ goto out;
+
+ raw_inode = ext4_raw_inode(&iloc);
+ if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
+ err = -EOVERFLOW;
+ brelse(iloc.bh);
+- goto out_unlock;
++ goto out;
+ }
+ brelse(iloc.bh);
+
+@@ -361,7 +355,7 @@ static int ext4_ioctl_setproject(struct
+ EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+ if (IS_ERR(handle)) {
+ err = PTR_ERR(handle);
+- goto out_unlock;
++ goto out;
+ }
+
+ err = ext4_reserve_inode_write(handle, inode, &iloc);
+@@ -384,16 +378,14 @@ out_dirty:
+ err = rc;
+ out_stop:
+ ext4_journal_stop(handle);
+-out_unlock:
+- mutex_unlock(&inode->i_mutex);
+- mnt_drop_write_file(filp);
++out:
+ return err;
+
+
+ }
+
+ #else
+-static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
++int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ {
+ if (projid != EXT4_DEF_PROJID)
+ return -EOPNOTSUPP;
+@@ -841,7 +833,14 @@ resizefs_out:
+ if (err)
+ return err;
+
+- err = ext4_ioctl_setproject(filp, fa.fsx_projid);
++ err = mnt_want_write_file(filp);
++ if (err)
++ return err;
++
++ mutex_lock(&inode->i_mutex);
++ err = ext4_ioctl_setproject(inode, fa.fsx_projid);
++ mutex_unlock(&inode->i_mutex);
++ mnt_drop_write_file(filp);
+ if (err)
+ return err;
+
+Index: linux-3.10.0-1160.45.1.el7/fs/ext4/ext4.h
+===================================================================
+--- linux-3.10.0-1160.45.1.el7.orig/fs/ext4/ext4.h
++++ linux-3.10.0-1160.45.1.el7/fs/ext4/ext4.h
+@@ -2451,6 +2451,7 @@ extern int ext4_ind_remove_space(handle_
+ /* ioctl.c */
+ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
+ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
++extern int ext4_ioctl_setproject(struct inode *, __u32);
+
+ /* migrate.c */
+ extern int ext4_ext_migrate(struct inode *);
--- /dev/null
+Index: bionic/fs/ext4/ext4.h
+===================================================================
+--- bionic.orig/fs/ext4/ext4.h
++++ bionic/fs/ext4/ext4.h
+@@ -2669,6 +2669,7 @@ extern int ext4_ind_remove_space(handle_
+ /* ioctl.c */
+ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
+ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
++extern int ext4_ioctl_setproject(struct inode *, __u32);
+
+ /* migrate.c */
+ extern int ext4_ext_migrate(struct inode *);
+Index: bionic/fs/ext4/ioctl.c
+===================================================================
+--- bionic.orig/fs/ext4/ioctl.c
++++ bionic/fs/ext4/ioctl.c
+@@ -315,9 +315,8 @@ flags_out:
+ }
+
+ #ifdef CONFIG_QUOTA
+-static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
++int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ {
+- struct inode *inode = file_inode(filp);
+ struct super_block *sb = inode->i_sb;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ int err, rc;
+@@ -344,19 +343,14 @@ static int ext4_ioctl_setproject(struct
+ if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
+ return 0;
+
+- err = mnt_want_write_file(filp);
+- if (err)
+- return err;
+-
+ err = -EPERM;
+- inode_lock(inode);
+ /* Is it quota file? Do not allow user to mess with it */
+ if (ext4_is_quota_file(inode))
+- goto out_unlock;
++ goto out;
+
+ err = ext4_get_inode_loc(inode, &iloc);
+ if (err)
+- goto out_unlock;
++ goto out;
+
+ raw_inode = ext4_raw_inode(&iloc);
+ if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
+@@ -364,7 +358,7 @@ static int ext4_ioctl_setproject(struct
+ EXT4_SB(sb)->s_want_extra_isize,
+ &iloc);
+ if (err)
+- goto out_unlock;
++ goto out;
+ } else {
+ brelse(iloc.bh);
+ }
+@@ -376,7 +370,7 @@ static int ext4_ioctl_setproject(struct
+ EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+ if (IS_ERR(handle)) {
+ err = PTR_ERR(handle);
+- goto out_unlock;
++ goto out;
+ }
+
+ err = ext4_reserve_inode_write(handle, inode, &iloc);
+@@ -405,13 +399,11 @@ out_dirty:
+ err = rc;
+ out_stop:
+ ext4_journal_stop(handle);
+-out_unlock:
+- inode_unlock(inode);
+- mnt_drop_write_file(filp);
++out:
+ return err;
+ }
+ #else
+-static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
++static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ {
+ if (projid != EXT4_DEF_PROJID)
+ return -EOPNOTSUPP;
+@@ -1037,7 +1029,14 @@ resizefs_out:
+ if (err)
+ return err;
+
++ err = mnt_want_write_file(filp);
++ if (err)
++ return err;
++
++ inode_lock(inode);
+ err = ext4_ioctl_setproject(filp, fa.fsx_projid);
++ inode_unlock(inode);
++ mnt_drop_write_file(filp);
+ if (err)
+ return err;
+
+Index: bionic/fs/ext4/xattr.c
+===================================================================
+--- bionic.orig/fs/ext4/xattr.c
++++ bionic/fs/ext4/xattr.c
+@@ -61,6 +61,8 @@
+ #include "xattr.h"
+ #include "acl.h"
+
++#define EXT4_XATTR_PROJID "projid"
++
+ #ifdef EXT4_XATTR_DEBUG
+ # define ea_idebug(inode, fmt, ...) \
+ printk(KERN_DEBUG "inode %s:%lu: " fmt "\n", \
+@@ -644,11 +646,30 @@ ext4_xattr_get(struct inode *inode, int
+ return -ERANGE;
+
+ down_read(&EXT4_I(inode)->xattr_sem);
++ if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
++ strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
++ ext4_has_feature_project(inode->i_sb)) {
++ /* 10 chars to hold u32 in decimal, plus ending \0 */
++ char value[11];
++ __u32 projid = (__u32)from_kprojid(&init_user_ns,
++ EXT4_I(inode)->i_projid);
++ error = snprintf(value, sizeof(value), "%u", projid);
++ if (buffer) {
++ if (error > buffer_size) {
++ error = -ERANGE;
++ goto out;
++ }
++ memcpy(buffer, value, error);
++ }
++ goto out;
++ }
++
+ error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
+ buffer_size);
+ if (error == -ENODATA)
+ error = ext4_xattr_block_get(inode, name_index, name, buffer,
+ buffer_size);
++out:
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
+@@ -773,7 +794,33 @@ ext4_listxattr(struct dentry *dentry, ch
+ ret = ext4_xattr_block_list(dentry, buffer, buffer_size);
+ if (ret < 0)
+ goto errout;
++ if (buffer) {
++ buffer += ret;
++ buffer_size -= ret;
++ }
+ ret += ret2;
++ if (ext4_has_feature_project(dentry->d_sb)) {
++ size_t prefix_len = strlen(XATTR_TRUSTED_PREFIX);
++ size_t name_len = strlen(EXT4_XATTR_PROJID);
++ size_t size = prefix_len + name_len + 1;
++
++ if (__kprojid_val(EXT4_I(dentry->d_inode)->i_projid) ==
++ EXT4_DEF_PROJID)
++ goto errout;
++ if (buffer) {
++ if (size > buffer_size) {
++ ret = -ERANGE;
++ goto errout;
++ }
++ strncpy(buffer, XATTR_TRUSTED_PREFIX, prefix_len);
++ buffer += prefix_len;
++ strncpy(buffer, EXT4_XATTR_PROJID, name_len);
++ buffer += name_len;
++ *buffer++ = 0;
++ buffer_size -= size;
++ }
++ ret += size;
++ }
+ errout:
+ up_read(&EXT4_I(d_inode(dentry))->xattr_sem);
+ return ret;
+@@ -2487,6 +2534,43 @@ ext4_xattr_set(struct inode *inode, int
+ int error, retries = 0;
+ int credits;
+
++ if (name_index == EXT4_XATTR_INDEX_TRUSTED &&
++ strncmp(name, EXT4_XATTR_PROJID, strlen(name)) == 0 &&
++ ext4_has_feature_project(inode->i_sb)) {
++ /* 10 chars to hold u32 in decimal, plus ending \0 */
++ char buffer[11];
++ __u32 projid;
++
++ /*
++ * Project Quota ID state is only allowed to change from within
++ * the init namespace.
++ */
++ if (current_user_ns() != &init_user_ns)
++ return -EINVAL;
++
++ if (value && value_len) {
++ if (value_len >= sizeof(buffer))
++ return -EINVAL;
++ memcpy(buffer, value, value_len);
++ buffer[value_len] = '\0';
++ error = kstrtouint(buffer, 0, &projid);
++ if (error)
++ return error;
++ } else {
++ projid = EXT4_DEF_PROJID;
++ }
++
++ /*
++ * Caller is allowed to change the project ID. If it is being
++ * changed, make sure that the new value is valid.
++ */
++ if (!projid_valid(make_kprojid(&init_user_ns, projid)))
++ return -EINVAL;
++
++ error = ext4_ioctl_setproject(inode, projid);
++ return error;
++ }
++
+ error = dquot_initialize(inode);
+ if (error)
+ return error;
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+rhel7.6/ext4-projid-xattrs.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+rhel7.6/ext4-projid-xattrs.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+rhel7.6/ext4-projid-xattrs.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+rhel7.6/ext4-projid-xattrs.patch
suse15/ext4-export-mb-stream-allocator-variables.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
suse15/ext4-export-mb-stream-allocator-variables.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
suse15/ext4-export-mb-stream-allocator-variables.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
suse15/ext4-export-mb-stream-allocator-variables.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+ubuntu18/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+ubuntu18/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8.3/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8.3/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8.3/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
base/ext4-reset-exts-for-gcc10.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+ubuntu18/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
linux-5.4/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
linux-5.4/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
linux-5.4/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8/ext4-xattr-disable-credits-check.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8.3/ext4-xattr-disable-credits-check.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
rhel8.3/ext4-xattr-disable-credits-check.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
linux-5.9/ext4-simple-blockalloc.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
#define XATTR_NAME_HSM "trusted.hsm"
#define XATTR_NAME_LFSCK_BITMAP "trusted.lfsck_bitmap"
#define XATTR_NAME_DUMMY "trusted.dummy"
+#define XATTR_NAME_PROJID "trusted.projid"
#define LL_XATTR_NAME_ENCRYPTION_CONTEXT XATTR_SECURITY_PREFIX"c"
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
+ struct inode *dir = d_inode(dentry->d_parent);
struct inode *inode = dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
ktime_t kstart = ktime_get();
hide_xattr = true;
}
+ /* Hide virtual project id xattr from the list when
+ * parent has the inherit flag and the same project id,
+ * so project id won't be messed up by copying the xattrs
+ * when mv to a tree with different project id.
+ */
+ if (get_xattr_type(xattr_name)->flags == XATTR_TRUSTED_T &&
+ strcmp(xattr_name, XATTR_NAME_PROJID) == 0) {
+ if (ll_i2info(inode)->lli_projid ==
+ ll_i2info(dir)->lli_projid &&
+ test_bit(LLIF_PROJECT_INHERIT,
+ &ll_i2info(dir)->lli_flags))
+ hide_xattr = true;
+ }
+
len = strnlen(xattr_name, rem - 1) + 1;
rem -= len;
if (!xattr_type_filter(sbi, hide_xattr ? NULL :
else
rc = -ERANGE;
}
+ /* Return the project id when the virtual project id xattr
+ * is explicitly asked.
+ */
+ } else if (strcmp(name, XATTR_NAME_PROJID) == 0) {
+ /* 10 chars to hold u32 in decimal, plus ending \0 */
+ char projid[11];
+
+ rc = snprintf(projid, sizeof(projid),
+ "%u", lli->lli_projid);
+ if (size != 0) {
+ if (rc <= size)
+ memcpy(buffer, projid, rc);
+ else
+ rc = -ERANGE;
+ }
}
} else if (valid & OBD_MD_FLXATTRLS) {
rc = ll_xattr_cache_list(&lli->lli_xattrs,
*/
if (ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID))
lockpart |= MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM;
+ /* Clear xattr cache on clients, so the virtual project ID xattr
+ * can get the new project ID
+ */
+ if (ma->ma_attr.la_valid & LA_PROJID)
+ lockpart |= MDS_INODELOCK_XATTR;
rc = mdt_reint_striped_lock(info, mo, lh, lockpart, einfo,
cos_incompat);
}
run_test 130 "re-register an MDT after writeconf"
+test_131() {
+ [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
+ do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
+ grep -q project || skip "skip project quota not supported"
+
+ local projid
+
+ setupall
+ test_mkdir -c $MDSCOUNT -p $DIR/$tdir
+ $LFS project -p 1000 $DIR/$tdir || error "set dir project id failed"
+ createmany -o $DIR/$tdir/f 512
+ for ((i = 0; i < 512; ++i)); do
+ $LFS project -p $i $DIR/$tdir/f${i} ||
+ error "set f${i} project id failed"
+ done
+
+ test_mkdir -c $MDSCOUNT -p $DIR/$tdir.inherit
+ $LFS project -p 1001 -s $DIR/$tdir.inherit
+ createmany -o $DIR/$tdir.inherit/f 128
+ (( $($LFS project $DIR/$tdir.inherit/f* |
+ awk '$1 == 1001 { print }' | wc -l) == 128 )) ||
+ error "files did not inherit projid 1001"
+
+ stopall
+
+ for i in $(seq $MDSCOUNT); do
+ mds_backup_restore mds$i ||
+ error "Backup/restore on mds$i failed"
+ done
+
+ setupall
+
+ projid=($($LFS project -d $DIR/$tdir))
+ [ ${projid[0]} == "1000" ] ||
+ error "projid expected 1000 not ${projid[0]}"
+ for ((i = 0; i < 512; ++i)); do
+ projid=($($LFS project $DIR/$tdir/f${i}))
+ [ ${projid[0]} == "$i" ] ||
+ error "projid expected $i not ${projid[0]}"
+ done
+
+ (( $($LFS project $DIR/$tdir.inherit/f* |
+ awk '$1 == 1001 { print }' | wc -l) == 128 )) ||
+ error "restore did not copy projid 1001"
+}
+run_test 131 "MDT backup restore with project ID"
+
if ! combined_mgs_mds ; then
stop mgs
fi
}
run_test 903 "Test long page discard does not cause evictions"
+test_904() {
+ [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
+ do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
+ grep -q project || skip "skip project quota not supported"
+
+ local testfile="$DIR/$tdir/$tfile"
+ local xattr="trusted.projid"
+ local projid
+
+ mkdir -p $DIR/$tdir
+ touch $testfile
+ #should be hidden when projid is 0
+ $LFS project -p 0 $testfile ||
+ error "set $testfile project id failed"
+ getfattr -m - $testfile | grep $xattr &&
+ error "do not show trusted.projid with project ID 0"
+
+ #still can getxattr explicitly
+ projid=$(getfattr -n $xattr $testfile |
+ sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
+ [ $projid == "0" ] ||
+ error "projid expected 0 not $projid"
+
+ #set the projid via setxattr
+ setfattr -n $xattr -v "1000" $testfile ||
+ error "setattr failed with $?"
+ projid=($($LFS project $testfile))
+ [ ${projid[0]} == "1000" ] ||
+ error "projid expected 1000 not $projid"
+
+ #check the new projid via getxattr
+ $LFS project -p 1001 $testfile ||
+ error "set $testfile project id failed"
+ projid=$(getfattr -n $xattr $testfile |
+ sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
+ [ $projid == "1001" ] ||
+ error "projid expected 1001 not $projid"
+
+ #try to set invalid projid
+ setfattr -n $xattr -v "4294967295" $testfile &&
+ error "set invalid projid should fail"
+
+ #remove the xattr means setting projid to 0
+ setfattr -x $xattr $testfile ||
+ error "setfattr failed with $?"
+ projid=($($LFS project $testfile))
+ [ ${projid[0]} == "0" ] ||
+ error "projid expected 0 not $projid"
+
+ #should be hidden when parent has inherit flag and same projid
+ $LFS project -srp 1002 $DIR/$tdir ||
+ error "set $tdir project id failed"
+ getfattr -m - $testfile | grep $xattr &&
+ error "do not show trusted.projid with inherit flag"
+
+ #still can getxattr explicitly
+ projid=$(getfattr -n $xattr $testfile |
+ sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
+ [ $projid == "1002" ] ||
+ error "projid expected 1002 not $projid"
+}
+run_test 904 "virtual project ID xattr"
+
complete $SECONDS
[ -f $EXT2_DEV ] && rm $EXT2_DEV || true
check_and_cleanup_lustre
local devname=$(mdsdevname $(facet_number $facet))
local mntpt=$(facet_mntpt brpt)
local rcmd="do_facet $facet"
- local metaea=${TMP}/backup_restore.ea
local metadata=${TMP}/backup_restore.tgz
local opts=${MDS_MOUNT_FS_OPTS}
local svc=${facet}_svc
# step 1: build mount point
${rcmd} mkdir -p $mntpt
# step 2: cleanup old backup
- ${rcmd} rm -f $metaea $metadata
+ ${rcmd} rm -f $metadata
# step 3: mount dev
- ${rcmd} mount -t ldiskfs $opts $devname $mntpt || return 1
+ ${rcmd} mount -t ldiskfs $opts $devname $mntpt || return 3
if [ ! -z $igif ]; then
# step 3.5: rm .lustre
- ${rcmd} rm -rf $mntpt/ROOT/.lustre || return 1
+ ${rcmd} rm -rf $mntpt/ROOT/.lustre || return 3
fi
- # step 4: backup metaea
- echo "backup EA"
- ${rcmd} "cd $mntpt && getfattr -R -d -m '.*' -P . > $metaea && cd -" ||
- return 2
- # step 5: backup metadata
+ # step 4: backup metadata
echo "backup data"
- ${rcmd} tar zcf $metadata -C $mntpt/ . > /dev/null 2>&1 || return 3
- # step 6: umount
- ${rcmd} $UMOUNT $mntpt || return 4
- # step 8: reformat dev
+ ${rcmd} tar zcf $metadata --xattrs --xattrs-include="trusted.*" \
+ --sparse -C $mntpt/ . > /dev/null 2>&1 || return 4
+ # step 5: umount
+ ${rcmd} $UMOUNT $mntpt || return 5
+ # step 6: reformat dev
echo "reformat new device"
format_mdt $(facet_number $facet)
- # step 9: mount dev
+ # step 7: mount dev
${rcmd} mount -t ldiskfs $opts $devname $mntpt || return 7
- # step 10: restore metadata
+ # step 8: restore metadata
echo "restore data"
- ${rcmd} tar zxfp $metadata -C $mntpt > /dev/null 2>&1 || return 8
- # step 11: restore metaea
- echo "restore EA"
- ${rcmd} "cd $mntpt && setfattr --restore=$metaea && cd - " || return 9
- # step 12: remove recovery logs
+ ${rcmd} tar zxfp $metadata --xattrs --xattrs-include="trusted.*" \
+ --sparse -C $mntpt > /dev/null 2>&1 || return 8
+ # step 9: remove recovery logs
echo "remove recovery logs"
${rcmd} rm -fv $mntpt/OBJECTS/* $mntpt/CATALOGS
- # step 13: umount dev
+ # step 10: umount dev
${rcmd} $UMOUNT $mntpt || return 10
- # step 14: cleanup tmp backup
+ # step 11: cleanup tmp backup
${rcmd} rm -f $metaea $metadata
- # step 15: reset device label - it's not virgin on
+ # step 12: reset device label - it's not virgin on
${rcmd} e2label $devname ${!svc}
}