From 8c8f4920e0157b2f1617b7d6da3f758781d68642 Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Fri, 26 Jan 2018 15:26:00 +0800 Subject: [PATCH] LU-9724 ldiskfs: update ext4-large-eas.patch to match upstream ext4 In order to match the enhanced ea_inode functionality being landed to the upstream ext4 kernel tree, ext4-large-eas.patch is modified to start properly initializing some of the fields we don't currently use to minimize the interoperability issues. In particular, the new EA inode refcount is initialized to 1, and hash field is computed based on the xattr value as it is in the upstream kernel patch. However, since ext4_xattr_inode_get_hash() has not been added to ldiskfs code so that this hash value is not used anywhere, if the new checksum driver (sbi->s_chksum_driver) is not available, hash value will be 0 in the current implementation, until we find a way to calculate it based on the xattr value propely. Signed-off-by: Emoly Liu Change-Id: I2bcf45c67a580f2f545816e1a70a6322c6ccc368 Reviewed-on: https://review.whamcloud.com/31033 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Fan Yong Reviewed-by: Yang Sheng Reviewed-by: Andreas Dilger --- .../patches/rhel7.2/ext4-large-eas.patch | 72 ++++++++++++++-------- .../patches/rhel7/ext4-large-eas.patch | 72 ++++++++++++++-------- .../patches/sles12/ext4-large-eas.patch | 72 ++++++++++++++-------- .../patches/sles12sp2/ext4-large-eas.patch | 72 ++++++++++++++-------- 4 files changed, 192 insertions(+), 96 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch b/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch index 3b05c6e..afe5447 100644 --- a/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch +++ b/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch @@ -366,7 +366,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < *min_offs) *min_offs = offs; -@@ -611,16 +728,174 @@ static size_t ext4_xattr_free_space(stru +@@ -611,16 +728,198 @@ static size_t ext4_xattr_free_space(stru return (*min_offs - ((void *)last - base) - sizeof(__u32)); } @@ -443,11 +443,22 @@ Index: linux-stage/fs/ext4/xattr.c + return ret; +} + ++static void ext4_xattr_inode_set_ref(struct inode *ea_inode, __u64 ref_count) ++{ ++ ea_inode->i_ctime.tv_sec = (__u32)(ref_count >> 32); ++ ea_inode->i_version = (__u32)ref_count; ++} ++ ++static void ext4_xattr_inode_set_hash(struct inode *ea_inode, __u32 hash) ++{ ++ ea_inode->i_atime.tv_sec = hash; ++} ++ +/* + * Create an inode to store the value of a large EA. + */ +static struct inode * -+ext4_xattr_inode_create(handle_t *handle, struct inode *inode) ++ext4_xattr_inode_create(handle_t *handle, struct inode *inode, __u32 hash) +{ + struct inode *ea_inode = NULL; + @@ -471,6 +482,9 @@ Index: linux-stage/fs/ext4/xattr.c + */ + EXT4_XATTR_INODE_SET_PARENT(ea_inode, inode->i_ino); + unlock_new_inode(ea_inode); ++ ++ ext4_xattr_inode_set_ref(ea_inode, 1); ++ ext4_xattr_inode_set_hash(ea_inode, hash); + } + + return ea_inode; @@ -495,6 +509,14 @@ Index: linux-stage/fs/ext4/xattr.c + return 0; +} + ++static __u32 ++ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size) ++{ ++ if (ext4_has_metadata_csum(sbi->s_sb)) ++ return ext4_chksum(sbi, sbi->s_csum_seed, buffer, size); ++ return 0; ++} ++ +/* + * Add value of the EA in an inode. + */ @@ -503,10 +525,12 @@ Index: linux-stage/fs/ext4/xattr.c + const void *value, size_t value_len) +{ + struct inode *ea_inode = NULL; ++ __u32 hash; + int err; + + /* Create an inode for the EA value */ -+ ea_inode = ext4_xattr_inode_create(handle, inode); ++ hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len); ++ ea_inode = ext4_xattr_inode_create(handle, inode, hash); + if (IS_ERR(ea_inode)) + return -1; + @@ -543,7 +567,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < min_offs) min_offs = offs; -@@ -628,15 +903,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -628,15 +927,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i } free = min_offs - ((void *)last - s->base) - sizeof(__u32); if (!s->not_found) { @@ -568,7 +592,7 @@ Index: linux-stage/fs/ext4/xattr.c return -ENOSPC; } -@@ -651,7 +931,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -651,7 +955,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i s->here->e_name_len = name_len; memcpy(s->here->e_name, i->name, name_len); } else { @@ -578,7 +602,7 @@ Index: linux-stage/fs/ext4/xattr.c void *first_val = s->base + min_offs; size_t offs = le16_to_cpu(s->here->e_value_offs); void *val = s->base + offs; -@@ -685,13 +966,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -685,13 +990,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i last = s->first; while (!IS_LAST_ENTRY(last)) { size_t o = le16_to_cpu(last->e_value_offs); @@ -598,7 +622,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!i->value) { /* Remove the old name. */ size_t size = EXT4_XATTR_LEN(name_len); -@@ -705,10 +990,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -705,10 +1014,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i if (i->value) { /* Insert the new value. */ s->here->e_value_size = cpu_to_le32(i->value_len); @@ -617,7 +641,7 @@ Index: linux-stage/fs/ext4/xattr.c if (i->value == EXT4_ZERO_XATTR_VALUE) { memset(val, 0, size); } else { -@@ -758,7 +1050,7 @@ ext4_xattr_block_find(struct inode *inod +@@ -758,7 +1074,7 @@ ext4_xattr_block_find(struct inode *inod bs->s.end = bs->bh->b_data + bs->bh->b_size; bs->s.here = bs->s.first; error = ext4_xattr_find_entry(&bs->s.here, i->name_index, @@ -626,7 +650,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; -@@ -782,8 +1074,6 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -782,8 +1098,6 @@ ext4_xattr_block_set(handle_t *handle, s #define header(x) ((struct ext4_xattr_header *)(x)) @@ -635,7 +659,7 @@ Index: linux-stage/fs/ext4/xattr.c if (s->base) { ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, bs->bh->b_blocknr); -@@ -799,7 +1089,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -799,7 +1113,7 @@ ext4_xattr_block_set(handle_t *handle, s ce = NULL; } ea_bdebug(bs->bh, "modifying in-place"); @@ -644,7 +668,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!error) { if (!IS_LAST_ENTRY(s->first)) ext4_xattr_rehash(header(s->base), -@@ -850,7 +1140,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -850,7 +1164,7 @@ ext4_xattr_block_set(handle_t *handle, s s->end = s->base + sb->s_blocksize; } @@ -653,7 +677,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error == -EIO) goto bad_block; if (error) -@@ -1000,7 +1290,7 @@ int ext4_xattr_ibody_find(struct inode * +@@ -1000,7 +1314,7 @@ int ext4_xattr_ibody_find(struct inode * /* Find the named attribute. */ error = ext4_xattr_find_entry(&is->s.here, i->name_index, i->name, is->s.end - @@ -662,7 +686,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) return error; is->s.not_found = error; -@@ -1018,7 +1308,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1018,7 +1332,7 @@ int ext4_xattr_ibody_inline_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -671,7 +695,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) { if (error == -ENOSPC && ext4_has_inline_data(inode)) { -@@ -1030,7 +1320,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1030,7 +1344,7 @@ int ext4_xattr_ibody_inline_set(handle_t error = ext4_xattr_ibody_find(inode, i, is); if (error) return error; @@ -680,7 +704,7 @@ Index: linux-stage/fs/ext4/xattr.c } if (error) return error; -@@ -1056,7 +1346,7 @@ static int ext4_xattr_ibody_set(handle_t +@@ -1056,7 +1370,7 @@ static int ext4_xattr_ibody_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -689,7 +713,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) return error; header = IHDR(inode, ext4_raw_inode(&is->iloc)); -@@ -1092,7 +1382,7 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1092,7 +1406,7 @@ ext4_xattr_set_handle(handle_t *handle, .name = name, .value = value, .value_len = value_len, @@ -698,7 +722,7 @@ Index: linux-stage/fs/ext4/xattr.c }; struct ext4_xattr_ibody_find is = { .s = { .not_found = -ENODATA, }, -@@ -1157,6 +1447,15 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1157,6 +1471,15 @@ ext4_xattr_set_handle(handle_t *handle, goto cleanup; } error = ext4_xattr_block_set(handle, inode, &i, &bs); @@ -714,7 +738,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) goto cleanup; if (!is.s.not_found) { -@@ -1203,9 +1502,22 @@ ext4_xattr_set(struct inode *inode, int +@@ -1203,9 +1526,22 @@ ext4_xattr_set(struct inode *inode, int const void *value, size_t value_len, int flags) { handle_t *handle; @@ -737,7 +761,7 @@ Index: linux-stage/fs/ext4/xattr.c retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits); if (IS_ERR(handle)) { -@@ -1217,7 +1529,7 @@ retry: +@@ -1217,7 +1553,7 @@ retry: value, value_len, flags); error2 = ext4_journal_stop(handle); if (error == -ENOSPC && @@ -746,7 +770,7 @@ Index: linux-stage/fs/ext4/xattr.c goto retry; if (error == 0) error = error2; -@@ -1239,7 +1551,7 @@ static void ext4_xattr_shift_entries(str +@@ -1239,7 +1575,7 @@ static void ext4_xattr_shift_entries(str /* Adjust the value offsets of the entries */ for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { @@ -755,7 +779,7 @@ Index: linux-stage/fs/ext4/xattr.c new_offs = le16_to_cpu(last->e_value_offs) + value_offs_shift; BUG_ON(new_offs + le32_to_cpu(last->e_value_size) -@@ -1477,21 +1789,135 @@ cleanup: +@@ -1477,21 +1813,135 @@ cleanup: } @@ -896,7 +920,7 @@ Index: linux-stage/fs/ext4/xattr.c bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); if (!bh) { EXT4_ERROR_INODE(inode, "block %llu read error", -@@ -1504,11 +1930,69 @@ ext4_xattr_delete_inode(handle_t *handle +@@ -1504,11 +1954,69 @@ ext4_xattr_delete_inode(handle_t *handle EXT4_I(inode)->i_file_acl); goto cleanup; } @@ -966,7 +990,7 @@ Index: linux-stage/fs/ext4/xattr.c } /* -@@ -1578,10 +2062,9 @@ ext4_xattr_cmp(struct ext4_xattr_header +@@ -1578,10 +2086,9 @@ ext4_xattr_cmp(struct ext4_xattr_header entry1->e_name_index != entry2->e_name_index || entry1->e_name_len != entry2->e_name_len || entry1->e_value_size != entry2->e_value_size || @@ -978,7 +1002,7 @@ Index: linux-stage/fs/ext4/xattr.c if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), (char *)header2 + le16_to_cpu(entry2->e_value_offs), le32_to_cpu(entry1->e_value_size))) -@@ -1665,7 +2148,7 @@ static inline void ext4_xattr_hash_entry +@@ -1665,7 +2172,7 @@ static inline void ext4_xattr_hash_entry *name++; } diff --git a/ldiskfs/kernel_patches/patches/rhel7/ext4-large-eas.patch b/ldiskfs/kernel_patches/patches/rhel7/ext4-large-eas.patch index 20d5b1e..bc87ecc 100644 --- a/ldiskfs/kernel_patches/patches/rhel7/ext4-large-eas.patch +++ b/ldiskfs/kernel_patches/patches/rhel7/ext4-large-eas.patch @@ -369,7 +369,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < *min_offs) *min_offs = offs; -@@ -611,16 +728,174 @@ static size_t ext4_xattr_free_space(stru +@@ -611,16 +728,198 @@ static size_t ext4_xattr_free_space(stru return (*min_offs - ((void *)last - base) - sizeof(__u32)); } @@ -446,11 +446,22 @@ Index: linux-stage/fs/ext4/xattr.c + return ret; +} + ++static void ext4_xattr_inode_set_ref(struct inode *ea_inode, __u64 ref_count) ++{ ++ ea_inode->i_ctime.tv_sec = (__u32)(ref_count >> 32); ++ ea_inode->i_version = (__u32)ref_count; ++} ++ ++static void ext4_xattr_inode_set_hash(struct inode *ea_inode, __u32 hash) ++{ ++ ea_inode->i_atime.tv_sec = hash; ++} ++ +/* + * Create an inode to store the value of a large EA. + */ +static struct inode * -+ext4_xattr_inode_create(handle_t *handle, struct inode *inode) ++ext4_xattr_inode_create(handle_t *handle, struct inode *inode, __u32 hash) +{ + struct inode *ea_inode = NULL; + @@ -474,6 +485,9 @@ Index: linux-stage/fs/ext4/xattr.c + */ + EXT4_XATTR_INODE_SET_PARENT(ea_inode, inode->i_ino); + unlock_new_inode(ea_inode); ++ ++ ext4_xattr_inode_set_ref(ea_inode, 1); ++ ext4_xattr_inode_set_hash(ea_inode, hash); + } + + return ea_inode; @@ -498,6 +512,14 @@ Index: linux-stage/fs/ext4/xattr.c + return 0; +} + ++static __u32 ++ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size) ++{ ++ if (ext4_has_metadata_csum(sbi->s_sb)) ++ return ext4_chksum(sbi, sbi->s_csum_seed, buffer, size); ++ return 0; ++} ++ +/* + * Add value of the EA in an inode. + */ @@ -506,10 +528,12 @@ Index: linux-stage/fs/ext4/xattr.c + const void *value, size_t value_len) +{ + struct inode *ea_inode = NULL; ++ __u32 hash; + int err; + + /* Create an inode for the EA value */ -+ ea_inode = ext4_xattr_inode_create(handle, inode); ++ hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len); ++ ea_inode = ext4_xattr_inode_create(handle, inode, hash); + if (IS_ERR(ea_inode)) + return -1; + @@ -546,7 +570,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < min_offs) min_offs = offs; -@@ -628,16 +903,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -628,16 +927,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i } free = min_offs - ((void *)last - s->base) - sizeof(__u32); if (!s->not_found) { @@ -572,7 +596,7 @@ Index: linux-stage/fs/ext4/xattr.c return -ENOSPC; } -@@ -651,7 +931,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -651,7 +955,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i s->here->e_name_len = name_len; memcpy(s->here->e_name, i->name, name_len); } else { @@ -582,7 +606,7 @@ Index: linux-stage/fs/ext4/xattr.c void *first_val = s->base + min_offs; size_t offs = le16_to_cpu(s->here->e_value_offs); void *val = s->base + offs; -@@ -685,13 +966,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -685,13 +990,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i last = s->first; while (!IS_LAST_ENTRY(last)) { size_t o = le16_to_cpu(last->e_value_offs); @@ -602,7 +626,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!i->value) { /* Remove the old name. */ size_t size = EXT4_XATTR_LEN(name_len); -@@ -705,10 +990,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -705,10 +1014,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i if (i->value) { /* Insert the new value. */ s->here->e_value_size = cpu_to_le32(i->value_len); @@ -621,7 +645,7 @@ Index: linux-stage/fs/ext4/xattr.c if (i->value == EXT4_ZERO_XATTR_VALUE) { memset(val, 0, size); } else { -@@ -758,7 +1050,7 @@ ext4_xattr_block_find(struct inode *inod +@@ -758,7 +1074,7 @@ ext4_xattr_block_find(struct inode *inod bs->s.end = bs->bh->b_data + bs->bh->b_size; bs->s.here = bs->s.first; error = ext4_xattr_find_entry(&bs->s.here, i->name_index, @@ -630,7 +654,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; -@@ -782,8 +1074,6 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -782,8 +1098,6 @@ ext4_xattr_block_set(handle_t *handle, s #define header(x) ((struct ext4_xattr_header *)(x)) @@ -639,7 +663,7 @@ Index: linux-stage/fs/ext4/xattr.c if (s->base) { ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, bs->bh->b_blocknr); -@@ -799,7 +1089,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -799,7 +1113,7 @@ ext4_xattr_block_set(handle_t *handle, s ce = NULL; } ea_bdebug(bs->bh, "modifying in-place"); @@ -648,7 +672,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!error) { if (!IS_LAST_ENTRY(s->first)) ext4_xattr_rehash(header(s->base), -@@ -850,7 +1140,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -850,7 +1164,7 @@ ext4_xattr_block_set(handle_t *handle, s s->end = s->base + sb->s_blocksize; } @@ -657,7 +681,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error == -EIO) goto bad_block; if (error) -@@ -1000,7 +1290,7 @@ int ext4_xattr_ibody_find(struct inode * +@@ -1000,7 +1314,7 @@ int ext4_xattr_ibody_find(struct inode * /* Find the named attribute. */ error = ext4_xattr_find_entry(&is->s.here, i->name_index, i->name, is->s.end - @@ -666,7 +690,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) return error; is->s.not_found = error; -@@ -1018,7 +1308,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1018,7 +1332,7 @@ int ext4_xattr_ibody_inline_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -675,7 +699,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) { if (error == -ENOSPC && ext4_has_inline_data(inode)) { -@@ -1030,7 +1320,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1030,7 +1344,7 @@ int ext4_xattr_ibody_inline_set(handle_t error = ext4_xattr_ibody_find(inode, i, is); if (error) return error; @@ -684,7 +708,7 @@ Index: linux-stage/fs/ext4/xattr.c } if (error) return error; -@@ -1056,7 +1346,7 @@ static int ext4_xattr_ibody_set(handle_t +@@ -1056,7 +1370,7 @@ static int ext4_xattr_ibody_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -693,7 +717,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) return error; header = IHDR(inode, ext4_raw_inode(&is->iloc)); -@@ -1092,7 +1382,7 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1092,7 +1406,7 @@ ext4_xattr_set_handle(handle_t *handle, .name = name, .value = value, .value_len = value_len, @@ -702,7 +726,7 @@ Index: linux-stage/fs/ext4/xattr.c }; struct ext4_xattr_ibody_find is = { .s = { .not_found = -ENODATA, }, -@@ -1157,6 +1447,15 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1157,6 +1471,15 @@ ext4_xattr_set_handle(handle_t *handle, goto cleanup; } error = ext4_xattr_block_set(handle, inode, &i, &bs); @@ -718,7 +742,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) goto cleanup; if (!is.s.not_found) { -@@ -1203,9 +1502,22 @@ ext4_xattr_set(struct inode *inode, int +@@ -1203,9 +1526,22 @@ ext4_xattr_set(struct inode *inode, int const void *value, size_t value_len, int flags) { handle_t *handle; @@ -741,7 +765,7 @@ Index: linux-stage/fs/ext4/xattr.c retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits); if (IS_ERR(handle)) { -@@ -1217,7 +1529,7 @@ retry: +@@ -1217,7 +1553,7 @@ retry: value, value_len, flags); error2 = ext4_journal_stop(handle); if (error == -ENOSPC && @@ -750,7 +774,7 @@ Index: linux-stage/fs/ext4/xattr.c goto retry; if (error == 0) error = error2; -@@ -1239,7 +1551,7 @@ static void ext4_xattr_shift_entries(str +@@ -1239,7 +1575,7 @@ static void ext4_xattr_shift_entries(str /* Adjust the value offsets of the entries */ for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { @@ -759,7 +783,7 @@ Index: linux-stage/fs/ext4/xattr.c new_offs = le16_to_cpu(last->e_value_offs) + value_offs_shift; BUG_ON(new_offs + le32_to_cpu(last->e_value_size) -@@ -1477,21 +1789,135 @@ cleanup: +@@ -1477,21 +1813,135 @@ cleanup: } @@ -900,7 +924,7 @@ Index: linux-stage/fs/ext4/xattr.c bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); if (!bh) { EXT4_ERROR_INODE(inode, "block %llu read error", -@@ -1504,11 +1930,69 @@ ext4_xattr_delete_inode(handle_t *handle +@@ -1504,11 +1954,69 @@ ext4_xattr_delete_inode(handle_t *handle EXT4_I(inode)->i_file_acl); goto cleanup; } @@ -970,7 +994,7 @@ Index: linux-stage/fs/ext4/xattr.c } /* -@@ -1578,10 +2062,9 @@ ext4_xattr_cmp(struct ext4_xattr_header +@@ -1578,10 +2086,9 @@ ext4_xattr_cmp(struct ext4_xattr_header entry1->e_name_index != entry2->e_name_index || entry1->e_name_len != entry2->e_name_len || entry1->e_value_size != entry2->e_value_size || @@ -982,7 +1006,7 @@ Index: linux-stage/fs/ext4/xattr.c if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), (char *)header2 + le16_to_cpu(entry2->e_value_offs), le32_to_cpu(entry1->e_value_size))) -@@ -1665,7 +2148,7 @@ static inline void ext4_xattr_hash_entry +@@ -1665,7 +2172,7 @@ static inline void ext4_xattr_hash_entry *name++; } diff --git a/ldiskfs/kernel_patches/patches/sles12/ext4-large-eas.patch b/ldiskfs/kernel_patches/patches/sles12/ext4-large-eas.patch index 2820da2..8430ef1 100644 --- a/ldiskfs/kernel_patches/patches/sles12/ext4-large-eas.patch +++ b/ldiskfs/kernel_patches/patches/sles12/ext4-large-eas.patch @@ -366,7 +366,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < *min_offs) *min_offs = offs; -@@ -606,16 +722,172 @@ static size_t ext4_xattr_free_space(stru +@@ -606,16 +722,196 @@ static size_t ext4_xattr_free_space(stru return (*min_offs - ((void *)last - base) - sizeof(__u32)); } @@ -441,11 +441,22 @@ Index: linux-stage/fs/ext4/xattr.c + return ret; +} + ++static void ext4_xattr_inode_set_ref(struct inode *ea_inode, __u64 ref_count) ++{ ++ ea_inode->i_ctime.tv_sec = (__u32)(ref_count >> 32); ++ ea_inode->i_version = (__u32)ref_count; ++} ++ ++static void ext4_xattr_inode_set_hash(struct inode *ea_inode, __u32 hash) ++{ ++ ea_inode->i_atime.tv_sec = hash; ++} ++ +/* + * Create an inode to store the value of a large EA. + */ +static struct inode * -+ext4_xattr_inode_create(handle_t *handle, struct inode *inode) ++ext4_xattr_inode_create(handle_t *handle, struct inode *inode, __u32 hash) +{ + struct inode *ea_inode = NULL; + @@ -469,6 +480,9 @@ Index: linux-stage/fs/ext4/xattr.c + */ + EXT4_XATTR_INODE_SET_PARENT(ea_inode, inode->i_ino); + unlock_new_inode(ea_inode); ++ ++ ext4_xattr_inode_set_ref(ea_inode, 1); ++ ext4_xattr_inode_set_hash(ea_inode, hash); + } + + return ea_inode; @@ -493,6 +507,14 @@ Index: linux-stage/fs/ext4/xattr.c + return 0; +} + ++static __u32 ++ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size) ++{ ++ if (ext4_has_metadata_csum(sbi->s_sb)) ++ return ext4_chksum(sbi, sbi->s_csum_seed, buffer, size); ++ return 0; ++} ++ +/* + * Add value of the EA in an inode. + */ @@ -501,10 +523,12 @@ Index: linux-stage/fs/ext4/xattr.c + const void *value, size_t value_len) +{ + struct inode *ea_inode = NULL; ++ __u32 hash; + int err; + + /* Create an inode for the EA value */ -+ ea_inode = ext4_xattr_inode_create(handle, inode); ++ hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len); ++ ea_inode = ext4_xattr_inode_create(handle, inode, hash); + if (IS_ERR(ea_inode)) + return -1; + @@ -541,7 +565,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < min_offs) min_offs = offs; -@@ -623,16 +895,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -623,16 +919,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i } free = min_offs - ((void *)last - s->base) - sizeof(__u32); if (!s->not_found) { @@ -567,7 +591,7 @@ Index: linux-stage/fs/ext4/xattr.c return -ENOSPC; } -@@ -646,7 +923,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -646,7 +947,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i s->here->e_name_len = name_len; memcpy(s->here->e_name, i->name, name_len); } else { @@ -577,7 +601,7 @@ Index: linux-stage/fs/ext4/xattr.c void *first_val = s->base + min_offs; size_t offs = le16_to_cpu(s->here->e_value_offs); void *val = s->base + offs; -@@ -680,13 +958,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -680,13 +982,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i last = s->first; while (!IS_LAST_ENTRY(last)) { size_t o = le16_to_cpu(last->e_value_offs); @@ -597,7 +621,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!i->value) { /* Remove the old name. */ size_t size = EXT4_XATTR_LEN(name_len); -@@ -700,10 +982,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -700,10 +1006,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i if (i->value) { /* Insert the new value. */ s->here->e_value_size = cpu_to_le32(i->value_len); @@ -616,7 +640,7 @@ Index: linux-stage/fs/ext4/xattr.c if (i->value == EXT4_ZERO_XATTR_VALUE) { memset(val, 0, size); } else { -@@ -753,7 +1042,7 @@ ext4_xattr_block_find(struct inode *inod +@@ -753,7 +1066,7 @@ ext4_xattr_block_find(struct inode *inod bs->s.end = bs->bh->b_data + bs->bh->b_size; bs->s.here = bs->s.first; error = ext4_xattr_find_entry(&bs->s.here, i->name_index, @@ -625,7 +649,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; -@@ -777,8 +1066,6 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -777,8 +1090,6 @@ ext4_xattr_block_set(handle_t *handle, s #define header(x) ((struct ext4_xattr_header *)(x)) @@ -634,7 +658,7 @@ Index: linux-stage/fs/ext4/xattr.c if (s->base) { ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, bs->bh->b_blocknr); -@@ -794,7 +1081,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -794,7 +1105,7 @@ ext4_xattr_block_set(handle_t *handle, s ce = NULL; } ea_bdebug(bs->bh, "modifying in-place"); @@ -643,7 +667,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!error) { if (!IS_LAST_ENTRY(s->first)) ext4_xattr_rehash(header(s->base), -@@ -845,7 +1132,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -845,7 +1156,7 @@ ext4_xattr_block_set(handle_t *handle, s s->end = s->base + sb->s_blocksize; } @@ -652,7 +676,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error == -EIO) goto bad_block; if (error) -@@ -994,7 +1281,7 @@ int ext4_xattr_ibody_find(struct inode * +@@ -994,7 +1305,7 @@ int ext4_xattr_ibody_find(struct inode * /* Find the named attribute. */ error = ext4_xattr_find_entry(&is->s.here, i->name_index, i->name, is->s.end - @@ -661,7 +685,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) return error; is->s.not_found = error; -@@ -1012,7 +1299,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1012,7 +1323,7 @@ int ext4_xattr_ibody_inline_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -670,7 +694,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) { if (error == -ENOSPC && ext4_has_inline_data(inode)) { -@@ -1024,7 +1311,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1024,7 +1335,7 @@ int ext4_xattr_ibody_inline_set(handle_t error = ext4_xattr_ibody_find(inode, i, is); if (error) return error; @@ -679,7 +703,7 @@ Index: linux-stage/fs/ext4/xattr.c } if (error) return error; -@@ -1050,7 +1337,7 @@ static int ext4_xattr_ibody_set(handle_t +@@ -1050,7 +1361,7 @@ static int ext4_xattr_ibody_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -688,7 +712,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) return error; header = IHDR(inode, ext4_raw_inode(&is->iloc)); -@@ -1086,7 +1373,7 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1086,7 +1397,7 @@ ext4_xattr_set_handle(handle_t *handle, .name = name, .value = value, .value_len = value_len, @@ -697,7 +721,7 @@ Index: linux-stage/fs/ext4/xattr.c }; struct ext4_xattr_ibody_find is = { .s = { .not_found = -ENODATA, }, -@@ -1151,6 +1438,15 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1151,6 +1462,15 @@ ext4_xattr_set_handle(handle_t *handle, goto cleanup; } error = ext4_xattr_block_set(handle, inode, &i, &bs); @@ -713,7 +737,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) goto cleanup; if (!is.s.not_found) { -@@ -1197,9 +1493,22 @@ ext4_xattr_set(struct inode *inode, int +@@ -1197,9 +1517,22 @@ ext4_xattr_set(struct inode *inode, int const void *value, size_t value_len, int flags) { handle_t *handle; @@ -736,7 +760,7 @@ Index: linux-stage/fs/ext4/xattr.c retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits); if (IS_ERR(handle)) { -@@ -1211,7 +1520,7 @@ retry: +@@ -1211,7 +1544,7 @@ retry: value, value_len, flags); error2 = ext4_journal_stop(handle); if (error == -ENOSPC && @@ -745,7 +769,7 @@ Index: linux-stage/fs/ext4/xattr.c goto retry; if (error == 0) error = error2; -@@ -1233,7 +1542,7 @@ static void ext4_xattr_shift_entries(str +@@ -1233,7 +1566,7 @@ static void ext4_xattr_shift_entries(str /* Adjust the value offsets of the entries */ for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { @@ -754,7 +778,7 @@ Index: linux-stage/fs/ext4/xattr.c new_offs = le16_to_cpu(last->e_value_offs) + value_offs_shift; BUG_ON(new_offs + le32_to_cpu(last->e_value_size) -@@ -1472,21 +1781,135 @@ cleanup: +@@ -1472,21 +1805,135 @@ cleanup: } @@ -895,7 +919,7 @@ Index: linux-stage/fs/ext4/xattr.c bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); if (!bh) { EXT4_ERROR_INODE(inode, "block %llu read error", -@@ -1499,11 +1922,69 @@ ext4_xattr_delete_inode(handle_t *handle +@@ -1499,11 +1946,69 @@ ext4_xattr_delete_inode(handle_t *handle EXT4_I(inode)->i_file_acl); goto cleanup; } @@ -965,7 +989,7 @@ Index: linux-stage/fs/ext4/xattr.c } /* -@@ -1573,10 +2054,9 @@ ext4_xattr_cmp(struct ext4_xattr_header +@@ -1573,10 +2078,9 @@ ext4_xattr_cmp(struct ext4_xattr_header entry1->e_name_index != entry2->e_name_index || entry1->e_name_len != entry2->e_name_len || entry1->e_value_size != entry2->e_value_size || @@ -977,7 +1001,7 @@ Index: linux-stage/fs/ext4/xattr.c if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), (char *)header2 + le16_to_cpu(entry2->e_value_offs), le32_to_cpu(entry1->e_value_size))) -@@ -1660,7 +2140,7 @@ static inline void ext4_xattr_hash_entry +@@ -1660,7 +2164,7 @@ static inline void ext4_xattr_hash_entry *name++; } diff --git a/ldiskfs/kernel_patches/patches/sles12sp2/ext4-large-eas.patch b/ldiskfs/kernel_patches/patches/sles12sp2/ext4-large-eas.patch index 962512e..851e45f 100644 --- a/ldiskfs/kernel_patches/patches/sles12sp2/ext4-large-eas.patch +++ b/ldiskfs/kernel_patches/patches/sles12sp2/ext4-large-eas.patch @@ -369,7 +369,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < *min_offs) *min_offs = offs; -@@ -611,16 +728,176 @@ static size_t ext4_xattr_free_space(stru +@@ -611,16 +728,200 @@ static size_t ext4_xattr_free_space(stru return (*min_offs - ((void *)last - base) - sizeof(__u32)); } @@ -448,11 +448,22 @@ Index: linux-stage/fs/ext4/xattr.c + return ret; +} + ++static void ext4_xattr_inode_set_ref(struct inode *ea_inode, __u64 ref_count) ++{ ++ ea_inode->i_ctime.tv_sec = (__u32)(ref_count >> 32); ++ ea_inode->i_version = (__u32)ref_count; ++} ++ ++static void ext4_xattr_inode_set_hash(struct inode *ea_inode, __u32 hash) ++{ ++ ea_inode->i_atime.tv_sec = hash; ++} ++ +/* + * Create an inode to store the value of a large EA. + */ +static struct inode * -+ext4_xattr_inode_create(handle_t *handle, struct inode *inode) ++ext4_xattr_inode_create(handle_t *handle, struct inode *inode, __u32 hash) +{ + struct inode *ea_inode = NULL; + @@ -476,6 +487,9 @@ Index: linux-stage/fs/ext4/xattr.c + */ + EXT4_XATTR_INODE_SET_PARENT(ea_inode, inode->i_ino); + unlock_new_inode(ea_inode); ++ ++ ext4_xattr_inode_set_ref(ea_inode, 1); ++ ext4_xattr_inode_set_hash(ea_inode, hash); + } + + return ea_inode; @@ -500,6 +514,14 @@ Index: linux-stage/fs/ext4/xattr.c + return 0; +} + ++static __u32 ++ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size) ++{ ++ if (ext4_has_metadata_csum(sbi->s_sb)) ++ return ext4_chksum(sbi, sbi->s_csum_seed, buffer, size); ++ return 0; ++} ++ +/* + * Add value of the EA in an inode. + */ @@ -508,10 +530,12 @@ Index: linux-stage/fs/ext4/xattr.c + const void *value, size_t value_len) +{ + struct inode *ea_inode = NULL; ++ __u32 hash; + int err; + + /* Create an inode for the EA value */ -+ ea_inode = ext4_xattr_inode_create(handle, inode); ++ hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len); ++ ea_inode = ext4_xattr_inode_create(handle, inode, hash); + if (IS_ERR(ea_inode)) + return -1; + @@ -548,7 +572,7 @@ Index: linux-stage/fs/ext4/xattr.c size_t offs = le16_to_cpu(last->e_value_offs); if (offs < min_offs) min_offs = offs; -@@ -628,15 +903,20 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -628,15 +927,20 @@ ext4_xattr_set_entry(struct ext4_xattr_i } free = min_offs - ((void *)last - s->base) - sizeof(__u32); if (!s->not_found) { @@ -572,7 +596,7 @@ Index: linux-stage/fs/ext4/xattr.c return -ENOSPC; } -@@ -651,7 +931,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -651,7 +955,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i s->here->e_name_len = name_len; memcpy(s->here->e_name, i->name, name_len); } else { @@ -582,7 +606,7 @@ Index: linux-stage/fs/ext4/xattr.c void *first_val = s->base + min_offs; size_t offs = le16_to_cpu(s->here->e_value_offs); void *val = s->base + offs; -@@ -685,13 +966,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -685,13 +990,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i last = s->first; while (!IS_LAST_ENTRY(last)) { size_t o = le16_to_cpu(last->e_value_offs); @@ -602,7 +626,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!i->value) { /* Remove the old name. */ size_t size = EXT4_XATTR_LEN(name_len); -@@ -705,10 +990,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i +@@ -705,10 +1014,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i if (i->value) { /* Insert the new value. */ s->here->e_value_size = cpu_to_le32(i->value_len); @@ -621,7 +645,7 @@ Index: linux-stage/fs/ext4/xattr.c if (i->value == EXT4_ZERO_XATTR_VALUE) { memset(val, 0, size); } else { -@@ -758,7 +1050,7 @@ ext4_xattr_block_find(struct inode *inod +@@ -758,7 +1074,7 @@ ext4_xattr_block_find(struct inode *inod bs->s.end = bs->bh->b_data + bs->bh->b_size; bs->s.here = bs->s.first; error = ext4_xattr_find_entry(&bs->s.here, i->name_index, @@ -630,7 +654,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; -@@ -782,8 +1074,6 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -782,8 +1098,6 @@ ext4_xattr_block_set(handle_t *handle, s #define header(x) ((struct ext4_xattr_header *)(x)) @@ -639,7 +663,7 @@ Index: linux-stage/fs/ext4/xattr.c if (s->base) { ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, bs->bh->b_blocknr); -@@ -799,7 +1089,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -799,7 +1113,7 @@ ext4_xattr_block_set(handle_t *handle, s ce = NULL; } ea_bdebug(bs->bh, "modifying in-place"); @@ -648,7 +672,7 @@ Index: linux-stage/fs/ext4/xattr.c if (!error) { if (!IS_LAST_ENTRY(s->first)) ext4_xattr_rehash(header(s->base), -@@ -850,7 +1140,7 @@ ext4_xattr_block_set(handle_t *handle, s +@@ -850,7 +1164,7 @@ ext4_xattr_block_set(handle_t *handle, s s->end = s->base + sb->s_blocksize; } @@ -657,7 +681,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error == -EFSCORRUPTED) goto bad_block; if (error) -@@ -1000,7 +1290,7 @@ int ext4_xattr_ibody_find(struct inode * +@@ -1000,7 +1314,7 @@ int ext4_xattr_ibody_find(struct inode * /* Find the named attribute. */ error = ext4_xattr_find_entry(&is->s.here, i->name_index, i->name, is->s.end - @@ -666,7 +690,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error && error != -ENODATA) return error; is->s.not_found = error; -@@ -1018,7 +1308,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1018,7 +1332,7 @@ int ext4_xattr_ibody_inline_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -675,7 +699,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) { if (error == -ENOSPC && ext4_has_inline_data(inode)) { -@@ -1030,7 +1320,7 @@ int ext4_xattr_ibody_inline_set(handle_t +@@ -1030,7 +1344,7 @@ int ext4_xattr_ibody_inline_set(handle_t error = ext4_xattr_ibody_find(inode, i, is); if (error) return error; @@ -684,7 +708,7 @@ Index: linux-stage/fs/ext4/xattr.c } if (error) return error; -@@ -1056,7 +1346,7 @@ static int ext4_xattr_ibody_set(handle_t +@@ -1056,7 +1370,7 @@ static int ext4_xattr_ibody_set(handle_t if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; @@ -693,7 +717,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) return error; header = IHDR(inode, ext4_raw_inode(&is->iloc)); -@@ -1092,7 +1382,7 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1092,7 +1406,7 @@ ext4_xattr_set_handle(handle_t *handle, .name = name, .value = value, .value_len = value_len, @@ -702,7 +726,7 @@ Index: linux-stage/fs/ext4/xattr.c }; struct ext4_xattr_ibody_find is = { .s = { .not_found = -ENODATA, }, -@@ -1157,6 +1447,15 @@ ext4_xattr_set_handle(handle_t *handle, +@@ -1157,6 +1471,15 @@ ext4_xattr_set_handle(handle_t *handle, goto cleanup; } error = ext4_xattr_block_set(handle, inode, &i, &bs); @@ -718,7 +742,7 @@ Index: linux-stage/fs/ext4/xattr.c if (error) goto cleanup; if (!is.s.not_found) { -@@ -1203,9 +1502,22 @@ ext4_xattr_set(struct inode *inode, int +@@ -1203,9 +1526,22 @@ ext4_xattr_set(struct inode *inode, int const void *value, size_t value_len, int flags) { handle_t *handle; @@ -741,7 +765,7 @@ Index: linux-stage/fs/ext4/xattr.c retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits); if (IS_ERR(handle)) { -@@ -1217,7 +1529,7 @@ retry: +@@ -1217,7 +1553,7 @@ retry: value, value_len, flags); error2 = ext4_journal_stop(handle); if (error == -ENOSPC && @@ -750,7 +774,7 @@ Index: linux-stage/fs/ext4/xattr.c goto retry; if (error == 0) error = error2; -@@ -1239,7 +1551,7 @@ static void ext4_xattr_shift_entries(str +@@ -1239,7 +1575,7 @@ static void ext4_xattr_shift_entries(str /* Adjust the value offsets of the entries */ for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { @@ -759,7 +783,7 @@ Index: linux-stage/fs/ext4/xattr.c new_offs = le16_to_cpu(last->e_value_offs) + value_offs_shift; BUG_ON(new_offs + le32_to_cpu(last->e_value_size) -@@ -1477,21 +1789,135 @@ cleanup: +@@ -1477,21 +1813,135 @@ cleanup: } @@ -900,7 +924,7 @@ Index: linux-stage/fs/ext4/xattr.c bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); if (!bh) { EXT4_ERROR_INODE(inode, "block %llu read error", -@@ -1504,11 +1930,69 @@ ext4_xattr_delete_inode(handle_t *handle +@@ -1504,11 +1954,69 @@ ext4_xattr_delete_inode(handle_t *handle EXT4_I(inode)->i_file_acl); goto cleanup; } @@ -970,7 +994,7 @@ Index: linux-stage/fs/ext4/xattr.c } /* -@@ -1578,10 +2062,9 @@ ext4_xattr_cmp(struct ext4_xattr_header +@@ -1578,10 +2086,9 @@ ext4_xattr_cmp(struct ext4_xattr_header entry1->e_name_index != entry2->e_name_index || entry1->e_name_len != entry2->e_name_len || entry1->e_value_size != entry2->e_value_size || @@ -982,7 +1006,7 @@ Index: linux-stage/fs/ext4/xattr.c if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), (char *)header2 + le16_to_cpu(entry2->e_value_offs), le32_to_cpu(entry1->e_value_size))) -@@ -1665,7 +2148,7 @@ static inline void ext4_xattr_hash_entry +@@ -1665,7 +2172,7 @@ static inline void ext4_xattr_hash_entry *name++; } -- 1.8.3.1