diff options
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r-- | fs/btrfs/ordered-data.c | 52 |
1 files changed, 18 insertions, 34 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 81369827e514..c702cb62f78a 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -67,7 +67,7 @@ static void ordered_data_tree_panic(struct inode *inode, int errno, | |||
67 | { | 67 | { |
68 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 68 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
69 | btrfs_panic(fs_info, errno, "Inconsistency in ordered tree at offset " | 69 | btrfs_panic(fs_info, errno, "Inconsistency in ordered tree at offset " |
70 | "%llu\n", (unsigned long long)offset); | 70 | "%llu\n", offset); |
71 | } | 71 | } |
72 | 72 | ||
73 | /* | 73 | /* |
@@ -205,6 +205,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
205 | entry->bytes_left = len; | 205 | entry->bytes_left = len; |
206 | entry->inode = igrab(inode); | 206 | entry->inode = igrab(inode); |
207 | entry->compress_type = compress_type; | 207 | entry->compress_type = compress_type; |
208 | entry->truncated_len = (u64)-1; | ||
208 | if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) | 209 | if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) |
209 | set_bit(type, &entry->flags); | 210 | set_bit(type, &entry->flags); |
210 | 211 | ||
@@ -336,14 +337,12 @@ int btrfs_dec_test_first_ordered_pending(struct inode *inode, | |||
336 | *file_offset = dec_end; | 337 | *file_offset = dec_end; |
337 | if (dec_start > dec_end) { | 338 | if (dec_start > dec_end) { |
338 | printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n", | 339 | printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n", |
339 | (unsigned long long)dec_start, | 340 | dec_start, dec_end); |
340 | (unsigned long long)dec_end); | ||
341 | } | 341 | } |
342 | to_dec = dec_end - dec_start; | 342 | to_dec = dec_end - dec_start; |
343 | if (to_dec > entry->bytes_left) { | 343 | if (to_dec > entry->bytes_left) { |
344 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", | 344 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", |
345 | (unsigned long long)entry->bytes_left, | 345 | entry->bytes_left, to_dec); |
346 | (unsigned long long)to_dec); | ||
347 | } | 346 | } |
348 | entry->bytes_left -= to_dec; | 347 | entry->bytes_left -= to_dec; |
349 | if (!uptodate) | 348 | if (!uptodate) |
@@ -403,8 +402,7 @@ have_entry: | |||
403 | 402 | ||
404 | if (io_size > entry->bytes_left) { | 403 | if (io_size > entry->bytes_left) { |
405 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", | 404 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", |
406 | (unsigned long long)entry->bytes_left, | 405 | entry->bytes_left, io_size); |
407 | (unsigned long long)io_size); | ||
408 | } | 406 | } |
409 | entry->bytes_left -= io_size; | 407 | entry->bytes_left -= io_size; |
410 | if (!uptodate) | 408 | if (!uptodate) |
@@ -565,11 +563,10 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work) | |||
565 | * wait for all the ordered extents in a root. This is done when balancing | 563 | * wait for all the ordered extents in a root. This is done when balancing |
566 | * space between drives. | 564 | * space between drives. |
567 | */ | 565 | */ |
568 | void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput) | 566 | void btrfs_wait_ordered_extents(struct btrfs_root *root) |
569 | { | 567 | { |
570 | struct list_head splice, works; | 568 | struct list_head splice, works; |
571 | struct btrfs_ordered_extent *ordered, *next; | 569 | struct btrfs_ordered_extent *ordered, *next; |
572 | struct inode *inode; | ||
573 | 570 | ||
574 | INIT_LIST_HEAD(&splice); | 571 | INIT_LIST_HEAD(&splice); |
575 | INIT_LIST_HEAD(&works); | 572 | INIT_LIST_HEAD(&works); |
@@ -582,15 +579,6 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput) | |||
582 | root_extent_list); | 579 | root_extent_list); |
583 | list_move_tail(&ordered->root_extent_list, | 580 | list_move_tail(&ordered->root_extent_list, |
584 | &root->ordered_extents); | 581 | &root->ordered_extents); |
585 | /* | ||
586 | * the inode may be getting freed (in sys_unlink path). | ||
587 | */ | ||
588 | inode = igrab(ordered->inode); | ||
589 | if (!inode) { | ||
590 | cond_resched_lock(&root->ordered_extent_lock); | ||
591 | continue; | ||
592 | } | ||
593 | |||
594 | atomic_inc(&ordered->refs); | 582 | atomic_inc(&ordered->refs); |
595 | spin_unlock(&root->ordered_extent_lock); | 583 | spin_unlock(&root->ordered_extent_lock); |
596 | 584 | ||
@@ -607,21 +595,13 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput) | |||
607 | list_for_each_entry_safe(ordered, next, &works, work_list) { | 595 | list_for_each_entry_safe(ordered, next, &works, work_list) { |
608 | list_del_init(&ordered->work_list); | 596 | list_del_init(&ordered->work_list); |
609 | wait_for_completion(&ordered->completion); | 597 | wait_for_completion(&ordered->completion); |
610 | |||
611 | inode = ordered->inode; | ||
612 | btrfs_put_ordered_extent(ordered); | 598 | btrfs_put_ordered_extent(ordered); |
613 | if (delay_iput) | ||
614 | btrfs_add_delayed_iput(inode); | ||
615 | else | ||
616 | iput(inode); | ||
617 | |||
618 | cond_resched(); | 599 | cond_resched(); |
619 | } | 600 | } |
620 | mutex_unlock(&root->fs_info->ordered_operations_mutex); | 601 | mutex_unlock(&root->fs_info->ordered_operations_mutex); |
621 | } | 602 | } |
622 | 603 | ||
623 | void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info, | 604 | void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info) |
624 | int delay_iput) | ||
625 | { | 605 | { |
626 | struct btrfs_root *root; | 606 | struct btrfs_root *root; |
627 | struct list_head splice; | 607 | struct list_head splice; |
@@ -639,7 +619,7 @@ void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info, | |||
639 | &fs_info->ordered_roots); | 619 | &fs_info->ordered_roots); |
640 | spin_unlock(&fs_info->ordered_root_lock); | 620 | spin_unlock(&fs_info->ordered_root_lock); |
641 | 621 | ||
642 | btrfs_wait_ordered_extents(root, delay_iput); | 622 | btrfs_wait_ordered_extents(root); |
643 | btrfs_put_fs_root(root); | 623 | btrfs_put_fs_root(root); |
644 | 624 | ||
645 | spin_lock(&fs_info->ordered_root_lock); | 625 | spin_lock(&fs_info->ordered_root_lock); |
@@ -671,7 +651,7 @@ int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans, | |||
671 | INIT_LIST_HEAD(&splice); | 651 | INIT_LIST_HEAD(&splice); |
672 | INIT_LIST_HEAD(&works); | 652 | INIT_LIST_HEAD(&works); |
673 | 653 | ||
674 | mutex_lock(&root->fs_info->ordered_operations_mutex); | 654 | mutex_lock(&root->fs_info->ordered_extent_flush_mutex); |
675 | spin_lock(&root->fs_info->ordered_root_lock); | 655 | spin_lock(&root->fs_info->ordered_root_lock); |
676 | list_splice_init(&cur_trans->ordered_operations, &splice); | 656 | list_splice_init(&cur_trans->ordered_operations, &splice); |
677 | while (!list_empty(&splice)) { | 657 | while (!list_empty(&splice)) { |
@@ -718,7 +698,7 @@ out: | |||
718 | list_del_init(&work->list); | 698 | list_del_init(&work->list); |
719 | btrfs_wait_and_free_delalloc_work(work); | 699 | btrfs_wait_and_free_delalloc_work(work); |
720 | } | 700 | } |
721 | mutex_unlock(&root->fs_info->ordered_operations_mutex); | 701 | mutex_unlock(&root->fs_info->ordered_extent_flush_mutex); |
722 | return ret; | 702 | return ret; |
723 | } | 703 | } |
724 | 704 | ||
@@ -923,12 +903,16 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
923 | struct btrfs_ordered_extent *test; | 903 | struct btrfs_ordered_extent *test; |
924 | int ret = 1; | 904 | int ret = 1; |
925 | 905 | ||
926 | if (ordered) | 906 | spin_lock_irq(&tree->lock); |
907 | if (ordered) { | ||
927 | offset = entry_end(ordered); | 908 | offset = entry_end(ordered); |
928 | else | 909 | if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags)) |
910 | offset = min(offset, | ||
911 | ordered->file_offset + | ||
912 | ordered->truncated_len); | ||
913 | } else { | ||
929 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | 914 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); |
930 | 915 | } | |
931 | spin_lock_irq(&tree->lock); | ||
932 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 916 | disk_i_size = BTRFS_I(inode)->disk_i_size; |
933 | 917 | ||
934 | /* truncate file */ | 918 | /* truncate file */ |