diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-01 19:08:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-01 19:08:34 -0400 |
commit | 82d2a348bb9a1e265fe1c62e39341128ec014ed9 (patch) | |
tree | f5ec3d92e66d6047d134f4278080437ad9562196 /fs/btrfs/disk-io.c | |
parent | 22fed39775c6f06e275075e1570e1cebb12593e0 (diff) | |
parent | 232cad8413a0bfbd25f11cc19fd13dfd85e1d8ad (diff) |
Merge branch 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason:
"This has a few fixes Dave Sterba had queued up. These are all pretty
small, but since they were tested I decided against waiting for more"
* 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
btrfs: transaction_kthread() is not freezable
btrfs: cleaner_kthread() doesn't need explicit freeze
btrfs: do not write corrupted metadata blocks to disk
btrfs: csum_tree_block: return proper errno value
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4b02591b0301..d01f89d130e0 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/buffer_head.h> | 25 | #include <linux/buffer_head.h> |
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
28 | #include <linux/freezer.h> | ||
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/migrate.h> | 29 | #include <linux/migrate.h> |
31 | #include <linux/ratelimit.h> | 30 | #include <linux/ratelimit.h> |
@@ -303,7 +302,7 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info, | |||
303 | err = map_private_extent_buffer(buf, offset, 32, | 302 | err = map_private_extent_buffer(buf, offset, 32, |
304 | &kaddr, &map_start, &map_len); | 303 | &kaddr, &map_start, &map_len); |
305 | if (err) | 304 | if (err) |
306 | return 1; | 305 | return err; |
307 | cur_len = min(len, map_len - (offset - map_start)); | 306 | cur_len = min(len, map_len - (offset - map_start)); |
308 | crc = btrfs_csum_data(kaddr + offset - map_start, | 307 | crc = btrfs_csum_data(kaddr + offset - map_start, |
309 | crc, cur_len); | 308 | crc, cur_len); |
@@ -313,7 +312,7 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info, | |||
313 | if (csum_size > sizeof(inline_result)) { | 312 | if (csum_size > sizeof(inline_result)) { |
314 | result = kzalloc(csum_size, GFP_NOFS); | 313 | result = kzalloc(csum_size, GFP_NOFS); |
315 | if (!result) | 314 | if (!result) |
316 | return 1; | 315 | return -ENOMEM; |
317 | } else { | 316 | } else { |
318 | result = (char *)&inline_result; | 317 | result = (char *)&inline_result; |
319 | } | 318 | } |
@@ -334,7 +333,7 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info, | |||
334 | val, found, btrfs_header_level(buf)); | 333 | val, found, btrfs_header_level(buf)); |
335 | if (result != (char *)&inline_result) | 334 | if (result != (char *)&inline_result) |
336 | kfree(result); | 335 | kfree(result); |
337 | return 1; | 336 | return -EUCLEAN; |
338 | } | 337 | } |
339 | } else { | 338 | } else { |
340 | write_extent_buffer(buf, result, 0, csum_size); | 339 | write_extent_buffer(buf, result, 0, csum_size); |
@@ -513,11 +512,21 @@ static int csum_dirty_buffer(struct btrfs_fs_info *fs_info, struct page *page) | |||
513 | eb = (struct extent_buffer *)page->private; | 512 | eb = (struct extent_buffer *)page->private; |
514 | if (page != eb->pages[0]) | 513 | if (page != eb->pages[0]) |
515 | return 0; | 514 | return 0; |
515 | |||
516 | found_start = btrfs_header_bytenr(eb); | 516 | found_start = btrfs_header_bytenr(eb); |
517 | if (WARN_ON(found_start != start || !PageUptodate(page))) | 517 | /* |
518 | return 0; | 518 | * Please do not consolidate these warnings into a single if. |
519 | csum_tree_block(fs_info, eb, 0); | 519 | * It is useful to know what went wrong. |
520 | return 0; | 520 | */ |
521 | if (WARN_ON(found_start != start)) | ||
522 | return -EUCLEAN; | ||
523 | if (WARN_ON(!PageUptodate(page))) | ||
524 | return -EUCLEAN; | ||
525 | |||
526 | ASSERT(memcmp_extent_buffer(eb, fs_info->fsid, | ||
527 | btrfs_header_fsid(), BTRFS_FSID_SIZE) == 0); | ||
528 | |||
529 | return csum_tree_block(fs_info, eb, 0); | ||
521 | } | 530 | } |
522 | 531 | ||
523 | static int check_tree_block_fsid(struct btrfs_fs_info *fs_info, | 532 | static int check_tree_block_fsid(struct btrfs_fs_info *fs_info, |
@@ -661,10 +670,8 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, | |||
661 | eb, found_level); | 670 | eb, found_level); |
662 | 671 | ||
663 | ret = csum_tree_block(fs_info, eb, 1); | 672 | ret = csum_tree_block(fs_info, eb, 1); |
664 | if (ret) { | 673 | if (ret) |
665 | ret = -EIO; | ||
666 | goto err; | 674 | goto err; |
667 | } | ||
668 | 675 | ||
669 | /* | 676 | /* |
670 | * If this is a leaf block and it is corrupt, set the corrupt bit so | 677 | * If this is a leaf block and it is corrupt, set the corrupt bit so |
@@ -1831,7 +1838,7 @@ static int cleaner_kthread(void *arg) | |||
1831 | */ | 1838 | */ |
1832 | btrfs_delete_unused_bgs(root->fs_info); | 1839 | btrfs_delete_unused_bgs(root->fs_info); |
1833 | sleep: | 1840 | sleep: |
1834 | if (!try_to_freeze() && !again) { | 1841 | if (!again) { |
1835 | set_current_state(TASK_INTERRUPTIBLE); | 1842 | set_current_state(TASK_INTERRUPTIBLE); |
1836 | if (!kthread_should_stop()) | 1843 | if (!kthread_should_stop()) |
1837 | schedule(); | 1844 | schedule(); |
@@ -1921,14 +1928,12 @@ sleep: | |||
1921 | if (unlikely(test_bit(BTRFS_FS_STATE_ERROR, | 1928 | if (unlikely(test_bit(BTRFS_FS_STATE_ERROR, |
1922 | &root->fs_info->fs_state))) | 1929 | &root->fs_info->fs_state))) |
1923 | btrfs_cleanup_transaction(root); | 1930 | btrfs_cleanup_transaction(root); |
1924 | if (!try_to_freeze()) { | 1931 | set_current_state(TASK_INTERRUPTIBLE); |
1925 | set_current_state(TASK_INTERRUPTIBLE); | 1932 | if (!kthread_should_stop() && |
1926 | if (!kthread_should_stop() && | 1933 | (!btrfs_transaction_blocked(root->fs_info) || |
1927 | (!btrfs_transaction_blocked(root->fs_info) || | 1934 | cannot_commit)) |
1928 | cannot_commit)) | 1935 | schedule_timeout(delay); |
1929 | schedule_timeout(delay); | 1936 | __set_current_state(TASK_RUNNING); |
1930 | __set_current_state(TASK_RUNNING); | ||
1931 | } | ||
1932 | } while (!kthread_should_stop()); | 1937 | } while (!kthread_should_stop()); |
1933 | return 0; | 1938 | return 0; |
1934 | } | 1939 | } |