Btrfs: don't use ram_bytes for uncompressed inline items
If we truncate an uncompressed inline item, ram_bytes isn't updated to reflect the new size. The fixe uses the size directly from the item header when reading uncompressed inlines, and also fixes truncate to update the size as it goes. Reported-by: Jens Axboe <axboe@fb.com> Signed-off-by: Chris Mason <clm@fb.com> CC: stable@vger.kernel.org
This commit is contained in:
@@ -1281,7 +1281,8 @@ next_slot:
|
||||
nocow = 1;
|
||||
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
|
||||
extent_end = found_key.offset +
|
||||
btrfs_file_extent_inline_len(leaf, fi);
|
||||
btrfs_file_extent_inline_len(leaf,
|
||||
path->slots[0], fi);
|
||||
extent_end = ALIGN(extent_end, root->sectorsize);
|
||||
} else {
|
||||
BUG_ON(1);
|
||||
@@ -4023,7 +4024,7 @@ search_again:
|
||||
btrfs_file_extent_num_bytes(leaf, fi);
|
||||
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
|
||||
item_end += btrfs_file_extent_inline_len(leaf,
|
||||
fi);
|
||||
path->slots[0], fi);
|
||||
}
|
||||
item_end--;
|
||||
}
|
||||
@@ -4093,6 +4094,12 @@ search_again:
|
||||
inode_sub_bytes(inode, item_end + 1 -
|
||||
new_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* update the ram bytes to properly reflect
|
||||
* the new size of our item
|
||||
*/
|
||||
btrfs_set_file_extent_ram_bytes(leaf, fi, size);
|
||||
size =
|
||||
btrfs_file_extent_calc_inline_size(size);
|
||||
btrfs_truncate_item(root, path, size, 1);
|
||||
@@ -6162,7 +6169,7 @@ again:
|
||||
btrfs_file_extent_num_bytes(leaf, item);
|
||||
} else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
|
||||
size_t size;
|
||||
size = btrfs_file_extent_inline_len(leaf, item);
|
||||
size = btrfs_file_extent_inline_len(leaf, path->slots[0], item);
|
||||
extent_end = ALIGN(extent_start + size, root->sectorsize);
|
||||
}
|
||||
next:
|
||||
@@ -6231,7 +6238,7 @@ next:
|
||||
goto out;
|
||||
}
|
||||
|
||||
size = btrfs_file_extent_inline_len(leaf, item);
|
||||
size = btrfs_file_extent_inline_len(leaf, path->slots[0], item);
|
||||
extent_offset = page_offset(page) + pg_offset - extent_start;
|
||||
copy_size = min_t(u64, PAGE_CACHE_SIZE - pg_offset,
|
||||
size - extent_offset);
|
||||
|
Reference in New Issue
Block a user