aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2011-11-09 07:44:05 -0500
committerStefan Behrens <sbehrens@giantdisaster.de>2011-12-21 13:14:17 -0500
commit21adbd5cbb5344a3fca6bb7ddb2ab6cb03c44546 (patch)
tree208c3ab6ad8bb35937b21c4d54e45e46d99557ff /fs
parentf11e4d7f533249ddfa110116200c5c3a509f9218 (diff)
Btrfs: integrate integrity check module into btrfs
This is the last part of the patch series. It modifies the btrfs code to use the integrity check module if configured to do so with the define BTRFS_FS_CHECK_INTEGRITY. If this define is not set, the only effective change is that code is added that handles the mount option to activate the integrity check. If the mount option is set and the define BTRFS_FS_CHECK_INTEGRITY is not set, that code complains in the log and the mount fails with EINVAL. Add the mount option to activate the usage of the integrity check code. Add invocation of btrfs integrity check code init and cleanup function on mount and umount, respectively. Add hook to call btrfs integrity check code version of submit_bh/submit_bio. Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h8
-rw-r--r--fs/btrfs/disk-io.c26
-rw-r--r--fs/btrfs/extent_io.c5
-rw-r--r--fs/btrfs/scrub.c5
-rw-r--r--fs/btrfs/super.c39
-rw-r--r--fs/btrfs/volumes.c7
6 files changed, 79 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 67385033323..39f6188688e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -971,7 +971,7 @@ struct btrfs_fs_info {
971 * is required instead of the faster short fsync log commits 971 * is required instead of the faster short fsync log commits
972 */ 972 */
973 u64 last_trans_log_full_commit; 973 u64 last_trans_log_full_commit;
974 unsigned long mount_opt:20; 974 unsigned long mount_opt:21;
975 unsigned long compress_type:4; 975 unsigned long compress_type:4;
976 u64 max_inline; 976 u64 max_inline;
977 u64 alloc_start; 977 u64 alloc_start;
@@ -1155,6 +1155,10 @@ struct btrfs_fs_info {
1155 int scrub_workers_refcnt; 1155 int scrub_workers_refcnt;
1156 struct btrfs_workers scrub_workers; 1156 struct btrfs_workers scrub_workers;
1157 1157
1158#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
1159 u32 check_integrity_print_mask;
1160#endif
1161
1158 /* filesystem state */ 1162 /* filesystem state */
1159 u64 fs_state; 1163 u64 fs_state;
1160 1164
@@ -1413,6 +1417,8 @@ struct btrfs_ioctl_defrag_range_args {
1413#define BTRFS_MOUNT_AUTO_DEFRAG (1 << 16) 1417#define BTRFS_MOUNT_AUTO_DEFRAG (1 << 16)
1414#define BTRFS_MOUNT_INODE_MAP_CACHE (1 << 17) 1418#define BTRFS_MOUNT_INODE_MAP_CACHE (1 << 17)
1415#define BTRFS_MOUNT_RECOVERY (1 << 18) 1419#define BTRFS_MOUNT_RECOVERY (1 << 18)
1420#define BTRFS_MOUNT_CHECK_INTEGRITY (1 << 19)
1421#define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 20)
1416 1422
1417#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) 1423#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1418#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) 1424#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3f9d5551e58..f363c6d9c3d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -43,6 +43,7 @@
43#include "tree-log.h" 43#include "tree-log.h"
44#include "free-space-cache.h" 44#include "free-space-cache.h"
45#include "inode-map.h" 45#include "inode-map.h"
46#include "check-integrity.h"
46 47
47static struct extent_io_ops btree_extent_io_ops; 48static struct extent_io_ops btree_extent_io_ops;
48static void end_workqueue_fn(struct btrfs_work *work); 49static void end_workqueue_fn(struct btrfs_work *work);
@@ -2001,6 +2002,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
2001 init_waitqueue_head(&fs_info->scrub_pause_wait); 2002 init_waitqueue_head(&fs_info->scrub_pause_wait);
2002 init_rwsem(&fs_info->scrub_super_lock); 2003 init_rwsem(&fs_info->scrub_super_lock);
2003 fs_info->scrub_workers_refcnt = 0; 2004 fs_info->scrub_workers_refcnt = 0;
2005#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
2006 fs_info->check_integrity_print_mask = 0;
2007#endif
2004 2008
2005 sb->s_blocksize = 4096; 2009 sb->s_blocksize = 4096;
2006 sb->s_blocksize_bits = blksize_bits(4096); 2010 sb->s_blocksize_bits = blksize_bits(4096);
@@ -2356,6 +2360,19 @@ retry_root_backup:
2356 btrfs_set_opt(fs_info->mount_opt, SSD); 2360 btrfs_set_opt(fs_info->mount_opt, SSD);
2357 } 2361 }
2358 2362
2363#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
2364 if (btrfs_test_opt(tree_root, CHECK_INTEGRITY)) {
2365 ret = btrfsic_mount(tree_root, fs_devices,
2366 btrfs_test_opt(tree_root,
2367 CHECK_INTEGRITY_INCLUDING_EXTENT_DATA) ?
2368 1 : 0,
2369 fs_info->check_integrity_print_mask);
2370 if (ret)
2371 printk(KERN_WARNING "btrfs: failed to initialize"
2372 " integrity check module %s\n", sb->s_id);
2373 }
2374#endif
2375
2359 /* do not make disk changes in broken FS */ 2376 /* do not make disk changes in broken FS */
2360 if (btrfs_super_log_root(disk_super) != 0 && 2377 if (btrfs_super_log_root(disk_super) != 0 &&
2361 !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) { 2378 !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) {
@@ -2634,7 +2651,7 @@ static int write_dev_supers(struct btrfs_device *device,
2634 * we fua the first super. The others we allow 2651 * we fua the first super. The others we allow
2635 * to go down lazy. 2652 * to go down lazy.
2636 */ 2653 */
2637 ret = submit_bh(WRITE_FUA, bh); 2654 ret = btrfsic_submit_bh(WRITE_FUA, bh);
2638 if (ret) 2655 if (ret)
2639 errors++; 2656 errors++;
2640 } 2657 }
@@ -2711,7 +2728,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
2711 device->flush_bio = bio; 2728 device->flush_bio = bio;
2712 2729
2713 bio_get(bio); 2730 bio_get(bio);
2714 submit_bio(WRITE_FLUSH, bio); 2731 btrfsic_submit_bio(WRITE_FLUSH, bio);
2715 2732
2716 return 0; 2733 return 0;
2717} 2734}
@@ -3057,6 +3074,11 @@ int close_ctree(struct btrfs_root *root)
3057 btrfs_stop_workers(&fs_info->caching_workers); 3074 btrfs_stop_workers(&fs_info->caching_workers);
3058 btrfs_stop_workers(&fs_info->readahead_workers); 3075 btrfs_stop_workers(&fs_info->readahead_workers);
3059 3076
3077#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
3078 if (btrfs_test_opt(root, CHECK_INTEGRITY))
3079 btrfsic_unmount(root, fs_info->fs_devices);
3080#endif
3081
3060 btrfs_close_devices(fs_info->fs_devices); 3082 btrfs_close_devices(fs_info->fs_devices);
3061 btrfs_mapping_tree_free(&fs_info->mapping_tree); 3083 btrfs_mapping_tree_free(&fs_info->mapping_tree);
3062 3084
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 49f3c9dc09f..246669296e0 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -18,6 +18,7 @@
18#include "ctree.h" 18#include "ctree.h"
19#include "btrfs_inode.h" 19#include "btrfs_inode.h"
20#include "volumes.h" 20#include "volumes.h"
21#include "check-integrity.h"
21 22
22static struct kmem_cache *extent_state_cache; 23static struct kmem_cache *extent_state_cache;
23static struct kmem_cache *extent_buffer_cache; 24static struct kmem_cache *extent_buffer_cache;
@@ -1895,7 +1896,7 @@ int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start,
1895 } 1896 }
1896 bio->bi_bdev = dev->bdev; 1897 bio->bi_bdev = dev->bdev;
1897 bio_add_page(bio, page, length, start-page_offset(page)); 1898 bio_add_page(bio, page, length, start-page_offset(page));
1898 submit_bio(WRITE_SYNC, bio); 1899 btrfsic_submit_bio(WRITE_SYNC, bio);
1899 wait_for_completion(&compl); 1900 wait_for_completion(&compl);
1900 1901
1901 if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { 1902 if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
@@ -2393,7 +2394,7 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num,
2393 ret = tree->ops->submit_bio_hook(page->mapping->host, rw, bio, 2394 ret = tree->ops->submit_bio_hook(page->mapping->host, rw, bio,
2394 mirror_num, bio_flags, start); 2395 mirror_num, bio_flags, start);
2395 else 2396 else
2396 submit_bio(rw, bio); 2397 btrfsic_submit_bio(rw, bio);
2397 2398
2398 if (bio_flagged(bio, BIO_EOPNOTSUPP)) 2399 if (bio_flagged(bio, BIO_EOPNOTSUPP))
2399 ret = -EOPNOTSUPP; 2400 ret = -EOPNOTSUPP;
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index ddf2c90d3fc..567e148caca 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -25,6 +25,7 @@
25#include "transaction.h" 25#include "transaction.h"
26#include "backref.h" 26#include "backref.h"
27#include "extent_io.h" 27#include "extent_io.h"
28#include "check-integrity.h"
28 29
29/* 30/*
30 * This is only the first step towards a full-features scrub. It reads all 31 * This is only the first step towards a full-features scrub. It reads all
@@ -732,7 +733,7 @@ static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,
732 bio_add_page(bio, page, PAGE_SIZE, 0); 733 bio_add_page(bio, page, PAGE_SIZE, 0);
733 bio->bi_end_io = scrub_fixup_end_io; 734 bio->bi_end_io = scrub_fixup_end_io;
734 bio->bi_private = &complete; 735 bio->bi_private = &complete;
735 submit_bio(rw, bio); 736 btrfsic_submit_bio(rw, bio);
736 737
737 /* this will also unplug the queue */ 738 /* this will also unplug the queue */
738 wait_for_completion(&complete); 739 wait_for_completion(&complete);
@@ -958,7 +959,7 @@ static int scrub_submit(struct scrub_dev *sdev)
958 sdev->curr = -1; 959 sdev->curr = -1;
959 atomic_inc(&sdev->in_flight); 960 atomic_inc(&sdev->in_flight);
960 961
961 submit_bio(READ, sbio->bio); 962 btrfsic_submit_bio(READ, sbio->bio);
962 963
963 return 0; 964 return 0;
964} 965}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 34a8b6112ea..22a2015f1d7 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -165,7 +165,10 @@ enum {
165 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, 165 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
166 Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, 166 Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
167 Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, 167 Opt_enospc_debug, Opt_subvolrootid, Opt_defrag,
168 Opt_inode_cache, Opt_no_space_cache, Opt_recovery, Opt_err, 168 Opt_inode_cache, Opt_no_space_cache, Opt_recovery,
169 Opt_check_integrity, Opt_check_integrity_including_extent_data,
170 Opt_check_integrity_print_mask,
171 Opt_err,
169}; 172};
170 173
171static match_table_t tokens = { 174static match_table_t tokens = {
@@ -200,6 +203,9 @@ static match_table_t tokens = {
200 {Opt_inode_cache, "inode_cache"}, 203 {Opt_inode_cache, "inode_cache"},
201 {Opt_no_space_cache, "nospace_cache"}, 204 {Opt_no_space_cache, "nospace_cache"},
202 {Opt_recovery, "recovery"}, 205 {Opt_recovery, "recovery"},
206 {Opt_check_integrity, "check_int"},
207 {Opt_check_integrity_including_extent_data, "check_int_data"},
208 {Opt_check_integrity_print_mask, "check_int_print_mask=%d"},
203 {Opt_err, NULL}, 209 {Opt_err, NULL},
204}; 210};
205 211
@@ -398,6 +404,37 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
398 printk(KERN_INFO "btrfs: enabling auto recovery"); 404 printk(KERN_INFO "btrfs: enabling auto recovery");
399 btrfs_set_opt(info->mount_opt, RECOVERY); 405 btrfs_set_opt(info->mount_opt, RECOVERY);
400 break; 406 break;
407#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
408 case Opt_check_integrity_including_extent_data:
409 printk(KERN_INFO "btrfs: enabling check integrity"
410 " including extent data\n");
411 btrfs_set_opt(info->mount_opt,
412 CHECK_INTEGRITY_INCLUDING_EXTENT_DATA);
413 btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY);
414 break;
415 case Opt_check_integrity:
416 printk(KERN_INFO "btrfs: enabling check integrity\n");
417 btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY);
418 break;
419 case Opt_check_integrity_print_mask:
420 intarg = 0;
421 match_int(&args[0], &intarg);
422 if (intarg) {
423 info->check_integrity_print_mask = intarg;
424 printk(KERN_INFO "btrfs:"
425 " check_integrity_print_mask 0x%x\n",
426 info->check_integrity_print_mask);
427 }
428 break;
429#else
430 case Opt_check_integrity_including_extent_data:
431 case Opt_check_integrity:
432 case Opt_check_integrity_print_mask:
433 printk(KERN_ERR "btrfs: support for check_integrity*"
434 " not compiled in!\n");
435 ret = -EINVAL;
436 goto out;
437#endif
401 case Opt_err: 438 case Opt_err:
402 printk(KERN_INFO "btrfs: unrecognized mount option " 439 printk(KERN_INFO "btrfs: unrecognized mount option "
403 "'%s'\n", p); 440 "'%s'\n", p);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index f4b839fd3c9..821334f6e3a 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -32,6 +32,7 @@
32#include "print-tree.h" 32#include "print-tree.h"
33#include "volumes.h" 33#include "volumes.h"
34#include "async-thread.h" 34#include "async-thread.h"
35#include "check-integrity.h"
35 36
36static int init_first_rw_device(struct btrfs_trans_handle *trans, 37static int init_first_rw_device(struct btrfs_trans_handle *trans,
37 struct btrfs_root *root, 38 struct btrfs_root *root,
@@ -246,7 +247,7 @@ loop_lock:
246 sync_pending = 0; 247 sync_pending = 0;
247 } 248 }
248 249
249 submit_bio(cur->bi_rw, cur); 250 btrfsic_submit_bio(cur->bi_rw, cur);
250 num_run++; 251 num_run++;
251 batch_run++; 252 batch_run++;
252 if (need_resched()) 253 if (need_resched())
@@ -3304,7 +3305,7 @@ static noinline int schedule_bio(struct btrfs_root *root,
3304 /* don't bother with additional async steps for reads, right now */ 3305 /* don't bother with additional async steps for reads, right now */
3305 if (!(rw & REQ_WRITE)) { 3306 if (!(rw & REQ_WRITE)) {
3306 bio_get(bio); 3307 bio_get(bio);
3307 submit_bio(rw, bio); 3308 btrfsic_submit_bio(rw, bio);
3308 bio_put(bio); 3309 bio_put(bio);
3309 return 0; 3310 return 0;
3310 } 3311 }
@@ -3399,7 +3400,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
3399 if (async_submit) 3400 if (async_submit)
3400 schedule_bio(root, dev, rw, bio); 3401 schedule_bio(root, dev, rw, bio);
3401 else 3402 else
3402 submit_bio(rw, bio); 3403 btrfsic_submit_bio(rw, bio);
3403 } else { 3404 } else {
3404 bio->bi_bdev = root->fs_info->fs_devices->latest_bdev; 3405 bio->bi_bdev = root->fs_info->fs_devices->latest_bdev;
3405 bio->bi_sector = logical >> 9; 3406 bio->bi_sector = logical >> 9;