1 ext4: fix ext4_xattr_move_to_block()
3 From: Tahsin Erdogan <tahsin@google.com>
5 When moving xattr entries from inline area to a xattr block, entries
6 that refer to external xattr inodes need special handling because
7 value data is not available in the inline area but rather should be
8 read from its external inode.
10 Signed-off-by: Tahsin Erdogan <tahsin@google.com>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 fs/ext4/xattr.c | 19 +++++++++++++------
14 1 file changed, 13 insertions(+), 6 deletions(-)
16 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
17 index 6a6bee246873..9c243b3510b7 100644
20 @@ -1658,18 +1658,16 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
21 struct ext4_xattr_ibody_find *is = NULL;
22 struct ext4_xattr_block_find *bs = NULL;
23 char *buffer = NULL, *b_entry_name = NULL;
24 - size_t value_offs, value_size;
25 + size_t value_size = le32_to_cpu(entry->e_value_size);
26 struct ext4_xattr_info i = {
29 .name_index = entry->e_name_index,
30 + .in_inode = !!entry->e_value_inum,
32 struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
35 - value_offs = le16_to_cpu(entry->e_value_offs);
36 - value_size = le32_to_cpu(entry->e_value_size);
38 is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
39 bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
40 buffer = kmalloc(value_size, GFP_NOFS);
41 @@ -1685,7 +1683,17 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
44 /* Save the entry name and the entry value */
45 - memcpy(buffer, (void *)IFIRST(header) + value_offs, value_size);
46 + if (entry->e_value_inum) {
47 + error = ext4_xattr_inode_get(inode,
48 + le32_to_cpu(entry->e_value_inum),
49 + buffer, value_size);
53 + size_t value_offs = le16_to_cpu(entry->e_value_offs);
54 + memcpy(buffer, (void *)IFIRST(header) + value_offs, value_size);
57 memcpy(b_entry_name, entry->e_name, entry->e_name_len);
58 b_entry_name[entry->e_name_len] = '\0';
59 i.name = b_entry_name;
60 @@ -1703,7 +1711,6 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
64 - i.name = b_entry_name;
66 i.value_len = value_size;
67 error = ext4_xattr_block_find(inode, &i, bs);
69 2.13.1.611.g7e3b11ae1-goog