aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-02-20 12:07:25 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit065631f6dccea07bfad48d8981369f6d9cfd6e2b (patch)
treed9d5736f61d225d0418cf298092ac36fbe6099e2 /fs/btrfs/inode.c
parent0740c82bc7585a23e100c9a59d5e2abbf99459fb (diff)
Btrfs: checksum file data at bio submission time instead of during writepage
When we checkum file data during writepage, the checksumming is done one page at a time, making it difficult to do bulk metadata modifications to insert checksums for large ranges of the file at once. This patch changes btrfs to checksum on a per-bio basis instead. The bios are checksummed before they are handed off to the block layer, so each bio is contiguous and only has pages from the same inode. Checksumming on a bio basis allows us to insert and modify the file checksum items in large groups. It also allows the checksumming to be done more easily by async worker threads. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3e79572a5cb1..bbb71fad861a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -16,6 +16,7 @@
16 * Boston, MA 021110-1307, USA. 16 * Boston, MA 021110-1307, USA.
17 */ 17 */
18 18
19#include <linux/bio.h>
19#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
20#include <linux/fs.h> 21#include <linux/fs.h>
21#include <linux/pagemap.h> 22#include <linux/pagemap.h>
@@ -294,6 +295,32 @@ int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
294 return 0; 295 return 0;
295} 296}
296 297
298int btrfs_submit_bio_hook(int rw, struct bio *bio)
299{
300 // struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
301 struct bio_vec *bvec = bio->bi_io_vec;
302 struct inode *inode = bvec->bv_page->mapping->host;
303 struct btrfs_root *root = BTRFS_I(inode)->root;
304 struct btrfs_trans_handle *trans;
305 int ret = 0;
306
307 if (rw != WRITE)
308 return 0;
309
310 if (btrfs_test_opt(root, NODATASUM) ||
311 btrfs_test_flag(inode, NODATASUM))
312 return 0;
313
314 mutex_lock(&root->fs_info->fs_mutex);
315 trans = btrfs_start_transaction(root, 1);
316 btrfs_set_trans_block_group(trans, inode);
317 btrfs_csum_file_blocks(trans, root, inode, bio);
318 ret = btrfs_end_transaction(trans, root);
319 BUG_ON(ret);
320 mutex_unlock(&root->fs_info->fs_mutex);
321 return ret;
322}
323#if 0
297int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end) 324int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
298{ 325{
299 struct inode *inode = page->mapping->host; 326 struct inode *inode = page->mapping->host;
@@ -318,7 +345,7 @@ int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
318 mutex_unlock(&root->fs_info->fs_mutex); 345 mutex_unlock(&root->fs_info->fs_mutex);
319 return ret; 346 return ret;
320} 347}
321 348#endif
322int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) 349int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
323{ 350{
324 int ret = 0; 351 int ret = 0;
@@ -3022,7 +3049,8 @@ static struct file_operations btrfs_dir_file_operations = {
3022 3049
3023static struct extent_io_ops btrfs_extent_io_ops = { 3050static struct extent_io_ops btrfs_extent_io_ops = {
3024 .fill_delalloc = run_delalloc_range, 3051 .fill_delalloc = run_delalloc_range,
3025 .writepage_io_hook = btrfs_writepage_io_hook, 3052 // .writepage_io_hook = btrfs_writepage_io_hook,
3053 .submit_bio_hook = btrfs_submit_bio_hook,
3026 .readpage_io_hook = btrfs_readpage_io_hook, 3054 .readpage_io_hook = btrfs_readpage_io_hook,
3027 .readpage_end_io_hook = btrfs_readpage_end_io_hook, 3055 .readpage_end_io_hook = btrfs_readpage_end_io_hook,
3028 .set_bit_hook = btrfs_set_bit_hook, 3056 .set_bit_hook = btrfs_set_bit_hook,