diff options
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 11 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 13 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 1 |
4 files changed, 22 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2775e270881e..0079b60b18f3 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -610,6 +610,7 @@ struct btrfs_fs_info { | |||
610 | struct list_head dead_roots; | 610 | struct list_head dead_roots; |
611 | 611 | ||
612 | atomic_t nr_async_submits; | 612 | atomic_t nr_async_submits; |
613 | atomic_t async_submit_draining; | ||
613 | atomic_t nr_async_bios; | 614 | atomic_t nr_async_bios; |
614 | atomic_t tree_log_writers; | 615 | atomic_t tree_log_writers; |
615 | atomic_t tree_log_commit; | 616 | atomic_t tree_log_commit; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 45bc3132b054..45b4f7285275 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -460,6 +460,13 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
460 | async->submit_bio_hook = submit_bio_hook; | 460 | async->submit_bio_hook = submit_bio_hook; |
461 | async->work.func = run_one_async_submit; | 461 | async->work.func = run_one_async_submit; |
462 | async->work.flags = 0; | 462 | async->work.flags = 0; |
463 | |||
464 | while(atomic_read(&fs_info->async_submit_draining) && | ||
465 | atomic_read(&fs_info->nr_async_submits)) { | ||
466 | wait_event(fs_info->async_submit_wait, | ||
467 | (atomic_read(&fs_info->nr_async_submits) == 0)); | ||
468 | } | ||
469 | |||
463 | atomic_inc(&fs_info->nr_async_submits); | 470 | atomic_inc(&fs_info->nr_async_submits); |
464 | btrfs_queue_worker(&fs_info->workers, &async->work); | 471 | btrfs_queue_worker(&fs_info->workers, &async->work); |
465 | 472 | ||
@@ -495,11 +502,8 @@ static int __btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
495 | int mirror_num) | 502 | int mirror_num) |
496 | { | 503 | { |
497 | struct btrfs_root *root = BTRFS_I(inode)->root; | 504 | struct btrfs_root *root = BTRFS_I(inode)->root; |
498 | u64 offset; | ||
499 | int ret; | 505 | int ret; |
500 | 506 | ||
501 | offset = bio->bi_sector << 9; | ||
502 | |||
503 | /* | 507 | /* |
504 | * when we're called for a write, we're already in the async | 508 | * when we're called for a write, we're already in the async |
505 | * submission context. Just jump into btrfs_map_bio | 509 | * submission context. Just jump into btrfs_map_bio |
@@ -1360,6 +1364,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1360 | INIT_LIST_HEAD(&fs_info->space_info); | 1364 | INIT_LIST_HEAD(&fs_info->space_info); |
1361 | btrfs_mapping_init(&fs_info->mapping_tree); | 1365 | btrfs_mapping_init(&fs_info->mapping_tree); |
1362 | atomic_set(&fs_info->nr_async_submits, 0); | 1366 | atomic_set(&fs_info->nr_async_submits, 0); |
1367 | atomic_set(&fs_info->async_submit_draining, 0); | ||
1363 | atomic_set(&fs_info->nr_async_bios, 0); | 1368 | atomic_set(&fs_info->nr_async_bios, 0); |
1364 | atomic_set(&fs_info->throttles, 0); | 1369 | atomic_set(&fs_info->throttles, 0); |
1365 | atomic_set(&fs_info->throttle_gen, 0); | 1370 | atomic_set(&fs_info->throttle_gen, 0); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4516fbf01671..404704d26822 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3440,13 +3440,24 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root) | |||
3440 | list_del_init(&binode->delalloc_inodes); | 3440 | list_del_init(&binode->delalloc_inodes); |
3441 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 3441 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); |
3442 | if (inode) { | 3442 | if (inode) { |
3443 | filemap_write_and_wait(inode->i_mapping); | 3443 | filemap_flush(inode->i_mapping); |
3444 | iput(inode); | 3444 | iput(inode); |
3445 | } | 3445 | } |
3446 | cond_resched(); | 3446 | cond_resched(); |
3447 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 3447 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); |
3448 | } | 3448 | } |
3449 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 3449 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); |
3450 | |||
3451 | /* the filemap_flush will queue IO into the worker threads, but | ||
3452 | * we have to make sure the IO is actually started and that | ||
3453 | * ordered extents get created before we return | ||
3454 | */ | ||
3455 | atomic_inc(&root->fs_info->async_submit_draining); | ||
3456 | while(atomic_read(&root->fs_info->nr_async_submits)) { | ||
3457 | wait_event(root->fs_info->async_submit_wait, | ||
3458 | (atomic_read(&root->fs_info->nr_async_submits) == 0)); | ||
3459 | } | ||
3460 | atomic_dec(&root->fs_info->async_submit_draining); | ||
3450 | return 0; | 3461 | return 0; |
3451 | } | 3462 | } |
3452 | 3463 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 51f113119b25..f63cf7621a01 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1038,6 +1038,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1038 | return -EIO; | 1038 | return -EIO; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | filemap_write_and_wait(bdev->bd_inode->i_mapping); | ||
1041 | mutex_lock(&root->fs_info->volume_mutex); | 1042 | mutex_lock(&root->fs_info->volume_mutex); |
1042 | 1043 | ||
1043 | trans = btrfs_start_transaction(root, 1); | 1044 | trans = btrfs_start_transaction(root, 1); |