Skip to content

Commit 3fd1646

Browse files
jankaratytso
authored andcommitted
ext4: shortcut setting of xattr to the same value
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 <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent dc8d5e5 commit 3fd1646

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

fs/ext4/xattr.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,17 @@ static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
10961096
return 0;
10971097
}
10981098

1099+
static int ext4_xattr_value_same(struct ext4_xattr_search *s,
1100+
struct ext4_xattr_info *i)
1101+
{
1102+
void *value;
1103+
1104+
if (le32_to_cpu(s->here->e_value_size) != i->value_len)
1105+
return 0;
1106+
value = ((void *)s->base) + le16_to_cpu(s->here->e_value_offs);
1107+
return !memcmp(value, i->value, i->value_len);
1108+
}
1109+
10991110
/*
11001111
* ext4_xattr_set_handle()
11011112
*
@@ -1172,6 +1183,13 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
11721183
else if (!bs.s.not_found)
11731184
error = ext4_xattr_block_set(handle, inode, &i, &bs);
11741185
} else {
1186+
error = 0;
1187+
/* Xattr value did not change? Save us some work and bail out */
1188+
if (!is.s.not_found && ext4_xattr_value_same(&is.s, &i))
1189+
goto cleanup;
1190+
if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i))
1191+
goto cleanup;
1192+
11751193
error = ext4_xattr_ibody_set(handle, inode, &i, &is);
11761194
if (!error && !bs.s.not_found) {
11771195
i.value = NULL;

0 commit comments

Comments
 (0)