aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-05-25 09:48:28 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-25 10:34:58 -0400
commiteaf25d933e64c2bf3c79b83e8820404f36fdfc52 (patch)
tree649dc862fcc9a243bdc925db34da618b25a275fc /fs/btrfs/inode.c
parented3b3d314cd2f16fac42676839854a68cab2e22b (diff)
Btrfs: use async helpers for DIO write checksumming
The async helper threads offload crc work onto all the CPUs, and make streaming writes much faster. This changes the O_DIRECT write code to use them. The only small complication was that we need to pass in the logical offset in the file for each bio, because we can't find it in the bio's pages. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c40
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 */
1386static int __btrfs_submit_bio_start(struct inode *inode, int rw, 1386static 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 */
1406static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio, 1407static 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 */
1417static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, 1419static 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
5491static 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
5487static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, 5502static 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;