aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2016-03-24 20:36:13 -0400
committerChris Mason <clm@fb.com>2016-03-24 20:36:13 -0400
commit232cad8413a0bfbd25f11cc19fd13dfd85e1d8ad (patch)
tree6b0f9a9af92a86050a40c0d09cb7facbb3621abc /fs/btrfs/disk-io.c
parent389f239c53420802ad5085e51e88c37e2df5e003 (diff)
parentce63f891e1a87ae79c4325dad5f512e8d6a8a78e (diff)
Merge branch 'misc-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.6
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c95e3ce9f22e..f6705252b5b2 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
523static int check_tree_block_fsid(struct btrfs_fs_info *fs_info, 532static 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);
1833sleep: 1840sleep:
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}