1 ext4: fix ext4_xattr_make_inode_space() value size calculation
3 From: Tahsin Erdogan <tahsin@google.com>
5 ext4_xattr_make_inode_space() is interested in calculating the inline
6 space used in an inode. When a xattr entry refers to an external inode
7 the value size indicates the external inode size, not the value size in
8 the inline area. Change the function to take this into account.
10 Signed-off-by: Tahsin Erdogan <tahsin@google.com>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 fs/ext4/xattr.c | 13 ++++++++-----
14 1 file changed, 8 insertions(+), 5 deletions(-)
16 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
17 index 681a9b5eefd8..6a6bee246873 100644
20 @@ -1747,9 +1747,10 @@ static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
21 last = IFIRST(header);
22 /* Find the entry best suited to be pushed into EA block */
23 for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
25 - EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
26 - EXT4_XATTR_LEN(last->e_name_len);
27 + total_size = EXT4_XATTR_LEN(last->e_name_len);
28 + if (!last->e_value_inum)
29 + total_size += EXT4_XATTR_SIZE(
30 + le32_to_cpu(last->e_value_size));
31 if (total_size <= bfree &&
32 total_size < min_total_size) {
33 if (total_size + ifree < isize_diff) {
34 @@ -1768,8 +1769,10 @@ static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
37 entry_size = EXT4_XATTR_LEN(entry->e_name_len);
38 - total_size = entry_size +
39 - EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
40 + total_size = entry_size;
41 + if (!entry->e_value_inum)
42 + total_size += EXT4_XATTR_SIZE(
43 + le32_to_cpu(entry->e_value_size));
44 error = ext4_xattr_move_to_block(handle, inode, raw_inode,
48 2.13.1.611.g7e3b11ae1-goog