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:
Chris Mason
2014-01-03 21:07:00 -08:00
parent 23c6bf6a91
commit 514ac8ad87
6 changed files with 52 additions and 22 deletions

View File

@@ -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);