+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 *);