|
@@ -4193,6 +4193,14 @@ static inline void ext4_iget_extra_inode(struct inode *inode,
|
|
|
EXT4_I(inode)->i_inline_off = 0;
|
|
|
}
|
|
|
|
|
|
+int ext4_get_projid(struct inode *inode, kprojid_t *projid)
|
|
|
+{
|
|
|
+ if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ *projid = EXT4_I(inode)->i_projid;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
|
|
{
|
|
|
struct ext4_iloc iloc;
|
|
@@ -4204,6 +4212,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
|
|
int block;
|
|
|
uid_t i_uid;
|
|
|
gid_t i_gid;
|
|
|
+ projid_t i_projid;
|
|
|
|
|
|
inode = iget_locked(sb, ino);
|
|
|
if (!inode)
|
|
@@ -4253,12 +4262,20 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
|
|
inode->i_mode = le16_to_cpu(raw_inode->i_mode);
|
|
|
i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
|
|
|
i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
|
|
|
+ if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
|
|
|
+ EXT4_INODE_SIZE(sb) > EXT4_GOOD_OLD_INODE_SIZE &&
|
|
|
+ EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))
|
|
|
+ i_projid = (projid_t)le32_to_cpu(raw_inode->i_projid);
|
|
|
+ else
|
|
|
+ i_projid = EXT4_DEF_PROJID;
|
|
|
+
|
|
|
if (!(test_opt(inode->i_sb, NO_UID32))) {
|
|
|
i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
|
|
|
i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
|
|
|
}
|
|
|
i_uid_write(inode, i_uid);
|
|
|
i_gid_write(inode, i_gid);
|
|
|
+ ei->i_projid = make_kprojid(&init_user_ns, i_projid);
|
|
|
set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
|
|
|
|
|
|
ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */
|
|
@@ -4556,6 +4573,7 @@ static int ext4_do_update_inode(handle_t *handle,
|
|
|
int need_datasync = 0, set_large_file = 0;
|
|
|
uid_t i_uid;
|
|
|
gid_t i_gid;
|
|
|
+ projid_t i_projid;
|
|
|
|
|
|
spin_lock(&ei->i_raw_lock);
|
|
|
|
|
@@ -4568,6 +4586,7 @@ static int ext4_do_update_inode(handle_t *handle,
|
|
|
raw_inode->i_mode = cpu_to_le16(inode->i_mode);
|
|
|
i_uid = i_uid_read(inode);
|
|
|
i_gid = i_gid_read(inode);
|
|
|
+ i_projid = from_kprojid(&init_user_ns, ei->i_projid);
|
|
|
if (!(test_opt(inode->i_sb, NO_UID32))) {
|
|
|
raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
|
|
|
raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
|
|
@@ -4645,6 +4664,15 @@ static int ext4_do_update_inode(handle_t *handle,
|
|
|
cpu_to_le16(ei->i_extra_isize);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
|
|
|
+ EXT4_FEATURE_RO_COMPAT_PROJECT) &&
|
|
|
+ i_projid != EXT4_DEF_PROJID);
|
|
|
+
|
|
|
+ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
|
|
|
+ EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))
|
|
|
+ raw_inode->i_projid = cpu_to_le32(i_projid);
|
|
|
+
|
|
|
ext4_inode_csum_set(inode, raw_inode, ei);
|
|
|
spin_unlock(&ei->i_raw_lock);
|
|
|
if (inode->i_sb->s_flags & MS_LAZYTIME)
|