diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-29 14:36:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-29 14:36:22 -0400 |
commit | 318e15101993c0fdc3f23f24ac61fc7769d27e68 (patch) | |
tree | 98e2805502dc83f64c632706aabe06391469df32 /fs/btrfs/disk-io.c | |
parent | a7ccbcf3307022c48810eebd99aa8dba84f13caf (diff) | |
parent | 256dd1bb3750ac5ad49b40887c1691788dc44b33 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason:
"I've split out the big send/receive update from my last pull request
and now have just the fixes in my for-linus branch. The send/recv
branch will wander over to linux-next shortly though.
The largest patches in this pull are Josef's patches to fix DIO
locking problems and his patch to fix a crash during balance. They
are both well tested.
The rest are smaller fixes that we've had queued. The last rc came
out while I was hacking new and exciting ways to recover from a
misplaced rm -rf on my dev box, so these missed rc3."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (25 commits)
Btrfs: fix that repair code is spuriously executed for transid failures
Btrfs: fix ordered extent leak when failing to start a transaction
Btrfs: fix a dio write regression
Btrfs: fix deadlock with freeze and sync V2
Btrfs: revert checksum error statistic which can cause a BUG()
Btrfs: remove superblock writing after fatal error
Btrfs: allow delayed refs to be merged
Btrfs: fix enospc problems when deleting a subvol
Btrfs: fix wrong mtime and ctime when creating snapshots
Btrfs: fix race in run_clustered_refs
Btrfs: don't run __tree_mod_log_free_eb on leaves
Btrfs: increase the size of the free space cache
Btrfs: barrier before waitqueue_active
Btrfs: fix deadlock in wait_for_more_refs
btrfs: fix second lock in btrfs_delete_delayed_items()
Btrfs: don't allocate a seperate csums array for direct reads
Btrfs: do not strdup non existent strings
Btrfs: do not use missing devices when showing devname
Btrfs: fix that error value is changed by mistake
Btrfs: lock extents as we map them in DIO
...
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 53 |
1 files changed, 14 insertions, 39 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62e0cafd6e25..22e98e04c2ea 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -377,9 +377,13 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, | |||
377 | ret = read_extent_buffer_pages(io_tree, eb, start, | 377 | ret = read_extent_buffer_pages(io_tree, eb, start, |
378 | WAIT_COMPLETE, | 378 | WAIT_COMPLETE, |
379 | btree_get_extent, mirror_num); | 379 | btree_get_extent, mirror_num); |
380 | if (!ret && !verify_parent_transid(io_tree, eb, | 380 | if (!ret) { |
381 | if (!verify_parent_transid(io_tree, eb, | ||
381 | parent_transid, 0)) | 382 | parent_transid, 0)) |
382 | break; | 383 | break; |
384 | else | ||
385 | ret = -EIO; | ||
386 | } | ||
383 | 387 | ||
384 | /* | 388 | /* |
385 | * This buffer's crc is fine, but its contents are corrupted, so | 389 | * This buffer's crc is fine, but its contents are corrupted, so |
@@ -754,9 +758,7 @@ static void run_one_async_done(struct btrfs_work *work) | |||
754 | limit = btrfs_async_submit_limit(fs_info); | 758 | limit = btrfs_async_submit_limit(fs_info); |
755 | limit = limit * 2 / 3; | 759 | limit = limit * 2 / 3; |
756 | 760 | ||
757 | atomic_dec(&fs_info->nr_async_submits); | 761 | if (atomic_dec_return(&fs_info->nr_async_submits) < limit && |
758 | |||
759 | if (atomic_read(&fs_info->nr_async_submits) < limit && | ||
760 | waitqueue_active(&fs_info->async_submit_wait)) | 762 | waitqueue_active(&fs_info->async_submit_wait)) |
761 | wake_up(&fs_info->async_submit_wait); | 763 | wake_up(&fs_info->async_submit_wait); |
762 | 764 | ||
@@ -2032,8 +2034,6 @@ int open_ctree(struct super_block *sb, | |||
2032 | fs_info->free_chunk_space = 0; | 2034 | fs_info->free_chunk_space = 0; |
2033 | fs_info->tree_mod_log = RB_ROOT; | 2035 | fs_info->tree_mod_log = RB_ROOT; |
2034 | 2036 | ||
2035 | init_waitqueue_head(&fs_info->tree_mod_seq_wait); | ||
2036 | |||
2037 | /* readahead state */ | 2037 | /* readahead state */ |
2038 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); | 2038 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); |
2039 | spin_lock_init(&fs_info->reada_lock); | 2039 | spin_lock_init(&fs_info->reada_lock); |
@@ -2528,8 +2528,7 @@ retry_root_backup: | |||
2528 | goto fail_trans_kthread; | 2528 | goto fail_trans_kthread; |
2529 | 2529 | ||
2530 | /* do not make disk changes in broken FS */ | 2530 | /* do not make disk changes in broken FS */ |
2531 | if (btrfs_super_log_root(disk_super) != 0 && | 2531 | if (btrfs_super_log_root(disk_super) != 0) { |
2532 | !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) { | ||
2533 | u64 bytenr = btrfs_super_log_root(disk_super); | 2532 | u64 bytenr = btrfs_super_log_root(disk_super); |
2534 | 2533 | ||
2535 | if (fs_devices->rw_devices == 0) { | 2534 | if (fs_devices->rw_devices == 0) { |
@@ -3189,30 +3188,14 @@ int close_ctree(struct btrfs_root *root) | |||
3189 | /* clear out the rbtree of defraggable inodes */ | 3188 | /* clear out the rbtree of defraggable inodes */ |
3190 | btrfs_run_defrag_inodes(fs_info); | 3189 | btrfs_run_defrag_inodes(fs_info); |
3191 | 3190 | ||
3192 | /* | ||
3193 | * Here come 2 situations when btrfs is broken to flip readonly: | ||
3194 | * | ||
3195 | * 1. when btrfs flips readonly somewhere else before | ||
3196 | * btrfs_commit_super, sb->s_flags has MS_RDONLY flag, | ||
3197 | * and btrfs will skip to write sb directly to keep | ||
3198 | * ERROR state on disk. | ||
3199 | * | ||
3200 | * 2. when btrfs flips readonly just in btrfs_commit_super, | ||
3201 | * and in such case, btrfs cannot write sb via btrfs_commit_super, | ||
3202 | * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag, | ||
3203 | * btrfs will cleanup all FS resources first and write sb then. | ||
3204 | */ | ||
3205 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { | 3191 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { |
3206 | ret = btrfs_commit_super(root); | 3192 | ret = btrfs_commit_super(root); |
3207 | if (ret) | 3193 | if (ret) |
3208 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); | 3194 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); |
3209 | } | 3195 | } |
3210 | 3196 | ||
3211 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 3197 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) |
3212 | ret = btrfs_error_commit_super(root); | 3198 | btrfs_error_commit_super(root); |
3213 | if (ret) | ||
3214 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); | ||
3215 | } | ||
3216 | 3199 | ||
3217 | btrfs_put_block_group_cache(fs_info); | 3200 | btrfs_put_block_group_cache(fs_info); |
3218 | 3201 | ||
@@ -3434,18 +3417,11 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | |||
3434 | if (read_only) | 3417 | if (read_only) |
3435 | return 0; | 3418 | return 0; |
3436 | 3419 | ||
3437 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | ||
3438 | printk(KERN_WARNING "warning: mount fs with errors, " | ||
3439 | "running btrfsck is recommended\n"); | ||
3440 | } | ||
3441 | |||
3442 | return 0; | 3420 | return 0; |
3443 | } | 3421 | } |
3444 | 3422 | ||
3445 | int btrfs_error_commit_super(struct btrfs_root *root) | 3423 | void btrfs_error_commit_super(struct btrfs_root *root) |
3446 | { | 3424 | { |
3447 | int ret; | ||
3448 | |||
3449 | mutex_lock(&root->fs_info->cleaner_mutex); | 3425 | mutex_lock(&root->fs_info->cleaner_mutex); |
3450 | btrfs_run_delayed_iputs(root); | 3426 | btrfs_run_delayed_iputs(root); |
3451 | mutex_unlock(&root->fs_info->cleaner_mutex); | 3427 | mutex_unlock(&root->fs_info->cleaner_mutex); |
@@ -3455,10 +3431,6 @@ int btrfs_error_commit_super(struct btrfs_root *root) | |||
3455 | 3431 | ||
3456 | /* cleanup FS via transaction */ | 3432 | /* cleanup FS via transaction */ |
3457 | btrfs_cleanup_transaction(root); | 3433 | btrfs_cleanup_transaction(root); |
3458 | |||
3459 | ret = write_ctree_super(NULL, root, 0); | ||
3460 | |||
3461 | return ret; | ||
3462 | } | 3434 | } |
3463 | 3435 | ||
3464 | static void btrfs_destroy_ordered_operations(struct btrfs_root *root) | 3436 | static void btrfs_destroy_ordered_operations(struct btrfs_root *root) |
@@ -3782,14 +3754,17 @@ int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
3782 | /* FIXME: cleanup wait for commit */ | 3754 | /* FIXME: cleanup wait for commit */ |
3783 | t->in_commit = 1; | 3755 | t->in_commit = 1; |
3784 | t->blocked = 1; | 3756 | t->blocked = 1; |
3757 | smp_mb(); | ||
3785 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) | 3758 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) |
3786 | wake_up(&root->fs_info->transaction_blocked_wait); | 3759 | wake_up(&root->fs_info->transaction_blocked_wait); |
3787 | 3760 | ||
3788 | t->blocked = 0; | 3761 | t->blocked = 0; |
3762 | smp_mb(); | ||
3789 | if (waitqueue_active(&root->fs_info->transaction_wait)) | 3763 | if (waitqueue_active(&root->fs_info->transaction_wait)) |
3790 | wake_up(&root->fs_info->transaction_wait); | 3764 | wake_up(&root->fs_info->transaction_wait); |
3791 | 3765 | ||
3792 | t->commit_done = 1; | 3766 | t->commit_done = 1; |
3767 | smp_mb(); | ||
3793 | if (waitqueue_active(&t->commit_wait)) | 3768 | if (waitqueue_active(&t->commit_wait)) |
3794 | wake_up(&t->commit_wait); | 3769 | wake_up(&t->commit_wait); |
3795 | 3770 | ||