Skip to content

Commit

Permalink
Btrfs: log ram bytes properly
Browse files Browse the repository at this point in the history
When logging changed extents I was logging ram_bytes as the current length,
which isn't correct, it's supposed to be the ram bytes of the original extent.
This is for compression where even if we split the extent we need to know the
ram bytes so when we uncompress the extent we know how big it will be.  This was
still working out right with compression for some reason but I think we were
getting lucky.  It was definitely off for prealloc which is why I noticed it,
btrfsck was complaining about it.  With this patch btrfsck no longer complains
after a log replay.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
  • Loading branch information
Josef Bacik committed May 6, 2013
1 parent 98ad69c commit cc95bef
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 5 deletions.
1 change: 1 addition & 0 deletions fs/btrfs/extent_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct extent_map {
u64 mod_len;
u64 orig_start;
u64 orig_block_len;
u64 ram_bytes;
u64 block_start;
u64 block_len;
u64 generation;
Expand Down
3 changes: 3 additions & 0 deletions fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
split->block_len = em->block_len;
else
split->block_len = split->len;
split->ram_bytes = em->ram_bytes;
split->orig_block_len = max(split->block_len,
em->orig_block_len);
split->generation = gen;
Expand All @@ -632,6 +633,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
split->generation = gen;
split->orig_block_len = max(em->block_len,
em->orig_block_len);
split->ram_bytes = em->ram_bytes;

if (compressed) {
split->block_len = em->block_len;
Expand Down Expand Up @@ -1915,6 +1917,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
} else {
hole_em->start = offset;
hole_em->len = end - offset;
hole_em->ram_bytes = hole_em->len;
hole_em->orig_start = offset;

hole_em->block_start = EXTENT_MAP_HOLE;
Expand Down
21 changes: 17 additions & 4 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ static noinline int cow_file_range(struct inode *inode,
static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
u64 len, u64 orig_start,
u64 block_start, u64 block_len,
u64 orig_block_len, int type);
u64 orig_block_len, u64 ram_bytes,
int type);

static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
struct inode *inode, struct inode *dir,
Expand Down Expand Up @@ -722,6 +723,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
em->block_start = ins.objectid;
em->block_len = ins.offset;
em->orig_block_len = ins.offset;
em->ram_bytes = async_extent->ram_size;
em->bdev = root->fs_info->fs_devices->latest_bdev;
em->compress_type = async_extent->compress_type;
set_bit(EXTENT_FLAG_PINNED, &em->flags);
Expand Down Expand Up @@ -932,6 +934,7 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
em->block_start = ins.objectid;
em->block_len = ins.offset;
em->orig_block_len = ins.offset;
em->ram_bytes = ram_size;
em->bdev = root->fs_info->fs_devices->latest_bdev;
set_bit(EXTENT_FLAG_PINNED, &em->flags);
em->generation = -1;
Expand Down Expand Up @@ -1194,6 +1197,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
u64 disk_bytenr;
u64 num_bytes;
u64 disk_num_bytes;
u64 ram_bytes;
int extent_type;
int ret, err;
int type;
Expand Down Expand Up @@ -1290,6 +1294,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
struct btrfs_file_extent_item);
extent_type = btrfs_file_extent_type(leaf, fi);

ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
if (extent_type == BTRFS_FILE_EXTENT_REG ||
extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
Expand Down Expand Up @@ -1373,6 +1378,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
em->block_len = num_bytes;
em->block_start = disk_bytenr;
em->orig_block_len = disk_num_bytes;
em->ram_bytes = ram_bytes;
em->bdev = root->fs_info->fs_devices->latest_bdev;
em->mod_start = em->start;
em->mod_len = em->len;
Expand Down Expand Up @@ -4454,6 +4460,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->block_len = 0;
hole_em->orig_block_len = 0;
hole_em->ram_bytes = hole_size;
hole_em->bdev = root->fs_info->fs_devices->latest_bdev;
hole_em->compress_type = BTRFS_COMPRESS_NONE;
hole_em->generation = trans->transid;
Expand Down Expand Up @@ -6156,6 +6163,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
goto not_found_em;
}

em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, item);
if (found_type == BTRFS_FILE_EXTENT_REG ||
found_type == BTRFS_FILE_EXTENT_PREALLOC) {
em->start = extent_start;
Expand Down Expand Up @@ -6487,7 +6495,7 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
}

em = create_pinned_em(inode, start, ins.offset, start, ins.objectid,
ins.offset, ins.offset, 0);
ins.offset, ins.offset, ins.offset, 0);
if (IS_ERR(em))
goto out;

Expand Down Expand Up @@ -6666,7 +6674,8 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
u64 len, u64 orig_start,
u64 block_start, u64 block_len,
u64 orig_block_len, int type)
u64 orig_block_len, u64 ram_bytes,
int type)
{
struct extent_map_tree *em_tree;
struct extent_map *em;
Expand All @@ -6687,6 +6696,7 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
em->block_start = block_start;
em->bdev = root->fs_info->fs_devices->latest_bdev;
em->orig_block_len = orig_block_len;
em->ram_bytes = ram_bytes;
em->generation = -1;
set_bit(EXTENT_FLAG_PINNED, &em->flags);
if (type == BTRFS_ORDERED_PREALLOC)
Expand Down Expand Up @@ -6815,13 +6825,15 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
if (can_nocow_odirect(trans, inode, start, len) == 1) {
u64 orig_start = em->orig_start;
u64 orig_block_len = em->orig_block_len;
u64 ram_bytes = em->ram_bytes;

if (type == BTRFS_ORDERED_PREALLOC) {
free_extent_map(em);
em = create_pinned_em(inode, start, len,
orig_start,
block_start, len,
orig_block_len, type);
orig_block_len,
ram_bytes, type);
if (IS_ERR(em)) {
btrfs_end_transaction(trans, root);
goto unlock_err;
Expand Down Expand Up @@ -8574,6 +8586,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
em->block_start = ins.objectid;
em->block_len = ins.offset;
em->orig_block_len = ins.offset;
em->ram_bytes = ins.offset;
em->bdev = root->fs_info->fs_devices->latest_bdev;
set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
em->generation = trans->transid;
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/tree-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -3410,7 +3410,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
em->start - em->orig_start,
&token);
btrfs_set_token_file_extent_num_bytes(leaf, fi, em->len, &token);
btrfs_set_token_file_extent_ram_bytes(leaf, fi, em->len, &token);
btrfs_set_token_file_extent_ram_bytes(leaf, fi, em->ram_bytes, &token);
btrfs_set_token_file_extent_compression(leaf, fi, em->compress_type,
&token);
btrfs_set_token_file_extent_encryption(leaf, fi, 0, &token);
Expand Down

0 comments on commit cc95bef

Please sign in to comment.