diff options
author | Arne Jansen <sensille@gmx.net> | 2011-03-08 08:14:00 -0500 |
---|---|---|
committer | Arne Jansen <sensille@gmx.net> | 2011-05-12 08:45:20 -0400 |
commit | a2de733c78fa7af51ba9670482fa7d392aa67c57 (patch) | |
tree | d88817bc7aba94e7efea530efac5ef190c1b799c /fs/btrfs/ctree.h | |
parent | 7cf96da3ec7ca225acf4f284b0e904a1f5f98821 (diff) |
btrfs: scrub
This adds an initial implementation for scrub. It works quite
straightforward. The usermode issues an ioctl for each device in the
fs. For each device, it enumerates the allocated device chunks. For
each chunk, the contained extents are enumerated and the data checksums
fetched. The extents are read sequentially and the checksums verified.
If an error occurs (checksum or EIO), a good copy is searched for. If
one is found, the bad copy will be rewritten.
All enumerations happen from the commit roots. During a transaction
commit, the scrubs get paused and afterwards continue from the new
roots.
This commit is based on the series originally posted to linux-btrfs
with some improvements that resulted from comments from David Sterba,
Ilya Dryomov and Jan Schmidt.
Signed-off-by: Arne Jansen <sensille@gmx.net>
Diffstat (limited to 'fs/btrfs/ctree.h')
-rw-r--r-- | fs/btrfs/ctree.h | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2e61fe1b6b8c..31141ba6072d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/highmem.h> | 24 | #include <linux/highmem.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/rwsem.h> | ||
26 | #include <linux/completion.h> | 27 | #include <linux/completion.h> |
27 | #include <linux/backing-dev.h> | 28 | #include <linux/backing-dev.h> |
28 | #include <linux/wait.h> | 29 | #include <linux/wait.h> |
@@ -33,6 +34,7 @@ | |||
33 | #include "extent_io.h" | 34 | #include "extent_io.h" |
34 | #include "extent_map.h" | 35 | #include "extent_map.h" |
35 | #include "async-thread.h" | 36 | #include "async-thread.h" |
37 | #include "ioctl.h" | ||
36 | 38 | ||
37 | struct btrfs_trans_handle; | 39 | struct btrfs_trans_handle; |
38 | struct btrfs_transaction; | 40 | struct btrfs_transaction; |
@@ -510,6 +512,12 @@ struct btrfs_extent_item_v0 { | |||
510 | /* use full backrefs for extent pointers in the block */ | 512 | /* use full backrefs for extent pointers in the block */ |
511 | #define BTRFS_BLOCK_FLAG_FULL_BACKREF (1ULL << 8) | 513 | #define BTRFS_BLOCK_FLAG_FULL_BACKREF (1ULL << 8) |
512 | 514 | ||
515 | /* | ||
516 | * this flag is only used internally by scrub and may be changed at any time | ||
517 | * it is only declared here to avoid collisions | ||
518 | */ | ||
519 | #define BTRFS_EXTENT_FLAG_SUPER (1ULL << 48) | ||
520 | |||
513 | struct btrfs_tree_block_info { | 521 | struct btrfs_tree_block_info { |
514 | struct btrfs_disk_key key; | 522 | struct btrfs_disk_key key; |
515 | u8 level; | 523 | u8 level; |
@@ -1077,6 +1085,17 @@ struct btrfs_fs_info { | |||
1077 | 1085 | ||
1078 | void *bdev_holder; | 1086 | void *bdev_holder; |
1079 | 1087 | ||
1088 | /* private scrub information */ | ||
1089 | struct mutex scrub_lock; | ||
1090 | atomic_t scrubs_running; | ||
1091 | atomic_t scrub_pause_req; | ||
1092 | atomic_t scrubs_paused; | ||
1093 | atomic_t scrub_cancel_req; | ||
1094 | wait_queue_head_t scrub_pause_wait; | ||
1095 | struct rw_semaphore scrub_super_lock; | ||
1096 | int scrub_workers_refcnt; | ||
1097 | struct btrfs_workers scrub_workers; | ||
1098 | |||
1080 | /* filesystem state */ | 1099 | /* filesystem state */ |
1081 | u64 fs_state; | 1100 | u64 fs_state; |
1082 | }; | 1101 | }; |
@@ -2472,8 +2491,8 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
2472 | int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | 2491 | int btrfs_csum_truncate(struct btrfs_trans_handle *trans, |
2473 | struct btrfs_root *root, struct btrfs_path *path, | 2492 | struct btrfs_root *root, struct btrfs_path *path, |
2474 | u64 isize); | 2493 | u64 isize); |
2475 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, | 2494 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, |
2476 | u64 end, struct list_head *list); | 2495 | struct list_head *list, int search_commit); |
2477 | /* inode.c */ | 2496 | /* inode.c */ |
2478 | 2497 | ||
2479 | /* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */ | 2498 | /* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */ |
@@ -2637,4 +2656,18 @@ void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans, | |||
2637 | u64 *bytes_to_reserve); | 2656 | u64 *bytes_to_reserve); |
2638 | void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, | 2657 | void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, |
2639 | struct btrfs_pending_snapshot *pending); | 2658 | struct btrfs_pending_snapshot *pending); |
2659 | |||
2660 | /* scrub.c */ | ||
2661 | int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, | ||
2662 | struct btrfs_scrub_progress *progress); | ||
2663 | int btrfs_scrub_pause(struct btrfs_root *root); | ||
2664 | int btrfs_scrub_pause_super(struct btrfs_root *root); | ||
2665 | int btrfs_scrub_continue(struct btrfs_root *root); | ||
2666 | int btrfs_scrub_continue_super(struct btrfs_root *root); | ||
2667 | int btrfs_scrub_cancel(struct btrfs_root *root); | ||
2668 | int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev); | ||
2669 | int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid); | ||
2670 | int btrfs_scrub_progress(struct btrfs_root *root, u64 devid, | ||
2671 | struct btrfs_scrub_progress *progress); | ||
2672 | |||
2640 | #endif | 2673 | #endif |