add patch fix-jbd2_journal_destroy-for-umount-path
[ext4-patch-queue.git] / shortcut-setting-of-xattr-to-the-same-value
blob216b081184ff617533da5b0ed36e20abb3e0d15a
1 ext4: shortcut setting of xattr to the same value
3 From: Jan Kara <jack@suse.cz>
5 When someone tried to set xattr to the same value (i.e., not changing
6 anything) we did all the work of removing original xattr, possibly
7 breaking references to shared xattr block, inserting new xattr, and
8 merging xattr blocks again. Since this is not so rare operation and it
9 is relatively cheap for us to detect this case, check for this and
10 shortcut xattr setting in that case.
12 Signed-off-by: Jan Kara <jack@suse.cz>
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 ---
15  fs/ext4/xattr.c | 18 ++++++++++++++++++
16  1 file changed, 18 insertions(+)
18 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
19 index c6af8a7a436a..b661ae8332e3 100644
20 --- a/fs/ext4/xattr.c
21 +++ b/fs/ext4/xattr.c
22 @@ -1096,6 +1096,17 @@ static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
23         return 0;
24  }
26 +static int ext4_xattr_value_same(struct ext4_xattr_search *s,
27 +                                struct ext4_xattr_info *i)
29 +       void *value;
31 +       if (le32_to_cpu(s->here->e_value_size) != i->value_len)
32 +               return 0;
33 +       value = ((void *)s->base) + le16_to_cpu(s->here->e_value_offs);
34 +       return !memcmp(value, i->value, i->value_len);
37  /*
38   * ext4_xattr_set_handle()
39   *
40 @@ -1172,6 +1183,13 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
41                 else if (!bs.s.not_found)
42                         error = ext4_xattr_block_set(handle, inode, &i, &bs);
43         } else {
44 +               error = 0;
45 +               /* Xattr value did not change? Save us some work and bail out */
46 +               if (!is.s.not_found && ext4_xattr_value_same(&is.s, &i))
47 +                       goto cleanup;
48 +               if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i))
49 +                       goto cleanup;
51                 error = ext4_xattr_ibody_set(handle, inode, &i, &is);
52                 if (!error && !bs.s.not_found) {
53                         i.value = NULL;
54 -- 
55 2.6.2