diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1695440a59a4..13a4aa222861 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1385,7 +1385,8 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, | |||
1385 | */ | 1385 | */ |
1386 | static int __btrfs_submit_bio_start(struct inode *inode, int rw, | 1386 | static int __btrfs_submit_bio_start(struct inode *inode, int rw, |
1387 | struct bio *bio, int mirror_num, | 1387 | struct bio *bio, int mirror_num, |
1388 | unsigned long bio_flags) | 1388 | unsigned long bio_flags, |
1389 | u64 bio_offset) | ||
1389 | { | 1390 | { |
1390 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1391 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1391 | int ret = 0; | 1392 | int ret = 0; |
@@ -1404,7 +1405,8 @@ static int __btrfs_submit_bio_start(struct inode *inode, int rw, | |||
1404 | * are inserted into the btree | 1405 | * are inserted into the btree |
1405 | */ | 1406 | */ |
1406 | static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | 1407 | static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio, |
1407 | int mirror_num, unsigned long bio_flags) | 1408 | int mirror_num, unsigned long bio_flags, |
1409 | u64 bio_offset) | ||
1408 | { | 1410 | { |
1409 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1411 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1410 | return btrfs_map_bio(root, rw, bio, mirror_num, 1); | 1412 | return btrfs_map_bio(root, rw, bio, mirror_num, 1); |
@@ -1415,7 +1417,8 @@ static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | |||
1415 | * on write, or reading the csums from the tree before a read | 1417 | * on write, or reading the csums from the tree before a read |
1416 | */ | 1418 | */ |
1417 | static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | 1419 | static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, |
1418 | int mirror_num, unsigned long bio_flags) | 1420 | int mirror_num, unsigned long bio_flags, |
1421 | u64 bio_offset) | ||
1419 | { | 1422 | { |
1420 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1423 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1421 | int ret = 0; | 1424 | int ret = 0; |
@@ -1440,7 +1443,8 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
1440 | /* we're doing a write, do the async checksumming */ | 1443 | /* we're doing a write, do the async checksumming */ |
1441 | return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | 1444 | return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, |
1442 | inode, rw, bio, mirror_num, | 1445 | inode, rw, bio, mirror_num, |
1443 | bio_flags, __btrfs_submit_bio_start, | 1446 | bio_flags, bio_offset, |
1447 | __btrfs_submit_bio_start, | ||
1444 | __btrfs_submit_bio_done); | 1448 | __btrfs_submit_bio_done); |
1445 | } | 1449 | } |
1446 | 1450 | ||
@@ -1844,7 +1848,7 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, | |||
1844 | 1848 | ||
1845 | BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio, | 1849 | BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio, |
1846 | failrec->last_mirror, | 1850 | failrec->last_mirror, |
1847 | failrec->bio_flags); | 1851 | failrec->bio_flags, 0); |
1848 | return 0; | 1852 | return 0; |
1849 | } | 1853 | } |
1850 | 1854 | ||
@@ -5484,6 +5488,17 @@ out_done: | |||
5484 | dio_end_io(bio, err); | 5488 | dio_end_io(bio, err); |
5485 | } | 5489 | } |
5486 | 5490 | ||
5491 | static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, | ||
5492 | struct bio *bio, int mirror_num, | ||
5493 | unsigned long bio_flags, u64 offset) | ||
5494 | { | ||
5495 | int ret; | ||
5496 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
5497 | ret = btrfs_csum_one_bio(root, inode, bio, offset, 1); | ||
5498 | BUG_ON(ret); | ||
5499 | return 0; | ||
5500 | } | ||
5501 | |||
5487 | static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | 5502 | static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, |
5488 | loff_t file_offset) | 5503 | loff_t file_offset) |
5489 | { | 5504 | { |
@@ -5535,13 +5550,20 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | |||
5535 | if (ret) | 5550 | if (ret) |
5536 | goto out_err; | 5551 | goto out_err; |
5537 | 5552 | ||
5538 | if (write && !skip_sum) | 5553 | if (write && !skip_sum) { |
5539 | btrfs_csum_one_bio(root, inode, bio, dip->logical_offset, 1); | 5554 | ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, |
5540 | else if (!skip_sum) | 5555 | inode, rw, bio, 0, 0, |
5556 | dip->logical_offset, | ||
5557 | __btrfs_submit_bio_start_direct_io, | ||
5558 | __btrfs_submit_bio_done); | ||
5559 | if (ret) | ||
5560 | goto out_err; | ||
5561 | return; | ||
5562 | } else if (!skip_sum) | ||
5541 | btrfs_lookup_bio_sums_dio(root, inode, bio, | 5563 | btrfs_lookup_bio_sums_dio(root, inode, bio, |
5542 | dip->logical_offset, dip->csums); | 5564 | dip->logical_offset, dip->csums); |
5543 | 5565 | ||
5544 | ret = btrfs_map_bio(root, rw, bio, 0, 0); | 5566 | ret = btrfs_map_bio(root, rw, bio, 0, 1); |
5545 | if (ret) | 5567 | if (ret) |
5546 | goto out_err; | 5568 | goto out_err; |
5547 | return; | 5569 | return; |