aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-29 14:13:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-29 14:13:25 -0400
commit3615db41c4b82896de450b6b4e3dab2420dcae51 (patch)
tree9ef91db29c1aa57fe7354ec2ee3fa682f9c6547d /fs/btrfs/inode.c
parented176886b68fbc450ddbe808684a142fcad72b56 (diff)
parentd8fe29e9dea8d7d61fd140d8779326856478fc62 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "We've had a busy two weeks of bug fixing. The biggest patches in here are some long standing early-enospc problems (Josef) and a very old race where compression and mmap combine forces to lose writes (me). I'm fairly sure the mmap bug goes all the way back to the introduction of the compression code, which is proof that fsx doesn't trigger every possible mmap corner after all. I'm sure you'll notice one of these is from this morning, it's a small and isolated use-after-free fix in our scrub error reporting. I double checked it here." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: don't drop path when printing out tree errors in scrub Btrfs: fix wrong return value of btrfs_lookup_csum() Btrfs: fix wrong reservation of csums Btrfs: fix double free in the btrfs_qgroup_account_ref() Btrfs: limit the global reserve to 512mb Btrfs: hold the ordered operations mutex when waiting on ordered extents Btrfs: fix space accounting for unlink and rename Btrfs: fix space leak when we fail to reserve metadata space Btrfs: fix EIO from btrfs send in is_extent_unchanged for punched holes Btrfs: fix race between mmap writes and compression Btrfs: fix memory leak in btrfs_create_tree() Btrfs: fix locking on ROOT_REPLACE operations in tree mod log Btrfs: fix missing qgroup reservation before fallocating Btrfs: handle a bogus chunk tree nicely Btrfs: update to use fs_state bit
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ca1b767d51f7..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}
@@ -3679,11 +3695,9 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
3679 * 1 for the dir item 3695 * 1 for the dir item
3680 * 1 for the dir index 3696 * 1 for the dir index
3681 * 1 for the inode ref 3697 * 1 for the inode ref
3682 * 1 for the inode ref in the tree log
3683 * 2 for the dir entries in the log
3684 * 1 for the inode 3698 * 1 for the inode
3685 */ 3699 */
3686 trans = btrfs_start_transaction(root, 8); 3700 trans = btrfs_start_transaction(root, 5);
3687 if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC) 3701 if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
3688 return trans; 3702 return trans;
3689 3703
@@ -8127,7 +8141,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
8127 * 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
8128 * should cover the worst case number of items we'll modify. 8142 * should cover the worst case number of items we'll modify.
8129 */ 8143 */
8130 trans = btrfs_start_transaction(root, 20); 8144 trans = btrfs_start_transaction(root, 11);
8131 if (IS_ERR(trans)) { 8145 if (IS_ERR(trans)) {
8132 ret = PTR_ERR(trans); 8146 ret = PTR_ERR(trans);
8133 goto out_notrans; 8147 goto out_notrans;