Skip to content

Commit

Permalink
ext4: shortcut setting of xattr to the same value
Browse files Browse the repository at this point in the history
When someone tried to set xattr to the same value (i.e., not changing
anything) we did all the work of removing original xattr, possibly
breaking references to shared xattr block, inserting new xattr, and
merging xattr blocks again. Since this is not so rare operation and it
is relatively cheap for us to detect this case, check for this and
shortcut xattr setting in that case.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
  • Loading branch information
Jan Kara authored and Theodore Ts'o committed Feb 23, 2016
1 parent dc8d5e5 commit 3fd1646
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions fs/ext4/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,17 @@ static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
return 0;
}

static int ext4_xattr_value_same(struct ext4_xattr_search *s,
struct ext4_xattr_info *i)
{
void *value;

if (le32_to_cpu(s->here->e_value_size) != i->value_len)
return 0;
value = ((void *)s->base) + le16_to_cpu(s->here->e_value_offs);
return !memcmp(value, i->value, i->value_len);
}

/*
* ext4_xattr_set_handle()
*
Expand Down Expand Up @@ -1172,6 +1183,13 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
else if (!bs.s.not_found)
error = ext4_xattr_block_set(handle, inode, &i, &bs);
} else {
error = 0;
/* Xattr value did not change? Save us some work and bail out */
if (!is.s.not_found && ext4_xattr_value_same(&is.s, &i))
goto cleanup;
if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i))
goto cleanup;

error = ext4_xattr_ibody_set(handle, inode, &i, &is);
if (!error && !bs.s.not_found) {
i.value = NULL;
Expand Down

0 comments on commit 3fd1646

Please sign in to comment.