diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-09 16:28:12 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:01 -0400 |
commit | 22c599485b1fdd95e4476a4752596a6cf6c6629a (patch) | |
tree | f34285bfb545cf7abed9be6ad12a61e80dbb4bb5 /fs/btrfs/disk-io.c | |
parent | ce9adaa5a792c2099a83246265eb4055bc38b6b8 (diff) |
Btrfs: Handle data block end_io through the async work queue
Before it was done by the bio end_io routine, the work queue code is able
to scale much better with faster IO subsystems.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 82109204788c..94ff87d0eae4 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -54,6 +54,7 @@ struct end_io_wq { | |||
54 | void *private; | 54 | void *private; |
55 | struct btrfs_fs_info *info; | 55 | struct btrfs_fs_info *info; |
56 | int error; | 56 | int error; |
57 | int metadata; | ||
57 | struct list_head list; | 58 | struct list_head list; |
58 | }; | 59 | }; |
59 | 60 | ||
@@ -308,29 +309,40 @@ static int end_workqueue_bio(struct bio *bio, | |||
308 | #endif | 309 | #endif |
309 | } | 310 | } |
310 | 311 | ||
311 | static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio) | 312 | int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, |
313 | int metadata) | ||
312 | { | 314 | { |
313 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
314 | struct end_io_wq *end_io_wq; | 315 | struct end_io_wq *end_io_wq; |
315 | u64 offset; | ||
316 | offset = bio->bi_sector << 9; | ||
317 | |||
318 | if (rw & (1 << BIO_RW)) { | ||
319 | return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio); | ||
320 | } | ||
321 | |||
322 | end_io_wq = kmalloc(sizeof(*end_io_wq), GFP_NOFS); | 316 | end_io_wq = kmalloc(sizeof(*end_io_wq), GFP_NOFS); |
323 | if (!end_io_wq) | 317 | if (!end_io_wq) |
324 | return -ENOMEM; | 318 | return -ENOMEM; |
325 | 319 | ||
326 | end_io_wq->private = bio->bi_private; | 320 | end_io_wq->private = bio->bi_private; |
327 | end_io_wq->end_io = bio->bi_end_io; | 321 | end_io_wq->end_io = bio->bi_end_io; |
328 | end_io_wq->info = root->fs_info; | 322 | end_io_wq->info = info; |
329 | end_io_wq->error = 0; | 323 | end_io_wq->error = 0; |
330 | end_io_wq->bio = bio; | 324 | end_io_wq->bio = bio; |
325 | end_io_wq->metadata = metadata; | ||
331 | 326 | ||
332 | bio->bi_private = end_io_wq; | 327 | bio->bi_private = end_io_wq; |
333 | bio->bi_end_io = end_workqueue_bio; | 328 | bio->bi_end_io = end_workqueue_bio; |
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio) | ||
333 | { | ||
334 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
335 | u64 offset; | ||
336 | int ret; | ||
337 | |||
338 | offset = bio->bi_sector << 9; | ||
339 | |||
340 | if (rw & (1 << BIO_RW)) { | ||
341 | return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio); | ||
342 | } | ||
343 | |||
344 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 1); | ||
345 | BUG_ON(ret); | ||
334 | 346 | ||
335 | if (offset == BTRFS_SUPER_INFO_OFFSET) { | 347 | if (offset == BTRFS_SUPER_INFO_OFFSET) { |
336 | bio->bi_bdev = root->fs_info->sb->s_bdev; | 348 | bio->bi_bdev = root->fs_info->sb->s_bdev; |
@@ -880,7 +892,7 @@ void btrfs_end_io_csum(struct work_struct *work) | |||
880 | end_io_wq = list_entry(next, struct end_io_wq, list); | 892 | end_io_wq = list_entry(next, struct end_io_wq, list); |
881 | 893 | ||
882 | bio = end_io_wq->bio; | 894 | bio = end_io_wq->bio; |
883 | if (!bio_ready_for_csum(bio)) { | 895 | if (end_io_wq->metadata && !bio_ready_for_csum(bio)) { |
884 | spin_lock_irqsave(&fs_info->end_io_work_lock, flags); | 896 | spin_lock_irqsave(&fs_info->end_io_work_lock, flags); |
885 | was_empty = list_empty(&fs_info->end_io_work_list); | 897 | was_empty = list_empty(&fs_info->end_io_work_list); |
886 | list_add_tail(&end_io_wq->list, | 898 | list_add_tail(&end_io_wq->list, |