diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 84d4c052fcd9bc867421554e3975bdc148eb19c5..fceddbdfdd3d0377cb6d5d4c92eadf381f978740 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2990,15 +2990,6 @@ BTRFS_SETGET_FUNCS(file_extent_encryption, struct btrfs_file_extent_item, BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, other_encoding, 16); -/* this returns the number of file bytes represented by the inline item. - * If an item is compressed, this is the uncompressed size - */ -static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, - struct btrfs_file_extent_item *e) -{ - return btrfs_file_extent_ram_bytes(eb, e); -} - /* * this returns the number of bytes used by the item on disk, minus the * size of any extent headers. If a file is compressed on disk, this is @@ -3012,6 +3003,32 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, return btrfs_item_size(eb, e) - offset; } +/* this returns the number of file bytes represented by the inline item. + * If an item is compressed, this is the uncompressed size + */ +static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, + int slot, + struct btrfs_file_extent_item *fi) +{ + struct btrfs_map_token token; + + btrfs_init_map_token(&token); + /* + * return the space used on disk if this item isn't + * compressed or encoded + */ + if (btrfs_token_file_extent_compression(eb, fi, &token) == 0 && + btrfs_token_file_extent_encryption(eb, fi, &token) == 0 && + btrfs_token_file_extent_other_encoding(eb, fi, &token) == 0) { + return btrfs_file_extent_inline_item_len(eb, + btrfs_item_nr(slot)); + } + + /* otherwise use the ram bytes field */ + return btrfs_token_file_extent_ram_bytes(eb, fi, &token); +} + + /* btrfs_dev_stats_item */ static inline u64 btrfs_dev_stats_value(struct extent_buffer *eb, struct btrfs_dev_stats_item *ptr, diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 3dfd8db0e2439b3eb9b2cd387fb7f78a2bafeddc..0165b8672f099c49f96400fc0c87cc0b7cfc4532 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -772,7 +772,8 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans, btrfs_file_extent_num_bytes(leaf, fi); } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { extent_end = key.offset + - btrfs_file_extent_inline_len(leaf, fi); + btrfs_file_extent_inline_len(leaf, + path->slots[0], fi); } else { WARN_ON(1); extent_end = search_start; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3b6598783be9e6dda1c6e9d4478cbbe212e41893..ad961a598c99b38660a802d3afc8fd8839619ac8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1281,7 +1281,8 @@ static noinline int run_delalloc_nocow(struct inode *inode, 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 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, 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 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, 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 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, 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 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, 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); diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 4eed002b7cf66ec9eeb81cba380f96f647750e4f..6efd70d3b64f785e23d0bb3323d4905825406c62 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -249,7 +249,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) BTRFS_FILE_EXTENT_INLINE) { printk(KERN_INFO "\t\tinline extent data " "size %u\n", - btrfs_file_extent_inline_len(l, fi)); + btrfs_file_extent_inline_len(l, i, fi)); break; } printk(KERN_INFO "\t\textent data disk bytenr %llu " diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 85259cba784aaed6a4f31501e2c5ece102028d7d..730dce395858a6e4c86a43b4a8fa41779d719e0d 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -1377,7 +1377,7 @@ static int read_symlink(struct btrfs_root *root, BUG_ON(compression); off = btrfs_file_extent_inline_start(ei); - len = btrfs_file_extent_inline_len(path->nodes[0], ei); + len = btrfs_file_extent_inline_len(path->nodes[0], path->slots[0], ei); ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len); @@ -4207,7 +4207,8 @@ static int send_write_or_clone(struct send_ctx *sctx, struct btrfs_file_extent_item); type = btrfs_file_extent_type(path->nodes[0], ei); if (type == BTRFS_FILE_EXTENT_INLINE) { - len = btrfs_file_extent_inline_len(path->nodes[0], ei); + len = btrfs_file_extent_inline_len(path->nodes[0], + path->slots[0], ei); /* * it is possible the inline item won't cover the whole page, * but there may be items after this page. Make @@ -4448,7 +4449,8 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset) struct btrfs_file_extent_item); type = btrfs_file_extent_type(path->nodes[0], fi); if (type == BTRFS_FILE_EXTENT_INLINE) { - u64 size = btrfs_file_extent_inline_len(path->nodes[0], fi); + u64 size = btrfs_file_extent_inline_len(path->nodes[0], + path->slots[0], fi); extent_end = ALIGN(key.offset + size, sctx->send_root->sectorsize); } else { @@ -4482,7 +4484,8 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, struct btrfs_file_extent_item); type = btrfs_file_extent_type(path->nodes[0], fi); if (type == BTRFS_FILE_EXTENT_INLINE) { - u64 size = btrfs_file_extent_inline_len(path->nodes[0], fi); + u64 size = btrfs_file_extent_inline_len(path->nodes[0], + path->slots[0], fi); extent_end = ALIGN(key->offset + size, sctx->send_root->sectorsize); } else { diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index b142b6dc96c3bee7c9535f941a73afba18808d66..39d83da03e0398db90428e52b98524982da469b5 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -570,7 +570,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, if (btrfs_file_extent_disk_bytenr(eb, item) == 0) nbytes = 0; } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { - size = btrfs_file_extent_inline_len(eb, item); + size = btrfs_file_extent_inline_len(eb, slot, item); nbytes = btrfs_file_extent_ram_bytes(eb, item); extent_end = ALIGN(start + size, root->sectorsize); } else { @@ -3367,7 +3367,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, struct btrfs_file_extent_item); if (btrfs_file_extent_type(src, extent) == BTRFS_FILE_EXTENT_INLINE) { - len = btrfs_file_extent_inline_len(src, extent); + len = btrfs_file_extent_inline_len(src, + src_path->slots[0], + extent); *last_extent = ALIGN(key.offset + len, log->sectorsize); } else { @@ -3431,7 +3433,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item); if (btrfs_file_extent_type(src, extent) == BTRFS_FILE_EXTENT_INLINE) { - len = btrfs_file_extent_inline_len(src, extent); + len = btrfs_file_extent_inline_len(src, i, extent); extent_end = ALIGN(key.offset + len, log->sectorsize); } else { len = btrfs_file_extent_num_bytes(src, extent);