ext4: fix ext4_xattr_make_inode_space() value size calculation
authorTahsin Erdogan <tahsin@google.com>
Thu, 22 Jun 2017 02:05:44 +0000 (22:05 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 22 Jun 2017 02:05:44 +0000 (22:05 -0400)
ext4_xattr_make_inode_space() is interested in calculating the inline
space used in an inode. When a xattr entry refers to an external inode
the value size indicates the external inode size, not the value size in
the inline area. Change the function to take this into account.

Signed-off-by: Tahsin Erdogan <tahsin@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/xattr.c

index 13b7fa4cbf16edbed62200e98312a06f932419ef..2be891ffeda19d1f215fd138f2368a34edc6aae6 100644 (file)
@@ -1745,9 +1745,10 @@ static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
                last = IFIRST(header);
                /* Find the entry best suited to be pushed into EA block */
                for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
-                       total_size =
-                       EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
-                                       EXT4_XATTR_LEN(last->e_name_len);
+                       total_size = EXT4_XATTR_LEN(last->e_name_len);
+                       if (!last->e_value_inum)
+                               total_size += EXT4_XATTR_SIZE(
+                                              le32_to_cpu(last->e_value_size));
                        if (total_size <= bfree &&
                            total_size < min_total_size) {
                                if (total_size + ifree < isize_diff) {
@@ -1766,8 +1767,10 @@ static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
                }
 
                entry_size = EXT4_XATTR_LEN(entry->e_name_len);
-               total_size = entry_size +
-                       EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
+               total_size = entry_size;
+               if (!entry->e_value_inum)
+                       total_size += EXT4_XATTR_SIZE(
+                                             le32_to_cpu(entry->e_value_size));
                error = ext4_xattr_move_to_block(handle, inode, raw_inode,
                                                 entry);
                if (error)