aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4b02591b0301..4e47849d7427 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
@@ -1055,7 +1062,7 @@ static void btree_invalidatepage(struct page *page, unsigned int offset,
1055 (unsigned long long)page_offset(page)); 1062 (unsigned long long)page_offset(page));
1056 ClearPagePrivate(page); 1063 ClearPagePrivate(page);
1057 set_page_private(page, 0); 1064 set_page_private(page, 0);
1058 page_cache_release(page); 1065 put_page(page);
1059 } 1066 }
1060} 1067}
1061 1068
@@ -1757,7 +1764,7 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
1757 if (err) 1764 if (err)
1758 return err; 1765 return err;
1759 1766
1760 bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE; 1767 bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_SIZE;
1761 bdi->congested_fn = btrfs_congested_fn; 1768 bdi->congested_fn = btrfs_congested_fn;
1762 bdi->congested_data = info; 1769 bdi->congested_data = info;
1763 bdi->capabilities |= BDI_CAP_CGROUP_WRITEBACK; 1770 bdi->capabilities |= BDI_CAP_CGROUP_WRITEBACK;
@@ -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}
@@ -2537,7 +2542,7 @@ int open_ctree(struct super_block *sb,
2537 err = ret; 2542 err = ret;
2538 goto fail_bdi; 2543 goto fail_bdi;
2539 } 2544 }
2540 fs_info->dirty_metadata_batch = PAGE_CACHE_SIZE * 2545 fs_info->dirty_metadata_batch = PAGE_SIZE *
2541 (1 + ilog2(nr_cpu_ids)); 2546 (1 + ilog2(nr_cpu_ids));
2542 2547
2543 ret = percpu_counter_init(&fs_info->delalloc_bytes, 0, GFP_KERNEL); 2548 ret = percpu_counter_init(&fs_info->delalloc_bytes, 0, GFP_KERNEL);
@@ -2782,7 +2787,7 @@ int open_ctree(struct super_block *sb,
2782 * flag our filesystem as having big metadata blocks if 2787 * flag our filesystem as having big metadata blocks if
2783 * they are bigger than the page size 2788 * they are bigger than the page size
2784 */ 2789 */
2785 if (btrfs_super_nodesize(disk_super) > PAGE_CACHE_SIZE) { 2790 if (btrfs_super_nodesize(disk_super) > PAGE_SIZE) {
2786 if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA)) 2791 if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA))
2787 printk(KERN_INFO "BTRFS: flagging fs with big metadata feature\n"); 2792 printk(KERN_INFO "BTRFS: flagging fs with big metadata feature\n");
2788 features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA; 2793 features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
@@ -2832,7 +2837,7 @@ int open_ctree(struct super_block *sb,
2832 2837
2833 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); 2838 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
2834 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, 2839 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
2835 SZ_4M / PAGE_CACHE_SIZE); 2840 SZ_4M / PAGE_SIZE);
2836 2841
2837 tree_root->nodesize = nodesize; 2842 tree_root->nodesize = nodesize;
2838 tree_root->sectorsize = sectorsize; 2843 tree_root->sectorsize = sectorsize;
@@ -4071,9 +4076,9 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
4071 ret = -EINVAL; 4076 ret = -EINVAL;
4072 } 4077 }
4073 /* Only PAGE SIZE is supported yet */ 4078 /* Only PAGE SIZE is supported yet */
4074 if (sectorsize != PAGE_CACHE_SIZE) { 4079 if (sectorsize != PAGE_SIZE) {
4075 printk(KERN_ERR "BTRFS: sectorsize %llu not supported yet, only support %lu\n", 4080 printk(KERN_ERR "BTRFS: sectorsize %llu not supported yet, only support %lu\n",
4076 sectorsize, PAGE_CACHE_SIZE); 4081 sectorsize, PAGE_SIZE);
4077 ret = -EINVAL; 4082 ret = -EINVAL;
4078 } 4083 }
4079 if (!is_power_of_2(nodesize) || nodesize < sectorsize || 4084 if (!is_power_of_2(nodesize) || nodesize < sectorsize ||