aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/scrub.c
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-03-27 14:21:26 -0400
committerChris Mason <chris.mason@oracle.com>2012-03-27 14:21:26 -0400
commit1623edebee317855c6a854366c01d1630cc537c9 (patch)
treed2b79580ce85e26c89a257be0400c58c966ee4c6 /fs/btrfs/scrub.c
parent94598ba8d8ff066115508fb99e593d2de1ca67e1 (diff)
Btrfs: minor cleanup in scrub
Just a minor cleanup commit in preparation for the big block changes. Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r--fs/btrfs/scrub.c61
1 files changed, 25 insertions, 36 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index abc0fbffa510..e68bab4ffcd4 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -36,28 +36,11 @@
36 * Future enhancements: 36 * Future enhancements:
37 * - In case an unrepairable extent is encountered, track which files are 37 * - In case an unrepairable extent is encountered, track which files are
38 * affected and report them 38 * affected and report them
39 * - In case of a read error on files with nodatasum, map the file and read
40 * the extent to trigger a writeback of the good copy
41 * - track and record media errors, throw out bad devices 39 * - track and record media errors, throw out bad devices
42 * - add a mode to also read unallocated space 40 * - add a mode to also read unallocated space
43 */ 41 */
44 42
45struct scrub_bio;
46struct scrub_page;
47struct scrub_dev; 43struct scrub_dev;
48static void scrub_bio_end_io(struct bio *bio, int err);
49static void scrub_checksum(struct btrfs_work *work);
50static int scrub_checksum_data(struct scrub_dev *sdev,
51 struct scrub_page *spag, void *buffer);
52static int scrub_checksum_tree_block(struct scrub_dev *sdev,
53 struct scrub_page *spag, u64 logical,
54 void *buffer);
55static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer);
56static int scrub_fixup_check(struct scrub_bio *sbio, int ix);
57static void scrub_fixup_end_io(struct bio *bio, int err);
58static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,
59 struct page *page);
60static void scrub_fixup(struct scrub_bio *sbio, int ix);
61 44
62#define SCRUB_PAGES_PER_BIO 16 /* 64k per bio */ 45#define SCRUB_PAGES_PER_BIO 16 /* 64k per bio */
63#define SCRUB_BIOS_PER_DEV 16 /* 1 MB per device in flight */ 46#define SCRUB_BIOS_PER_DEV 16 /* 1 MB per device in flight */
@@ -124,6 +107,21 @@ struct scrub_warning {
124 int scratch_bufsize; 107 int scratch_bufsize;
125}; 108};
126 109
110static void scrub_bio_end_io(struct bio *bio, int err);
111static void scrub_checksum(struct btrfs_work *work);
112static int scrub_checksum_data(struct scrub_dev *sdev,
113 struct scrub_page *spag, void *buffer);
114static int scrub_checksum_tree_block(struct scrub_dev *sdev,
115 struct scrub_page *spag, u64 logical,
116 void *buffer);
117static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer);
118static int scrub_fixup_check(struct scrub_bio *sbio, int ix);
119static void scrub_fixup_end_io(struct bio *bio, int err);
120static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,
121 struct page *page);
122static void scrub_fixup(struct scrub_bio *sbio, int ix);
123
124
127static void scrub_free_csums(struct scrub_dev *sdev) 125static void scrub_free_csums(struct scrub_dev *sdev)
128{ 126{
129 while (!list_empty(&sdev->csum_list)) { 127 while (!list_empty(&sdev->csum_list)) {
@@ -342,7 +340,8 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,
342 do { 340 do {
343 ret = tree_backref_for_extent(&ptr, eb, ei, item_size, 341 ret = tree_backref_for_extent(&ptr, eb, ei, item_size,
344 &ref_root, &ref_level); 342 &ref_root, &ref_level);
345 printk(KERN_WARNING "%s at logical %llu on dev %s, " 343 printk(KERN_WARNING
344 "btrfs: %s at logical %llu on dev %s, "
346 "sector %llu: metadata %s (level %d) in tree " 345 "sector %llu: metadata %s (level %d) in tree "
347 "%llu\n", errstr, swarn.logical, dev->name, 346 "%llu\n", errstr, swarn.logical, dev->name,
348 (unsigned long long)swarn.sector, 347 (unsigned long long)swarn.sector,
@@ -948,12 +947,12 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer)
948 return fail; 947 return fail;
949} 948}
950 949
951static int scrub_submit(struct scrub_dev *sdev) 950static void scrub_submit(struct scrub_dev *sdev)
952{ 951{
953 struct scrub_bio *sbio; 952 struct scrub_bio *sbio;
954 953
955 if (sdev->curr == -1) 954 if (sdev->curr == -1)
956 return 0; 955 return;
957 956
958 sbio = sdev->bios[sdev->curr]; 957 sbio = sdev->bios[sdev->curr];
959 sbio->err = 0; 958 sbio->err = 0;
@@ -961,8 +960,6 @@ static int scrub_submit(struct scrub_dev *sdev)
961 atomic_inc(&sdev->in_flight); 960 atomic_inc(&sdev->in_flight);
962 961
963 btrfsic_submit_bio(READ, sbio->bio); 962 btrfsic_submit_bio(READ, sbio->bio);
964
965 return 0;
966} 963}
967 964
968static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, 965static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len,
@@ -1008,9 +1005,7 @@ again:
1008 sbio->bio = bio; 1005 sbio->bio = bio;
1009 } else if (sbio->physical + sbio->count * PAGE_SIZE != physical || 1006 } else if (sbio->physical + sbio->count * PAGE_SIZE != physical ||
1010 sbio->logical + sbio->count * PAGE_SIZE != logical) { 1007 sbio->logical + sbio->count * PAGE_SIZE != logical) {
1011 ret = scrub_submit(sdev); 1008 scrub_submit(sdev);
1012 if (ret)
1013 return ret;
1014 goto again; 1009 goto again;
1015 } 1010 }
1016 sbio->spag[sbio->count].flags = flags; 1011 sbio->spag[sbio->count].flags = flags;
@@ -1025,9 +1020,7 @@ again:
1025 ret = bio_add_page(sbio->bio, page, PAGE_SIZE, 0); 1020 ret = bio_add_page(sbio->bio, page, PAGE_SIZE, 0);
1026 if (!ret) { 1021 if (!ret) {
1027 __free_page(page); 1022 __free_page(page);
1028 ret = scrub_submit(sdev); 1023 scrub_submit(sdev);
1029 if (ret)
1030 return ret;
1031 goto again; 1024 goto again;
1032 } 1025 }
1033 1026
@@ -1036,13 +1029,8 @@ again:
1036 memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size); 1029 memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size);
1037 } 1030 }
1038 ++sbio->count; 1031 ++sbio->count;
1039 if (sbio->count == SCRUB_PAGES_PER_BIO || force) { 1032 if (sbio->count == SCRUB_PAGES_PER_BIO || force)
1040 int ret; 1033 scrub_submit(sdev);
1041
1042 ret = scrub_submit(sdev);
1043 if (ret)
1044 return ret;
1045 }
1046 1034
1047 return 0; 1035 return 0;
1048} 1036}
@@ -1520,7 +1508,7 @@ static noinline_for_stack int scrub_supers(struct scrub_dev *sdev)
1520 1508
1521 for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { 1509 for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
1522 bytenr = btrfs_sb_offset(i); 1510 bytenr = btrfs_sb_offset(i);
1523 if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes) 1511 if (bytenr + BTRFS_SUPER_INFO_SIZE > device->total_bytes)
1524 break; 1512 break;
1525 1513
1526 ret = scrub_page(sdev, bytenr, PAGE_SIZE, bytenr, 1514 ret = scrub_page(sdev, bytenr, PAGE_SIZE, bytenr,
@@ -1741,6 +1729,7 @@ int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev)
1741 1729
1742 return 0; 1730 return 0;
1743} 1731}
1732
1744int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid) 1733int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid)
1745{ 1734{
1746 struct btrfs_fs_info *fs_info = root->fs_info; 1735 struct btrfs_fs_info *fs_info = root->fs_info;