diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d1470adca8f8..09c58a35b429 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -353,6 +353,7 @@ static noinline int compress_file_range(struct inode *inode, | |||
353 | int i; | 353 | int i; |
354 | int will_compress; | 354 | int will_compress; |
355 | int compress_type = root->fs_info->compress_type; | 355 | int compress_type = root->fs_info->compress_type; |
356 | int redirty = 0; | ||
356 | 357 | ||
357 | /* if this is a small write inside eof, kick off a defrag */ | 358 | /* if this is a small write inside eof, kick off a defrag */ |
358 | if ((end - start + 1) < 16 * 1024 && | 359 | if ((end - start + 1) < 16 * 1024 && |
@@ -415,6 +416,17 @@ again: | |||
415 | if (BTRFS_I(inode)->force_compress) | 416 | if (BTRFS_I(inode)->force_compress) |
416 | compress_type = BTRFS_I(inode)->force_compress; | 417 | compress_type = BTRFS_I(inode)->force_compress; |
417 | 418 | ||
419 | /* | ||
420 | * we need to call clear_page_dirty_for_io on each | ||
421 | * page in the range. Otherwise applications with the file | ||
422 | * mmap'd can wander in and change the page contents while | ||
423 | * we are compressing them. | ||
424 | * | ||
425 | * If the compression fails for any reason, we set the pages | ||
426 | * dirty again later on. | ||
427 | */ | ||
428 | extent_range_clear_dirty_for_io(inode, start, end); | ||
429 | redirty = 1; | ||
418 | ret = btrfs_compress_pages(compress_type, | 430 | ret = btrfs_compress_pages(compress_type, |
419 | inode->i_mapping, start, | 431 | inode->i_mapping, start, |
420 | total_compressed, pages, | 432 | total_compressed, pages, |
@@ -554,6 +566,8 @@ cleanup_and_bail_uncompressed: | |||
554 | __set_page_dirty_nobuffers(locked_page); | 566 | __set_page_dirty_nobuffers(locked_page); |
555 | /* unlocked later on in the async handlers */ | 567 | /* unlocked later on in the async handlers */ |
556 | } | 568 | } |
569 | if (redirty) | ||
570 | extent_range_redirty_for_io(inode, start, end); | ||
557 | add_async_extent(async_cow, start, end - start + 1, | 571 | add_async_extent(async_cow, start, end - start + 1, |
558 | 0, NULL, 0, BTRFS_COMPRESS_NONE); | 572 | 0, NULL, 0, BTRFS_COMPRESS_NONE); |
559 | *num_added += 1; | 573 | *num_added += 1; |
@@ -1743,8 +1757,10 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
1743 | struct btrfs_ordered_sum *sum; | 1757 | struct btrfs_ordered_sum *sum; |
1744 | 1758 | ||
1745 | list_for_each_entry(sum, list, list) { | 1759 | list_for_each_entry(sum, list, list) { |
1760 | trans->adding_csums = 1; | ||
1746 | btrfs_csum_file_blocks(trans, | 1761 | btrfs_csum_file_blocks(trans, |
1747 | BTRFS_I(inode)->root->fs_info->csum_root, sum); | 1762 | BTRFS_I(inode)->root->fs_info->csum_root, sum); |
1763 | trans->adding_csums = 0; | ||
1748 | } | 1764 | } |
1749 | return 0; | 1765 | return 0; |
1750 | } | 1766 | } |
@@ -2312,6 +2328,7 @@ again: | |||
2312 | key.type = BTRFS_EXTENT_DATA_KEY; | 2328 | key.type = BTRFS_EXTENT_DATA_KEY; |
2313 | key.offset = start; | 2329 | key.offset = start; |
2314 | 2330 | ||
2331 | path->leave_spinning = 1; | ||
2315 | if (merge) { | 2332 | if (merge) { |
2316 | struct btrfs_file_extent_item *fi; | 2333 | struct btrfs_file_extent_item *fi; |
2317 | u64 extent_len; | 2334 | u64 extent_len; |
@@ -2368,6 +2385,7 @@ again: | |||
2368 | 2385 | ||
2369 | btrfs_mark_buffer_dirty(leaf); | 2386 | btrfs_mark_buffer_dirty(leaf); |
2370 | inode_add_bytes(inode, len); | 2387 | inode_add_bytes(inode, len); |
2388 | btrfs_release_path(path); | ||
2371 | 2389 | ||
2372 | ret = btrfs_inc_extent_ref(trans, root, new->bytenr, | 2390 | ret = btrfs_inc_extent_ref(trans, root, new->bytenr, |
2373 | new->disk_len, 0, | 2391 | new->disk_len, 0, |
@@ -2381,6 +2399,7 @@ again: | |||
2381 | ret = 1; | 2399 | ret = 1; |
2382 | out_free_path: | 2400 | out_free_path: |
2383 | btrfs_release_path(path); | 2401 | btrfs_release_path(path); |
2402 | path->leave_spinning = 0; | ||
2384 | btrfs_end_transaction(trans, root); | 2403 | btrfs_end_transaction(trans, root); |
2385 | out_unlock: | 2404 | out_unlock: |
2386 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end, | 2405 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end, |
@@ -3676,11 +3695,9 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir, | |||
3676 | * 1 for the dir item | 3695 | * 1 for the dir item |
3677 | * 1 for the dir index | 3696 | * 1 for the dir index |
3678 | * 1 for the inode ref | 3697 | * 1 for the inode ref |
3679 | * 1 for the inode ref in the tree log | ||
3680 | * 2 for the dir entries in the log | ||
3681 | * 1 for the inode | 3698 | * 1 for the inode |
3682 | */ | 3699 | */ |
3683 | trans = btrfs_start_transaction(root, 8); | 3700 | trans = btrfs_start_transaction(root, 5); |
3684 | if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC) | 3701 | if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC) |
3685 | return trans; | 3702 | return trans; |
3686 | 3703 | ||
@@ -8124,7 +8141,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
8124 | * inodes. So 5 * 2 is 10, plus 1 for the new link, so 11 total items | 8141 | * inodes. So 5 * 2 is 10, plus 1 for the new link, so 11 total items |
8125 | * should cover the worst case number of items we'll modify. | 8142 | * should cover the worst case number of items we'll modify. |
8126 | */ | 8143 | */ |
8127 | trans = btrfs_start_transaction(root, 20); | 8144 | trans = btrfs_start_transaction(root, 11); |
8128 | if (IS_ERR(trans)) { | 8145 | if (IS_ERR(trans)) { |
8129 | ret = PTR_ERR(trans); | 8146 | ret = PTR_ERR(trans); |
8130 | goto out_notrans; | 8147 | goto out_notrans; |