summaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2018-06-06 03:41:49 -0400
committerDavid Sterba <dsterba@suse.com>2018-08-06 07:12:38 -0400
commite41ca5897489b1c18af75ff0cc8f5c80260b3281 (patch)
treedc20051c4be3bb6f4b47bb1823364ae345d75809 /fs/btrfs
parentbc877d285ca3dba24c52406946a4a69847cc7422 (diff)
btrfs: Get rid of the confusing btrfs_file_extent_inline_len
We used to call btrfs_file_extent_inline_len() to get the uncompressed data size of an inlined extent. However this function is hiding evil, for compressed extent, it has no choice but to directly read out ram_bytes from btrfs_file_extent_item. While for uncompressed extent, it uses item size to calculate the real data size, and ignoring ram_bytes completely. In fact, for corrupted ram_bytes, due to above behavior kernel btrfs_print_leaf() can't even print correct ram_bytes to expose the bug. Since we have the tree-checker to verify all EXTENT_DATA, such mismatch can be detected pretty easily, thus we can trust ram_bytes without the evil btrfs_file_extent_inline_len(). Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h26
-rw-r--r--fs/btrfs/file-item.c2
-rw-r--r--fs/btrfs/file.c3
-rw-r--r--fs/btrfs/inode.c12
-rw-r--r--fs/btrfs/print-tree.c4
-rw-r--r--fs/btrfs/send.c17
-rw-r--r--fs/btrfs/tree-log.c12
7 files changed, 21 insertions, 55 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 12cb327cd16e..41ba770b9db9 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2428,32 +2428,6 @@ static inline u32 btrfs_file_extent_inline_item_len(
2428 return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START; 2428 return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START;
2429} 2429}
2430 2430
2431/* this returns the number of file bytes represented by the inline item.
2432 * If an item is compressed, this is the uncompressed size
2433 */
2434static inline u32 btrfs_file_extent_inline_len(const struct extent_buffer *eb,
2435 int slot,
2436 const struct btrfs_file_extent_item *fi)
2437{
2438 struct btrfs_map_token token;
2439
2440 btrfs_init_map_token(&token);
2441 /*
2442 * return the space used on disk if this item isn't
2443 * compressed or encoded
2444 */
2445 if (btrfs_token_file_extent_compression(eb, fi, &token) == 0 &&
2446 btrfs_token_file_extent_encryption(eb, fi, &token) == 0 &&
2447 btrfs_token_file_extent_other_encoding(eb, fi, &token) == 0) {
2448 return btrfs_file_extent_inline_item_len(eb,
2449 btrfs_item_nr(slot));
2450 }
2451
2452 /* otherwise use the ram bytes field */
2453 return btrfs_token_file_extent_ram_bytes(eb, fi, &token);
2454}
2455
2456
2457/* btrfs_dev_stats_item */ 2431/* btrfs_dev_stats_item */
2458static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb, 2432static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb,
2459 const struct btrfs_dev_stats_item *ptr, 2433 const struct btrfs_dev_stats_item *ptr,
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index f9dd6d1836a3..8c3cd7072caf 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -942,7 +942,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
942 btrfs_file_extent_num_bytes(leaf, fi); 942 btrfs_file_extent_num_bytes(leaf, fi);
943 } else if (type == BTRFS_FILE_EXTENT_INLINE) { 943 } else if (type == BTRFS_FILE_EXTENT_INLINE) {
944 size_t size; 944 size_t size;
945 size = btrfs_file_extent_inline_len(leaf, slot, fi); 945 size = btrfs_file_extent_ram_bytes(leaf, fi);
946 extent_end = ALIGN(extent_start + size, 946 extent_end = ALIGN(extent_start + size,
947 fs_info->sectorsize); 947 fs_info->sectorsize);
948 } 948 }
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 975c590c50d8..4cd8af14f915 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -833,8 +833,7 @@ next_slot:
833 btrfs_file_extent_num_bytes(leaf, fi); 833 btrfs_file_extent_num_bytes(leaf, fi);
834 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { 834 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
835 extent_end = key.offset + 835 extent_end = key.offset +
836 btrfs_file_extent_inline_len(leaf, 836 btrfs_file_extent_ram_bytes(leaf, fi);
837 path->slots[0], fi);
838 } else { 837 } else {
839 /* can't happen */ 838 /* can't happen */
840 BUG(); 839 BUG();
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index eba61bcb9bb3..1ade43c02b81 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1443,8 +1443,7 @@ next_slot:
1443 nocow = 1; 1443 nocow = 1;
1444 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { 1444 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
1445 extent_end = found_key.offset + 1445 extent_end = found_key.offset +
1446 btrfs_file_extent_inline_len(leaf, 1446 btrfs_file_extent_ram_bytes(leaf, fi);
1447 path->slots[0], fi);
1448 extent_end = ALIGN(extent_end, 1447 extent_end = ALIGN(extent_end,
1449 fs_info->sectorsize); 1448 fs_info->sectorsize);
1450 } else { 1449 } else {
@@ -4643,8 +4642,8 @@ search_again:
4643 BTRFS_I(inode), leaf, fi, 4642 BTRFS_I(inode), leaf, fi,
4644 found_key.offset); 4643 found_key.offset);
4645 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { 4644 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
4646 item_end += btrfs_file_extent_inline_len(leaf, 4645 item_end += btrfs_file_extent_ram_bytes(leaf,
4647 path->slots[0], fi); 4646 fi);
4648 4647
4649 trace_btrfs_truncate_show_fi_inline( 4648 trace_btrfs_truncate_show_fi_inline(
4650 BTRFS_I(inode), leaf, fi, path->slots[0], 4649 BTRFS_I(inode), leaf, fi, path->slots[0],
@@ -6943,7 +6942,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
6943 extent_start); 6942 extent_start);
6944 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 6943 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
6945 size_t size; 6944 size_t size;
6946 size = btrfs_file_extent_inline_len(leaf, path->slots[0], item); 6945
6946 size = btrfs_file_extent_ram_bytes(leaf, item);
6947 extent_end = ALIGN(extent_start + size, 6947 extent_end = ALIGN(extent_start + size,
6948 fs_info->sectorsize); 6948 fs_info->sectorsize);
6949 6949
@@ -6994,7 +6994,7 @@ next:
6994 if (new_inline) 6994 if (new_inline)
6995 goto out; 6995 goto out;
6996 6996
6997 size = btrfs_file_extent_inline_len(leaf, path->slots[0], item); 6997 size = btrfs_file_extent_ram_bytes(leaf, item);
6998 extent_offset = page_offset(page) + pg_offset - extent_start; 6998 extent_offset = page_offset(page) + pg_offset - extent_start;
6999 copy_size = min_t(u64, PAGE_SIZE - pg_offset, 6999 copy_size = min_t(u64, PAGE_SIZE - pg_offset,
7000 size - extent_offset); 7000 size - extent_offset);
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index a4e11cf04671..59efcf2e0de8 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -267,8 +267,8 @@ void btrfs_print_leaf(struct extent_buffer *l)
267 struct btrfs_file_extent_item); 267 struct btrfs_file_extent_item);
268 if (btrfs_file_extent_type(l, fi) == 268 if (btrfs_file_extent_type(l, fi) ==
269 BTRFS_FILE_EXTENT_INLINE) { 269 BTRFS_FILE_EXTENT_INLINE) {
270 pr_info("\t\tinline extent data size %u\n", 270 pr_info("\t\tinline extent data size %llu\n",
271 btrfs_file_extent_inline_len(l, i, fi)); 271 btrfs_file_extent_ram_bytes(l, fi));
272 break; 272 break;
273 } 273 }
274 pr_info("\t\textent data disk bytenr %llu nr %llu\n", 274 pr_info("\t\textent data disk bytenr %llu nr %llu\n",
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index c47f62b19226..6ff7a1315e52 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1500,7 +1500,7 @@ static int read_symlink(struct btrfs_root *root,
1500 BUG_ON(compression); 1500 BUG_ON(compression);
1501 1501
1502 off = btrfs_file_extent_inline_start(ei); 1502 off = btrfs_file_extent_inline_start(ei);
1503 len = btrfs_file_extent_inline_len(path->nodes[0], path->slots[0], ei); 1503 len = btrfs_file_extent_ram_bytes(path->nodes[0], ei);
1504 1504
1505 ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len); 1505 ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len);
1506 1506
@@ -5160,7 +5160,7 @@ static int clone_range(struct send_ctx *sctx,
5160 ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); 5160 ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
5161 type = btrfs_file_extent_type(leaf, ei); 5161 type = btrfs_file_extent_type(leaf, ei);
5162 if (type == BTRFS_FILE_EXTENT_INLINE) { 5162 if (type == BTRFS_FILE_EXTENT_INLINE) {
5163 ext_len = btrfs_file_extent_inline_len(leaf, slot, ei); 5163 ext_len = btrfs_file_extent_ram_bytes(leaf, ei);
5164 ext_len = PAGE_ALIGN(ext_len); 5164 ext_len = PAGE_ALIGN(ext_len);
5165 } else { 5165 } else {
5166 ext_len = btrfs_file_extent_num_bytes(leaf, ei); 5166 ext_len = btrfs_file_extent_num_bytes(leaf, ei);
@@ -5236,8 +5236,7 @@ static int send_write_or_clone(struct send_ctx *sctx,
5236 struct btrfs_file_extent_item); 5236 struct btrfs_file_extent_item);
5237 type = btrfs_file_extent_type(path->nodes[0], ei); 5237 type = btrfs_file_extent_type(path->nodes[0], ei);
5238 if (type == BTRFS_FILE_EXTENT_INLINE) { 5238 if (type == BTRFS_FILE_EXTENT_INLINE) {
5239 len = btrfs_file_extent_inline_len(path->nodes[0], 5239 len = btrfs_file_extent_ram_bytes(path->nodes[0], ei);
5240 path->slots[0], ei);
5241 /* 5240 /*
5242 * it is possible the inline item won't cover the whole page, 5241 * it is possible the inline item won't cover the whole page,
5243 * but there may be items after this page. Make 5242 * but there may be items after this page. Make
@@ -5375,7 +5374,7 @@ static int is_extent_unchanged(struct send_ctx *sctx,
5375 } 5374 }
5376 5375
5377 if (right_type == BTRFS_FILE_EXTENT_INLINE) { 5376 if (right_type == BTRFS_FILE_EXTENT_INLINE) {
5378 right_len = btrfs_file_extent_inline_len(eb, slot, ei); 5377 right_len = btrfs_file_extent_ram_bytes(eb, ei);
5379 right_len = PAGE_ALIGN(right_len); 5378 right_len = PAGE_ALIGN(right_len);
5380 } else { 5379 } else {
5381 right_len = btrfs_file_extent_num_bytes(eb, ei); 5380 right_len = btrfs_file_extent_num_bytes(eb, ei);
@@ -5496,8 +5495,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
5496 struct btrfs_file_extent_item); 5495 struct btrfs_file_extent_item);
5497 type = btrfs_file_extent_type(path->nodes[0], fi); 5496 type = btrfs_file_extent_type(path->nodes[0], fi);
5498 if (type == BTRFS_FILE_EXTENT_INLINE) { 5497 if (type == BTRFS_FILE_EXTENT_INLINE) {
5499 u64 size = btrfs_file_extent_inline_len(path->nodes[0], 5498 u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi);
5500 path->slots[0], fi);
5501 extent_end = ALIGN(key.offset + size, 5499 extent_end = ALIGN(key.offset + size,
5502 sctx->send_root->fs_info->sectorsize); 5500 sctx->send_root->fs_info->sectorsize);
5503 } else { 5501 } else {
@@ -5560,7 +5558,7 @@ static int range_is_hole_in_parent(struct send_ctx *sctx,
5560 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); 5558 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
5561 if (btrfs_file_extent_type(leaf, fi) == 5559 if (btrfs_file_extent_type(leaf, fi) ==
5562 BTRFS_FILE_EXTENT_INLINE) { 5560 BTRFS_FILE_EXTENT_INLINE) {
5563 u64 size = btrfs_file_extent_inline_len(leaf, slot, fi); 5561 u64 size = btrfs_file_extent_ram_bytes(leaf, fi);
5564 5562
5565 extent_end = ALIGN(key.offset + size, 5563 extent_end = ALIGN(key.offset + size,
5566 root->fs_info->sectorsize); 5564 root->fs_info->sectorsize);
@@ -5606,8 +5604,7 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
5606 struct btrfs_file_extent_item); 5604 struct btrfs_file_extent_item);
5607 type = btrfs_file_extent_type(path->nodes[0], fi); 5605 type = btrfs_file_extent_type(path->nodes[0], fi);
5608 if (type == BTRFS_FILE_EXTENT_INLINE) { 5606 if (type == BTRFS_FILE_EXTENT_INLINE) {
5609 u64 size = btrfs_file_extent_inline_len(path->nodes[0], 5607 u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi);
5610 path->slots[0], fi);
5611 extent_end = ALIGN(key->offset + size, 5608 extent_end = ALIGN(key->offset + size,
5612 sctx->send_root->fs_info->sectorsize); 5609 sctx->send_root->fs_info->sectorsize);
5613 } else { 5610 } else {
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index b3b1d424f2d8..6bca8f88ade0 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -597,7 +597,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
597 if (btrfs_file_extent_disk_bytenr(eb, item) == 0) 597 if (btrfs_file_extent_disk_bytenr(eb, item) == 0)
598 nbytes = 0; 598 nbytes = 0;
599 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 599 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
600 size = btrfs_file_extent_inline_len(eb, slot, item); 600 size = btrfs_file_extent_ram_bytes(eb, item);
601 nbytes = btrfs_file_extent_ram_bytes(eb, item); 601 nbytes = btrfs_file_extent_ram_bytes(eb, item);
602 extent_end = ALIGN(start + size, 602 extent_end = ALIGN(start + size,
603 fs_info->sectorsize); 603 fs_info->sectorsize);
@@ -3920,9 +3920,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3920 struct btrfs_file_extent_item); 3920 struct btrfs_file_extent_item);
3921 if (btrfs_file_extent_type(src, extent) == 3921 if (btrfs_file_extent_type(src, extent) ==
3922 BTRFS_FILE_EXTENT_INLINE) { 3922 BTRFS_FILE_EXTENT_INLINE) {
3923 len = btrfs_file_extent_inline_len(src, 3923 len = btrfs_file_extent_ram_bytes(src, extent);
3924 src_path->slots[0],
3925 extent);
3926 *last_extent = ALIGN(key.offset + len, 3924 *last_extent = ALIGN(key.offset + len,
3927 fs_info->sectorsize); 3925 fs_info->sectorsize);
3928 } else { 3926 } else {
@@ -3987,7 +3985,7 @@ fill_holes:
3987 extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item); 3985 extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item);
3988 if (btrfs_file_extent_type(src, extent) == 3986 if (btrfs_file_extent_type(src, extent) ==
3989 BTRFS_FILE_EXTENT_INLINE) { 3987 BTRFS_FILE_EXTENT_INLINE) {
3990 len = btrfs_file_extent_inline_len(src, i, extent); 3988 len = btrfs_file_extent_ram_bytes(src, extent);
3991 extent_end = ALIGN(key.offset + len, 3989 extent_end = ALIGN(key.offset + len,
3992 fs_info->sectorsize); 3990 fs_info->sectorsize);
3993 } else { 3991 } else {
@@ -4572,9 +4570,7 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
4572 4570
4573 if (btrfs_file_extent_type(leaf, extent) == 4571 if (btrfs_file_extent_type(leaf, extent) ==
4574 BTRFS_FILE_EXTENT_INLINE) { 4572 BTRFS_FILE_EXTENT_INLINE) {
4575 len = btrfs_file_extent_inline_len(leaf, 4573 len = btrfs_file_extent_ram_bytes(leaf, extent);
4576 path->slots[0],
4577 extent);
4578 ASSERT(len == i_size || 4574 ASSERT(len == i_size ||
4579 (len == fs_info->sectorsize && 4575 (len == fs_info->sectorsize &&
4580 btrfs_file_extent_compression(leaf, extent) != 4576 btrfs_file_extent_compression(leaf, extent) !=