Whamcloud - gitweb
LU-9724 ldiskfs: update ext4-large-eas.patch to match upstream ext4 33/31033/9
authorEmoly Liu <emoly.liu@intel.com>
Fri, 26 Jan 2018 07:26:00 +0000 (15:26 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 27 Feb 2018 03:43:02 +0000 (03:43 +0000)
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 <emoly.liu@intel.com>
Change-Id: I2bcf45c67a580f2f545816e1a70a6322c6ccc368
Reviewed-on: https://review.whamcloud.com/31033
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Yang Sheng <yang.sheng@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch
ldiskfs/kernel_patches/patches/rhel7/ext4-large-eas.patch
ldiskfs/kernel_patches/patches/sles12/ext4-large-eas.patch
ldiskfs/kernel_patches/patches/sles12sp2/ext4-large-eas.patch

index 3b05c6e..afe5447 100644 (file)
@@ -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++;
        }
  
index 20d5b1e..bc87ecc 100644 (file)
@@ -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++;
        }
  
index 2820da2..8430ef1 100644 (file)
@@ -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++;
        }
  
index 962512e..851e45f 100644 (file)
@@ -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++;
        }