diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2012-04-12 06:53:40 -0400 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2012-05-11 10:56:40 -0400 |
commit | e06baab4184509bdfddd294efc6cae7a410c6f07 (patch) | |
tree | 301e2060646d47de7885c925dd61b1c41f20b8f5 /fs/btrfs/check-integrity.c | |
parent | fd5e62a37cef5b212318c522eac0ecd394b50a19 (diff) |
Btrfs: change integrity checker to support big blocks
The integrity checker used to be coded for nodesize == leafsize ==
sectorsize == PAGE_CACHE_SIZE.
This is now changed to support sizes for nodesize and leafsize which are
N * PAGE_CACHE_SIZE.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Diffstat (limited to 'fs/btrfs/check-integrity.c')
-rw-r--r-- | fs/btrfs/check-integrity.c | 561 |
1 files changed, 415 insertions, 146 deletions
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index c053e90f2006..7f6cc359e440 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -103,8 +103,6 @@ | |||
103 | #define BTRFSIC_BLOCK_STACK_FRAME_MAGIC_NUMBER 20111300 | 103 | #define BTRFSIC_BLOCK_STACK_FRAME_MAGIC_NUMBER 20111300 |
104 | #define BTRFSIC_TREE_DUMP_MAX_INDENT_LEVEL (200 - 6) /* in characters, | 104 | #define BTRFSIC_TREE_DUMP_MAX_INDENT_LEVEL (200 - 6) /* in characters, |
105 | * excluding " [...]" */ | 105 | * excluding " [...]" */ |
106 | #define BTRFSIC_BLOCK_SIZE PAGE_SIZE | ||
107 | |||
108 | #define BTRFSIC_GENERATION_UNKNOWN ((u64)-1) | 106 | #define BTRFSIC_GENERATION_UNKNOWN ((u64)-1) |
109 | 107 | ||
110 | /* | 108 | /* |
@@ -210,8 +208,9 @@ struct btrfsic_block_data_ctx { | |||
210 | u64 dev_bytenr; /* physical bytenr on device */ | 208 | u64 dev_bytenr; /* physical bytenr on device */ |
211 | u32 len; | 209 | u32 len; |
212 | struct btrfsic_dev_state *dev; | 210 | struct btrfsic_dev_state *dev; |
213 | char *data; | 211 | char **datav; |
214 | struct buffer_head *bh; /* do not use if set to NULL */ | 212 | struct page **pagev; |
213 | void *mem_to_free; | ||
215 | }; | 214 | }; |
216 | 215 | ||
217 | /* This structure is used to implement recursion without occupying | 216 | /* This structure is used to implement recursion without occupying |
@@ -243,6 +242,8 @@ struct btrfsic_state { | |||
243 | struct btrfs_root *root; | 242 | struct btrfs_root *root; |
244 | u64 max_superblock_generation; | 243 | u64 max_superblock_generation; |
245 | struct btrfsic_block *latest_superblock; | 244 | struct btrfsic_block *latest_superblock; |
245 | u32 metablock_size; | ||
246 | u32 datablock_size; | ||
246 | }; | 247 | }; |
247 | 248 | ||
248 | static void btrfsic_block_init(struct btrfsic_block *b); | 249 | static void btrfsic_block_init(struct btrfsic_block *b); |
@@ -290,8 +291,10 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, | |||
290 | static int btrfsic_process_metablock(struct btrfsic_state *state, | 291 | static int btrfsic_process_metablock(struct btrfsic_state *state, |
291 | struct btrfsic_block *block, | 292 | struct btrfsic_block *block, |
292 | struct btrfsic_block_data_ctx *block_ctx, | 293 | struct btrfsic_block_data_ctx *block_ctx, |
293 | struct btrfs_header *hdr, | ||
294 | int limit_nesting, int force_iodone_flag); | 294 | int limit_nesting, int force_iodone_flag); |
295 | static void btrfsic_read_from_block_data( | ||
296 | struct btrfsic_block_data_ctx *block_ctx, | ||
297 | void *dst, u32 offset, size_t len); | ||
295 | static int btrfsic_create_link_to_next_block( | 298 | static int btrfsic_create_link_to_next_block( |
296 | struct btrfsic_state *state, | 299 | struct btrfsic_state *state, |
297 | struct btrfsic_block *block, | 300 | struct btrfsic_block *block, |
@@ -318,12 +321,13 @@ static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx); | |||
318 | static int btrfsic_read_block(struct btrfsic_state *state, | 321 | static int btrfsic_read_block(struct btrfsic_state *state, |
319 | struct btrfsic_block_data_ctx *block_ctx); | 322 | struct btrfsic_block_data_ctx *block_ctx); |
320 | static void btrfsic_dump_database(struct btrfsic_state *state); | 323 | static void btrfsic_dump_database(struct btrfsic_state *state); |
324 | static void btrfsic_complete_bio_end_io(struct bio *bio, int err); | ||
321 | static int btrfsic_test_for_metadata(struct btrfsic_state *state, | 325 | static int btrfsic_test_for_metadata(struct btrfsic_state *state, |
322 | const u8 *data, unsigned int size); | 326 | char **datav, unsigned int num_pages); |
323 | static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | 327 | static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, |
324 | u64 dev_bytenr, u8 *mapped_data, | 328 | u64 dev_bytenr, char **mapped_datav, |
325 | unsigned int len, struct bio *bio, | 329 | unsigned int num_pages, |
326 | int *bio_is_patched, | 330 | struct bio *bio, int *bio_is_patched, |
327 | struct buffer_head *bh, | 331 | struct buffer_head *bh, |
328 | int submit_bio_bh_rw); | 332 | int submit_bio_bh_rw); |
329 | static int btrfsic_process_written_superblock( | 333 | static int btrfsic_process_written_superblock( |
@@ -375,7 +379,7 @@ static struct btrfsic_dev_state *btrfsic_dev_state_lookup( | |||
375 | static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | 379 | static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, |
376 | u64 bytenr, | 380 | u64 bytenr, |
377 | struct btrfsic_dev_state *dev_state, | 381 | struct btrfsic_dev_state *dev_state, |
378 | u64 dev_bytenr, char *data); | 382 | u64 dev_bytenr); |
379 | 383 | ||
380 | static struct mutex btrfsic_mutex; | 384 | static struct mutex btrfsic_mutex; |
381 | static int btrfsic_is_initialized; | 385 | static int btrfsic_is_initialized; |
@@ -651,7 +655,7 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, | |||
651 | int pass; | 655 | int pass; |
652 | 656 | ||
653 | BUG_ON(NULL == state); | 657 | BUG_ON(NULL == state); |
654 | selected_super = kmalloc(sizeof(*selected_super), GFP_NOFS); | 658 | selected_super = kzalloc(sizeof(*selected_super), GFP_NOFS); |
655 | if (NULL == selected_super) { | 659 | if (NULL == selected_super) { |
656 | printk(KERN_INFO "btrfsic: error, kmalloc failed!\n"); | 660 | printk(KERN_INFO "btrfsic: error, kmalloc failed!\n"); |
657 | return -1; | 661 | return -1; |
@@ -718,7 +722,7 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, | |||
718 | 722 | ||
719 | num_copies = | 723 | num_copies = |
720 | btrfs_num_copies(&state->root->fs_info->mapping_tree, | 724 | btrfs_num_copies(&state->root->fs_info->mapping_tree, |
721 | next_bytenr, PAGE_SIZE); | 725 | next_bytenr, state->metablock_size); |
722 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) | 726 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) |
723 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", | 727 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", |
724 | (unsigned long long)next_bytenr, num_copies); | 728 | (unsigned long long)next_bytenr, num_copies); |
@@ -727,9 +731,9 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, | |||
727 | struct btrfsic_block *next_block; | 731 | struct btrfsic_block *next_block; |
728 | struct btrfsic_block_data_ctx tmp_next_block_ctx; | 732 | struct btrfsic_block_data_ctx tmp_next_block_ctx; |
729 | struct btrfsic_block_link *l; | 733 | struct btrfsic_block_link *l; |
730 | struct btrfs_header *hdr; | ||
731 | 734 | ||
732 | ret = btrfsic_map_block(state, next_bytenr, PAGE_SIZE, | 735 | ret = btrfsic_map_block(state, next_bytenr, |
736 | state->metablock_size, | ||
733 | &tmp_next_block_ctx, | 737 | &tmp_next_block_ctx, |
734 | mirror_num); | 738 | mirror_num); |
735 | if (ret) { | 739 | if (ret) { |
@@ -758,7 +762,7 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, | |||
758 | BUG_ON(NULL == l); | 762 | BUG_ON(NULL == l); |
759 | 763 | ||
760 | ret = btrfsic_read_block(state, &tmp_next_block_ctx); | 764 | ret = btrfsic_read_block(state, &tmp_next_block_ctx); |
761 | if (ret < (int)BTRFSIC_BLOCK_SIZE) { | 765 | if (ret < (int)PAGE_CACHE_SIZE) { |
762 | printk(KERN_INFO | 766 | printk(KERN_INFO |
763 | "btrfsic: read @logical %llu failed!\n", | 767 | "btrfsic: read @logical %llu failed!\n", |
764 | (unsigned long long) | 768 | (unsigned long long) |
@@ -768,11 +772,9 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, | |||
768 | return -1; | 772 | return -1; |
769 | } | 773 | } |
770 | 774 | ||
771 | hdr = (struct btrfs_header *)tmp_next_block_ctx.data; | ||
772 | ret = btrfsic_process_metablock(state, | 775 | ret = btrfsic_process_metablock(state, |
773 | next_block, | 776 | next_block, |
774 | &tmp_next_block_ctx, | 777 | &tmp_next_block_ctx, |
775 | hdr, | ||
776 | BTRFS_MAX_LEVEL + 3, 1); | 778 | BTRFS_MAX_LEVEL + 3, 1); |
777 | btrfsic_release_block_ctx(&tmp_next_block_ctx); | 779 | btrfsic_release_block_ctx(&tmp_next_block_ctx); |
778 | } | 780 | } |
@@ -799,7 +801,10 @@ static int btrfsic_process_superblock_dev_mirror( | |||
799 | 801 | ||
800 | /* super block bytenr is always the unmapped device bytenr */ | 802 | /* super block bytenr is always the unmapped device bytenr */ |
801 | dev_bytenr = btrfs_sb_offset(superblock_mirror_num); | 803 | dev_bytenr = btrfs_sb_offset(superblock_mirror_num); |
802 | bh = __bread(superblock_bdev, dev_bytenr / 4096, 4096); | 804 | if (dev_bytenr + BTRFS_SUPER_INFO_SIZE > device->total_bytes) |
805 | return -1; | ||
806 | bh = __bread(superblock_bdev, dev_bytenr / 4096, | ||
807 | BTRFS_SUPER_INFO_SIZE); | ||
803 | if (NULL == bh) | 808 | if (NULL == bh) |
804 | return -1; | 809 | return -1; |
805 | super_tmp = (struct btrfs_super_block *) | 810 | super_tmp = (struct btrfs_super_block *) |
@@ -808,7 +813,10 @@ static int btrfsic_process_superblock_dev_mirror( | |||
808 | if (btrfs_super_bytenr(super_tmp) != dev_bytenr || | 813 | if (btrfs_super_bytenr(super_tmp) != dev_bytenr || |
809 | strncmp((char *)(&(super_tmp->magic)), BTRFS_MAGIC, | 814 | strncmp((char *)(&(super_tmp->magic)), BTRFS_MAGIC, |
810 | sizeof(super_tmp->magic)) || | 815 | sizeof(super_tmp->magic)) || |
811 | memcmp(device->uuid, super_tmp->dev_item.uuid, BTRFS_UUID_SIZE)) { | 816 | memcmp(device->uuid, super_tmp->dev_item.uuid, BTRFS_UUID_SIZE) || |
817 | btrfs_super_nodesize(super_tmp) != state->metablock_size || | ||
818 | btrfs_super_leafsize(super_tmp) != state->metablock_size || | ||
819 | btrfs_super_sectorsize(super_tmp) != state->datablock_size) { | ||
812 | brelse(bh); | 820 | brelse(bh); |
813 | return 0; | 821 | return 0; |
814 | } | 822 | } |
@@ -893,7 +901,7 @@ static int btrfsic_process_superblock_dev_mirror( | |||
893 | 901 | ||
894 | num_copies = | 902 | num_copies = |
895 | btrfs_num_copies(&state->root->fs_info->mapping_tree, | 903 | btrfs_num_copies(&state->root->fs_info->mapping_tree, |
896 | next_bytenr, PAGE_SIZE); | 904 | next_bytenr, state->metablock_size); |
897 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) | 905 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) |
898 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", | 906 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", |
899 | (unsigned long long)next_bytenr, num_copies); | 907 | (unsigned long long)next_bytenr, num_copies); |
@@ -902,7 +910,8 @@ static int btrfsic_process_superblock_dev_mirror( | |||
902 | struct btrfsic_block_data_ctx tmp_next_block_ctx; | 910 | struct btrfsic_block_data_ctx tmp_next_block_ctx; |
903 | struct btrfsic_block_link *l; | 911 | struct btrfsic_block_link *l; |
904 | 912 | ||
905 | if (btrfsic_map_block(state, next_bytenr, PAGE_SIZE, | 913 | if (btrfsic_map_block(state, next_bytenr, |
914 | state->metablock_size, | ||
906 | &tmp_next_block_ctx, | 915 | &tmp_next_block_ctx, |
907 | mirror_num)) { | 916 | mirror_num)) { |
908 | printk(KERN_INFO "btrfsic: btrfsic_map_block(" | 917 | printk(KERN_INFO "btrfsic: btrfsic_map_block(" |
@@ -966,13 +975,15 @@ static int btrfsic_process_metablock( | |||
966 | struct btrfsic_state *state, | 975 | struct btrfsic_state *state, |
967 | struct btrfsic_block *const first_block, | 976 | struct btrfsic_block *const first_block, |
968 | struct btrfsic_block_data_ctx *const first_block_ctx, | 977 | struct btrfsic_block_data_ctx *const first_block_ctx, |
969 | struct btrfs_header *const first_hdr, | ||
970 | int first_limit_nesting, int force_iodone_flag) | 978 | int first_limit_nesting, int force_iodone_flag) |
971 | { | 979 | { |
972 | struct btrfsic_stack_frame initial_stack_frame = { 0 }; | 980 | struct btrfsic_stack_frame initial_stack_frame = { 0 }; |
973 | struct btrfsic_stack_frame *sf; | 981 | struct btrfsic_stack_frame *sf; |
974 | struct btrfsic_stack_frame *next_stack; | 982 | struct btrfsic_stack_frame *next_stack; |
983 | struct btrfs_header *const first_hdr = | ||
984 | (struct btrfs_header *)first_block_ctx->datav[0]; | ||
975 | 985 | ||
986 | BUG_ON(!first_hdr); | ||
976 | sf = &initial_stack_frame; | 987 | sf = &initial_stack_frame; |
977 | sf->error = 0; | 988 | sf->error = 0; |
978 | sf->i = -1; | 989 | sf->i = -1; |
@@ -1012,21 +1023,47 @@ continue_with_current_leaf_stack_frame: | |||
1012 | } | 1023 | } |
1013 | 1024 | ||
1014 | if (sf->i < sf->nr) { | 1025 | if (sf->i < sf->nr) { |
1015 | struct btrfs_item *disk_item = leafhdr->items + sf->i; | 1026 | struct btrfs_item disk_item; |
1016 | struct btrfs_disk_key *disk_key = &disk_item->key; | 1027 | u32 disk_item_offset = |
1028 | (uintptr_t)(leafhdr->items + sf->i) - | ||
1029 | (uintptr_t)leafhdr; | ||
1030 | struct btrfs_disk_key *disk_key; | ||
1017 | u8 type; | 1031 | u8 type; |
1018 | const u32 item_offset = le32_to_cpu(disk_item->offset); | 1032 | u32 item_offset; |
1019 | 1033 | ||
1034 | if (disk_item_offset + sizeof(struct btrfs_item) > | ||
1035 | sf->block_ctx->len) { | ||
1036 | leaf_item_out_of_bounce_error: | ||
1037 | printk(KERN_INFO | ||
1038 | "btrfsic: leaf item out of bounce at logical %llu, dev %s\n", | ||
1039 | sf->block_ctx->start, | ||
1040 | sf->block_ctx->dev->name); | ||
1041 | goto one_stack_frame_backwards; | ||
1042 | } | ||
1043 | btrfsic_read_from_block_data(sf->block_ctx, | ||
1044 | &disk_item, | ||
1045 | disk_item_offset, | ||
1046 | sizeof(struct btrfs_item)); | ||
1047 | item_offset = le32_to_cpu(disk_item.offset); | ||
1048 | disk_key = &disk_item.key; | ||
1020 | type = disk_key->type; | 1049 | type = disk_key->type; |
1021 | 1050 | ||
1022 | if (BTRFS_ROOT_ITEM_KEY == type) { | 1051 | if (BTRFS_ROOT_ITEM_KEY == type) { |
1023 | const struct btrfs_root_item *const root_item = | 1052 | struct btrfs_root_item root_item; |
1024 | (struct btrfs_root_item *) | 1053 | u32 root_item_offset; |
1025 | (sf->block_ctx->data + | 1054 | u64 next_bytenr; |
1026 | offsetof(struct btrfs_leaf, items) + | 1055 | |
1027 | item_offset); | 1056 | root_item_offset = item_offset + |
1028 | const u64 next_bytenr = | 1057 | offsetof(struct btrfs_leaf, items); |
1029 | le64_to_cpu(root_item->bytenr); | 1058 | if (root_item_offset + |
1059 | sizeof(struct btrfs_root_item) > | ||
1060 | sf->block_ctx->len) | ||
1061 | goto leaf_item_out_of_bounce_error; | ||
1062 | btrfsic_read_from_block_data( | ||
1063 | sf->block_ctx, &root_item, | ||
1064 | root_item_offset, | ||
1065 | sizeof(struct btrfs_root_item)); | ||
1066 | next_bytenr = le64_to_cpu(root_item.bytenr); | ||
1030 | 1067 | ||
1031 | sf->error = | 1068 | sf->error = |
1032 | btrfsic_create_link_to_next_block( | 1069 | btrfsic_create_link_to_next_block( |
@@ -1041,7 +1078,7 @@ continue_with_current_leaf_stack_frame: | |||
1041 | &sf->num_copies, | 1078 | &sf->num_copies, |
1042 | &sf->mirror_num, | 1079 | &sf->mirror_num, |
1043 | disk_key, | 1080 | disk_key, |
1044 | le64_to_cpu(root_item-> | 1081 | le64_to_cpu(root_item. |
1045 | generation)); | 1082 | generation)); |
1046 | if (sf->error) | 1083 | if (sf->error) |
1047 | goto one_stack_frame_backwards; | 1084 | goto one_stack_frame_backwards; |
@@ -1049,7 +1086,7 @@ continue_with_current_leaf_stack_frame: | |||
1049 | if (NULL != sf->next_block) { | 1086 | if (NULL != sf->next_block) { |
1050 | struct btrfs_header *const next_hdr = | 1087 | struct btrfs_header *const next_hdr = |
1051 | (struct btrfs_header *) | 1088 | (struct btrfs_header *) |
1052 | sf->next_block_ctx.data; | 1089 | sf->next_block_ctx.datav[0]; |
1053 | 1090 | ||
1054 | next_stack = | 1091 | next_stack = |
1055 | btrfsic_stack_frame_alloc(); | 1092 | btrfsic_stack_frame_alloc(); |
@@ -1111,10 +1148,24 @@ continue_with_current_node_stack_frame: | |||
1111 | } | 1148 | } |
1112 | 1149 | ||
1113 | if (sf->i < sf->nr) { | 1150 | if (sf->i < sf->nr) { |
1114 | struct btrfs_key_ptr *disk_key_ptr = | 1151 | struct btrfs_key_ptr key_ptr; |
1115 | nodehdr->ptrs + sf->i; | 1152 | u32 key_ptr_offset; |
1116 | const u64 next_bytenr = | 1153 | u64 next_bytenr; |
1117 | le64_to_cpu(disk_key_ptr->blockptr); | 1154 | |
1155 | key_ptr_offset = (uintptr_t)(nodehdr->ptrs + sf->i) - | ||
1156 | (uintptr_t)nodehdr; | ||
1157 | if (key_ptr_offset + sizeof(struct btrfs_key_ptr) > | ||
1158 | sf->block_ctx->len) { | ||
1159 | printk(KERN_INFO | ||
1160 | "btrfsic: node item out of bounce at logical %llu, dev %s\n", | ||
1161 | sf->block_ctx->start, | ||
1162 | sf->block_ctx->dev->name); | ||
1163 | goto one_stack_frame_backwards; | ||
1164 | } | ||
1165 | btrfsic_read_from_block_data( | ||
1166 | sf->block_ctx, &key_ptr, key_ptr_offset, | ||
1167 | sizeof(struct btrfs_key_ptr)); | ||
1168 | next_bytenr = le64_to_cpu(key_ptr.blockptr); | ||
1118 | 1169 | ||
1119 | sf->error = btrfsic_create_link_to_next_block( | 1170 | sf->error = btrfsic_create_link_to_next_block( |
1120 | state, | 1171 | state, |
@@ -1127,15 +1178,15 @@ continue_with_current_node_stack_frame: | |||
1127 | force_iodone_flag, | 1178 | force_iodone_flag, |
1128 | &sf->num_copies, | 1179 | &sf->num_copies, |
1129 | &sf->mirror_num, | 1180 | &sf->mirror_num, |
1130 | &disk_key_ptr->key, | 1181 | &key_ptr.key, |
1131 | le64_to_cpu(disk_key_ptr->generation)); | 1182 | le64_to_cpu(key_ptr.generation)); |
1132 | if (sf->error) | 1183 | if (sf->error) |
1133 | goto one_stack_frame_backwards; | 1184 | goto one_stack_frame_backwards; |
1134 | 1185 | ||
1135 | if (NULL != sf->next_block) { | 1186 | if (NULL != sf->next_block) { |
1136 | struct btrfs_header *const next_hdr = | 1187 | struct btrfs_header *const next_hdr = |
1137 | (struct btrfs_header *) | 1188 | (struct btrfs_header *) |
1138 | sf->next_block_ctx.data; | 1189 | sf->next_block_ctx.datav[0]; |
1139 | 1190 | ||
1140 | next_stack = btrfsic_stack_frame_alloc(); | 1191 | next_stack = btrfsic_stack_frame_alloc(); |
1141 | if (NULL == next_stack) | 1192 | if (NULL == next_stack) |
@@ -1181,6 +1232,35 @@ one_stack_frame_backwards: | |||
1181 | return sf->error; | 1232 | return sf->error; |
1182 | } | 1233 | } |
1183 | 1234 | ||
1235 | static void btrfsic_read_from_block_data( | ||
1236 | struct btrfsic_block_data_ctx *block_ctx, | ||
1237 | void *dstv, u32 offset, size_t len) | ||
1238 | { | ||
1239 | size_t cur; | ||
1240 | size_t offset_in_page; | ||
1241 | char *kaddr; | ||
1242 | char *dst = (char *)dstv; | ||
1243 | size_t start_offset = block_ctx->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
1244 | unsigned long i = (start_offset + offset) >> PAGE_CACHE_SHIFT; | ||
1245 | |||
1246 | WARN_ON(offset + len > block_ctx->len); | ||
1247 | offset_in_page = (start_offset + offset) & | ||
1248 | ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
1249 | |||
1250 | while (len > 0) { | ||
1251 | cur = min(len, ((size_t)PAGE_CACHE_SIZE - offset_in_page)); | ||
1252 | BUG_ON(i >= (block_ctx->len + PAGE_CACHE_SIZE - 1) >> | ||
1253 | PAGE_CACHE_SHIFT); | ||
1254 | kaddr = block_ctx->datav[i]; | ||
1255 | memcpy(dst, kaddr + offset_in_page, cur); | ||
1256 | |||
1257 | dst += cur; | ||
1258 | len -= cur; | ||
1259 | offset_in_page = 0; | ||
1260 | i++; | ||
1261 | } | ||
1262 | } | ||
1263 | |||
1184 | static int btrfsic_create_link_to_next_block( | 1264 | static int btrfsic_create_link_to_next_block( |
1185 | struct btrfsic_state *state, | 1265 | struct btrfsic_state *state, |
1186 | struct btrfsic_block *block, | 1266 | struct btrfsic_block *block, |
@@ -1204,7 +1284,7 @@ static int btrfsic_create_link_to_next_block( | |||
1204 | if (0 == *num_copiesp) { | 1284 | if (0 == *num_copiesp) { |
1205 | *num_copiesp = | 1285 | *num_copiesp = |
1206 | btrfs_num_copies(&state->root->fs_info->mapping_tree, | 1286 | btrfs_num_copies(&state->root->fs_info->mapping_tree, |
1207 | next_bytenr, PAGE_SIZE); | 1287 | next_bytenr, state->metablock_size); |
1208 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) | 1288 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) |
1209 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", | 1289 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", |
1210 | (unsigned long long)next_bytenr, *num_copiesp); | 1290 | (unsigned long long)next_bytenr, *num_copiesp); |
@@ -1219,7 +1299,7 @@ static int btrfsic_create_link_to_next_block( | |||
1219 | "btrfsic_create_link_to_next_block(mirror_num=%d)\n", | 1299 | "btrfsic_create_link_to_next_block(mirror_num=%d)\n", |
1220 | *mirror_nump); | 1300 | *mirror_nump); |
1221 | ret = btrfsic_map_block(state, next_bytenr, | 1301 | ret = btrfsic_map_block(state, next_bytenr, |
1222 | BTRFSIC_BLOCK_SIZE, | 1302 | state->metablock_size, |
1223 | next_block_ctx, *mirror_nump); | 1303 | next_block_ctx, *mirror_nump); |
1224 | if (ret) { | 1304 | if (ret) { |
1225 | printk(KERN_INFO | 1305 | printk(KERN_INFO |
@@ -1314,7 +1394,7 @@ static int btrfsic_create_link_to_next_block( | |||
1314 | 1394 | ||
1315 | if (limit_nesting > 0 && did_alloc_block_link) { | 1395 | if (limit_nesting > 0 && did_alloc_block_link) { |
1316 | ret = btrfsic_read_block(state, next_block_ctx); | 1396 | ret = btrfsic_read_block(state, next_block_ctx); |
1317 | if (ret < (int)BTRFSIC_BLOCK_SIZE) { | 1397 | if (ret < (int)next_block_ctx->len) { |
1318 | printk(KERN_INFO | 1398 | printk(KERN_INFO |
1319 | "btrfsic: read block @logical %llu failed!\n", | 1399 | "btrfsic: read block @logical %llu failed!\n", |
1320 | (unsigned long long)next_bytenr); | 1400 | (unsigned long long)next_bytenr); |
@@ -1339,43 +1419,55 @@ static int btrfsic_handle_extent_data( | |||
1339 | u32 item_offset, int force_iodone_flag) | 1419 | u32 item_offset, int force_iodone_flag) |
1340 | { | 1420 | { |
1341 | int ret; | 1421 | int ret; |
1342 | struct btrfs_file_extent_item *file_extent_item = | 1422 | struct btrfs_file_extent_item file_extent_item; |
1343 | (struct btrfs_file_extent_item *)(block_ctx->data + | 1423 | u64 file_extent_item_offset; |
1344 | offsetof(struct btrfs_leaf, | 1424 | u64 next_bytenr; |
1345 | items) + item_offset); | 1425 | u64 num_bytes; |
1346 | u64 next_bytenr = | 1426 | u64 generation; |
1347 | le64_to_cpu(file_extent_item->disk_bytenr) + | ||
1348 | le64_to_cpu(file_extent_item->offset); | ||
1349 | u64 num_bytes = le64_to_cpu(file_extent_item->num_bytes); | ||
1350 | u64 generation = le64_to_cpu(file_extent_item->generation); | ||
1351 | struct btrfsic_block_link *l; | 1427 | struct btrfsic_block_link *l; |
1352 | 1428 | ||
1429 | file_extent_item_offset = offsetof(struct btrfs_leaf, items) + | ||
1430 | item_offset; | ||
1431 | if (file_extent_item_offset + sizeof(struct btrfs_file_extent_item) > | ||
1432 | block_ctx->len) { | ||
1433 | printk(KERN_INFO | ||
1434 | "btrfsic: file item out of bounce at logical %llu, dev %s\n", | ||
1435 | block_ctx->start, block_ctx->dev->name); | ||
1436 | return -1; | ||
1437 | } | ||
1438 | btrfsic_read_from_block_data(block_ctx, &file_extent_item, | ||
1439 | file_extent_item_offset, | ||
1440 | sizeof(struct btrfs_file_extent_item)); | ||
1441 | next_bytenr = le64_to_cpu(file_extent_item.disk_bytenr) + | ||
1442 | le64_to_cpu(file_extent_item.offset); | ||
1443 | generation = le64_to_cpu(file_extent_item.generation); | ||
1444 | num_bytes = le64_to_cpu(file_extent_item.num_bytes); | ||
1445 | generation = le64_to_cpu(file_extent_item.generation); | ||
1446 | |||
1353 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERY_VERBOSE) | 1447 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERY_VERBOSE) |
1354 | printk(KERN_INFO "extent_data: type %u, disk_bytenr = %llu," | 1448 | printk(KERN_INFO "extent_data: type %u, disk_bytenr = %llu," |
1355 | " offset = %llu, num_bytes = %llu\n", | 1449 | " offset = %llu, num_bytes = %llu\n", |
1356 | file_extent_item->type, | 1450 | file_extent_item.type, |
1357 | (unsigned long long) | ||
1358 | le64_to_cpu(file_extent_item->disk_bytenr), | ||
1359 | (unsigned long long) | ||
1360 | le64_to_cpu(file_extent_item->offset), | ||
1361 | (unsigned long long) | 1451 | (unsigned long long) |
1362 | le64_to_cpu(file_extent_item->num_bytes)); | 1452 | le64_to_cpu(file_extent_item.disk_bytenr), |
1363 | if (BTRFS_FILE_EXTENT_REG != file_extent_item->type || | 1453 | (unsigned long long)le64_to_cpu(file_extent_item.offset), |
1364 | ((u64)0) == le64_to_cpu(file_extent_item->disk_bytenr)) | 1454 | (unsigned long long)num_bytes); |
1455 | if (BTRFS_FILE_EXTENT_REG != file_extent_item.type || | ||
1456 | ((u64)0) == le64_to_cpu(file_extent_item.disk_bytenr)) | ||
1365 | return 0; | 1457 | return 0; |
1366 | while (num_bytes > 0) { | 1458 | while (num_bytes > 0) { |
1367 | u32 chunk_len; | 1459 | u32 chunk_len; |
1368 | int num_copies; | 1460 | int num_copies; |
1369 | int mirror_num; | 1461 | int mirror_num; |
1370 | 1462 | ||
1371 | if (num_bytes > BTRFSIC_BLOCK_SIZE) | 1463 | if (num_bytes > state->datablock_size) |
1372 | chunk_len = BTRFSIC_BLOCK_SIZE; | 1464 | chunk_len = state->datablock_size; |
1373 | else | 1465 | else |
1374 | chunk_len = num_bytes; | 1466 | chunk_len = num_bytes; |
1375 | 1467 | ||
1376 | num_copies = | 1468 | num_copies = |
1377 | btrfs_num_copies(&state->root->fs_info->mapping_tree, | 1469 | btrfs_num_copies(&state->root->fs_info->mapping_tree, |
1378 | next_bytenr, PAGE_SIZE); | 1470 | next_bytenr, state->datablock_size); |
1379 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) | 1471 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) |
1380 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", | 1472 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", |
1381 | (unsigned long long)next_bytenr, num_copies); | 1473 | (unsigned long long)next_bytenr, num_copies); |
@@ -1475,8 +1567,9 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, | |||
1475 | block_ctx_out->dev_bytenr = multi->stripes[0].physical; | 1567 | block_ctx_out->dev_bytenr = multi->stripes[0].physical; |
1476 | block_ctx_out->start = bytenr; | 1568 | block_ctx_out->start = bytenr; |
1477 | block_ctx_out->len = len; | 1569 | block_ctx_out->len = len; |
1478 | block_ctx_out->data = NULL; | 1570 | block_ctx_out->datav = NULL; |
1479 | block_ctx_out->bh = NULL; | 1571 | block_ctx_out->pagev = NULL; |
1572 | block_ctx_out->mem_to_free = NULL; | ||
1480 | 1573 | ||
1481 | if (0 == ret) | 1574 | if (0 == ret) |
1482 | kfree(multi); | 1575 | kfree(multi); |
@@ -1496,8 +1589,9 @@ static int btrfsic_map_superblock(struct btrfsic_state *state, u64 bytenr, | |||
1496 | block_ctx_out->dev_bytenr = bytenr; | 1589 | block_ctx_out->dev_bytenr = bytenr; |
1497 | block_ctx_out->start = bytenr; | 1590 | block_ctx_out->start = bytenr; |
1498 | block_ctx_out->len = len; | 1591 | block_ctx_out->len = len; |
1499 | block_ctx_out->data = NULL; | 1592 | block_ctx_out->datav = NULL; |
1500 | block_ctx_out->bh = NULL; | 1593 | block_ctx_out->pagev = NULL; |
1594 | block_ctx_out->mem_to_free = NULL; | ||
1501 | if (NULL != block_ctx_out->dev) { | 1595 | if (NULL != block_ctx_out->dev) { |
1502 | return 0; | 1596 | return 0; |
1503 | } else { | 1597 | } else { |
@@ -1508,38 +1602,127 @@ static int btrfsic_map_superblock(struct btrfsic_state *state, u64 bytenr, | |||
1508 | 1602 | ||
1509 | static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx) | 1603 | static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx) |
1510 | { | 1604 | { |
1511 | if (NULL != block_ctx->bh) { | 1605 | if (block_ctx->mem_to_free) { |
1512 | brelse(block_ctx->bh); | 1606 | unsigned int num_pages; |
1513 | block_ctx->bh = NULL; | 1607 | |
1608 | BUG_ON(!block_ctx->datav); | ||
1609 | BUG_ON(!block_ctx->pagev); | ||
1610 | num_pages = (block_ctx->len + (u64)PAGE_CACHE_SIZE - 1) >> | ||
1611 | PAGE_CACHE_SHIFT; | ||
1612 | while (num_pages > 0) { | ||
1613 | num_pages--; | ||
1614 | if (block_ctx->datav[num_pages]) { | ||
1615 | kunmap(block_ctx->pagev[num_pages]); | ||
1616 | block_ctx->datav[num_pages] = NULL; | ||
1617 | } | ||
1618 | if (block_ctx->pagev[num_pages]) { | ||
1619 | __free_page(block_ctx->pagev[num_pages]); | ||
1620 | block_ctx->pagev[num_pages] = NULL; | ||
1621 | } | ||
1622 | } | ||
1623 | |||
1624 | kfree(block_ctx->mem_to_free); | ||
1625 | block_ctx->mem_to_free = NULL; | ||
1626 | block_ctx->pagev = NULL; | ||
1627 | block_ctx->datav = NULL; | ||
1514 | } | 1628 | } |
1515 | } | 1629 | } |
1516 | 1630 | ||
1517 | static int btrfsic_read_block(struct btrfsic_state *state, | 1631 | static int btrfsic_read_block(struct btrfsic_state *state, |
1518 | struct btrfsic_block_data_ctx *block_ctx) | 1632 | struct btrfsic_block_data_ctx *block_ctx) |
1519 | { | 1633 | { |
1520 | block_ctx->bh = NULL; | 1634 | unsigned int num_pages; |
1521 | if (block_ctx->dev_bytenr & 4095) { | 1635 | unsigned int i; |
1636 | u64 dev_bytenr; | ||
1637 | int ret; | ||
1638 | |||
1639 | BUG_ON(block_ctx->datav); | ||
1640 | BUG_ON(block_ctx->pagev); | ||
1641 | BUG_ON(block_ctx->mem_to_free); | ||
1642 | if (block_ctx->dev_bytenr & ((u64)PAGE_CACHE_SIZE - 1)) { | ||
1522 | printk(KERN_INFO | 1643 | printk(KERN_INFO |
1523 | "btrfsic: read_block() with unaligned bytenr %llu\n", | 1644 | "btrfsic: read_block() with unaligned bytenr %llu\n", |
1524 | (unsigned long long)block_ctx->dev_bytenr); | 1645 | (unsigned long long)block_ctx->dev_bytenr); |
1525 | return -1; | 1646 | return -1; |
1526 | } | 1647 | } |
1527 | if (block_ctx->len > 4096) { | 1648 | |
1528 | printk(KERN_INFO | 1649 | num_pages = (block_ctx->len + (u64)PAGE_CACHE_SIZE - 1) >> |
1529 | "btrfsic: read_block() with too huge size %d\n", | 1650 | PAGE_CACHE_SHIFT; |
1530 | block_ctx->len); | 1651 | block_ctx->mem_to_free = kzalloc((sizeof(*block_ctx->datav) + |
1652 | sizeof(*block_ctx->pagev)) * | ||
1653 | num_pages, GFP_NOFS); | ||
1654 | if (!block_ctx->mem_to_free) | ||
1531 | return -1; | 1655 | return -1; |
1656 | block_ctx->datav = block_ctx->mem_to_free; | ||
1657 | block_ctx->pagev = (struct page **)(block_ctx->datav + num_pages); | ||
1658 | for (i = 0; i < num_pages; i++) { | ||
1659 | block_ctx->pagev[i] = alloc_page(GFP_NOFS); | ||
1660 | if (!block_ctx->pagev[i]) | ||
1661 | return -1; | ||
1532 | } | 1662 | } |
1533 | 1663 | ||
1534 | block_ctx->bh = __bread(block_ctx->dev->bdev, | 1664 | dev_bytenr = block_ctx->dev_bytenr; |
1535 | block_ctx->dev_bytenr >> 12, 4096); | 1665 | for (i = 0; i < num_pages;) { |
1536 | if (NULL == block_ctx->bh) | 1666 | struct bio *bio; |
1537 | return -1; | 1667 | unsigned int j; |
1538 | block_ctx->data = block_ctx->bh->b_data; | 1668 | DECLARE_COMPLETION_ONSTACK(complete); |
1669 | |||
1670 | bio = bio_alloc(GFP_NOFS, num_pages - i); | ||
1671 | if (!bio) { | ||
1672 | printk(KERN_INFO | ||
1673 | "btrfsic: bio_alloc() for %u pages failed!\n", | ||
1674 | num_pages - i); | ||
1675 | return -1; | ||
1676 | } | ||
1677 | bio->bi_bdev = block_ctx->dev->bdev; | ||
1678 | bio->bi_sector = dev_bytenr >> 9; | ||
1679 | bio->bi_end_io = btrfsic_complete_bio_end_io; | ||
1680 | bio->bi_private = &complete; | ||
1681 | |||
1682 | for (j = i; j < num_pages; j++) { | ||
1683 | ret = bio_add_page(bio, block_ctx->pagev[j], | ||
1684 | PAGE_CACHE_SIZE, 0); | ||
1685 | if (PAGE_CACHE_SIZE != ret) | ||
1686 | break; | ||
1687 | } | ||
1688 | if (j == i) { | ||
1689 | printk(KERN_INFO | ||
1690 | "btrfsic: error, failed to add a single page!\n"); | ||
1691 | return -1; | ||
1692 | } | ||
1693 | submit_bio(READ, bio); | ||
1694 | |||
1695 | /* this will also unplug the queue */ | ||
1696 | wait_for_completion(&complete); | ||
1697 | |||
1698 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { | ||
1699 | printk(KERN_INFO | ||
1700 | "btrfsic: read error at logical %llu dev %s!\n", | ||
1701 | block_ctx->start, block_ctx->dev->name); | ||
1702 | bio_put(bio); | ||
1703 | return -1; | ||
1704 | } | ||
1705 | bio_put(bio); | ||
1706 | dev_bytenr += (j - i) * PAGE_CACHE_SIZE; | ||
1707 | i = j; | ||
1708 | } | ||
1709 | for (i = 0; i < num_pages; i++) { | ||
1710 | block_ctx->datav[i] = kmap(block_ctx->pagev[i]); | ||
1711 | if (!block_ctx->datav[i]) { | ||
1712 | printk(KERN_INFO "btrfsic: kmap() failed (dev %s)!\n", | ||
1713 | block_ctx->dev->name); | ||
1714 | return -1; | ||
1715 | } | ||
1716 | } | ||
1539 | 1717 | ||
1540 | return block_ctx->len; | 1718 | return block_ctx->len; |
1541 | } | 1719 | } |
1542 | 1720 | ||
1721 | static void btrfsic_complete_bio_end_io(struct bio *bio, int err) | ||
1722 | { | ||
1723 | complete((struct completion *)bio->bi_private); | ||
1724 | } | ||
1725 | |||
1543 | static void btrfsic_dump_database(struct btrfsic_state *state) | 1726 | static void btrfsic_dump_database(struct btrfsic_state *state) |
1544 | { | 1727 | { |
1545 | struct list_head *elem_all; | 1728 | struct list_head *elem_all; |
@@ -1617,32 +1800,39 @@ static void btrfsic_dump_database(struct btrfsic_state *state) | |||
1617 | * (note that this test fails for the super block) | 1800 | * (note that this test fails for the super block) |
1618 | */ | 1801 | */ |
1619 | static int btrfsic_test_for_metadata(struct btrfsic_state *state, | 1802 | static int btrfsic_test_for_metadata(struct btrfsic_state *state, |
1620 | const u8 *data, unsigned int size) | 1803 | char **datav, unsigned int num_pages) |
1621 | { | 1804 | { |
1622 | struct btrfs_header *h; | 1805 | struct btrfs_header *h; |
1623 | u8 csum[BTRFS_CSUM_SIZE]; | 1806 | u8 csum[BTRFS_CSUM_SIZE]; |
1624 | u32 crc = ~(u32)0; | 1807 | u32 crc = ~(u32)0; |
1625 | int fail = 0; | 1808 | unsigned int i; |
1626 | int crc_fail = 0; | ||
1627 | 1809 | ||
1628 | h = (struct btrfs_header *)data; | 1810 | if (num_pages * PAGE_CACHE_SIZE < state->metablock_size) |
1811 | return 1; /* not metadata */ | ||
1812 | num_pages = state->metablock_size >> PAGE_CACHE_SHIFT; | ||
1813 | h = (struct btrfs_header *)datav[0]; | ||
1629 | 1814 | ||
1630 | if (memcmp(h->fsid, state->root->fs_info->fsid, BTRFS_UUID_SIZE)) | 1815 | if (memcmp(h->fsid, state->root->fs_info->fsid, BTRFS_UUID_SIZE)) |
1631 | fail++; | 1816 | return 1; |
1632 | 1817 | ||
1633 | crc = crc32c(crc, data + BTRFS_CSUM_SIZE, PAGE_SIZE - BTRFS_CSUM_SIZE); | 1818 | for (i = 0; i < num_pages; i++) { |
1819 | u8 *data = i ? datav[i] : (datav[i] + BTRFS_CSUM_SIZE); | ||
1820 | size_t sublen = i ? PAGE_CACHE_SIZE : | ||
1821 | (PAGE_CACHE_SIZE - BTRFS_CSUM_SIZE); | ||
1822 | |||
1823 | crc = crc32c(crc, data, sublen); | ||
1824 | } | ||
1634 | btrfs_csum_final(crc, csum); | 1825 | btrfs_csum_final(crc, csum); |
1635 | if (memcmp(csum, h->csum, state->csum_size)) | 1826 | if (memcmp(csum, h->csum, state->csum_size)) |
1636 | crc_fail++; | 1827 | return 1; |
1637 | 1828 | ||
1638 | return fail || crc_fail; | 1829 | return 0; /* is metadata */ |
1639 | } | 1830 | } |
1640 | 1831 | ||
1641 | static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | 1832 | static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, |
1642 | u64 dev_bytenr, | 1833 | u64 dev_bytenr, char **mapped_datav, |
1643 | u8 *mapped_data, unsigned int len, | 1834 | unsigned int num_pages, |
1644 | struct bio *bio, | 1835 | struct bio *bio, int *bio_is_patched, |
1645 | int *bio_is_patched, | ||
1646 | struct buffer_head *bh, | 1836 | struct buffer_head *bh, |
1647 | int submit_bio_bh_rw) | 1837 | int submit_bio_bh_rw) |
1648 | { | 1838 | { |
@@ -1652,12 +1842,19 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1652 | int ret; | 1842 | int ret; |
1653 | struct btrfsic_state *state = dev_state->state; | 1843 | struct btrfsic_state *state = dev_state->state; |
1654 | struct block_device *bdev = dev_state->bdev; | 1844 | struct block_device *bdev = dev_state->bdev; |
1845 | unsigned int processed_len; | ||
1655 | 1846 | ||
1656 | WARN_ON(len > PAGE_SIZE); | ||
1657 | is_metadata = (0 == btrfsic_test_for_metadata(state, mapped_data, len)); | ||
1658 | if (NULL != bio_is_patched) | 1847 | if (NULL != bio_is_patched) |
1659 | *bio_is_patched = 0; | 1848 | *bio_is_patched = 0; |
1660 | 1849 | ||
1850 | again: | ||
1851 | if (num_pages == 0) | ||
1852 | return; | ||
1853 | |||
1854 | processed_len = 0; | ||
1855 | is_metadata = (0 == btrfsic_test_for_metadata(state, mapped_datav, | ||
1856 | num_pages)); | ||
1857 | |||
1661 | block = btrfsic_block_hashtable_lookup(bdev, dev_bytenr, | 1858 | block = btrfsic_block_hashtable_lookup(bdev, dev_bytenr, |
1662 | &state->block_hashtable); | 1859 | &state->block_hashtable); |
1663 | if (NULL != block) { | 1860 | if (NULL != block) { |
@@ -1667,8 +1864,16 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1667 | 1864 | ||
1668 | if (block->is_superblock) { | 1865 | if (block->is_superblock) { |
1669 | bytenr = le64_to_cpu(((struct btrfs_super_block *) | 1866 | bytenr = le64_to_cpu(((struct btrfs_super_block *) |
1670 | mapped_data)->bytenr); | 1867 | mapped_datav[0])->bytenr); |
1868 | if (num_pages * PAGE_CACHE_SIZE < | ||
1869 | BTRFS_SUPER_INFO_SIZE) { | ||
1870 | printk(KERN_INFO | ||
1871 | "btrfsic: cannot work with too short bios!\n"); | ||
1872 | return; | ||
1873 | } | ||
1671 | is_metadata = 1; | 1874 | is_metadata = 1; |
1875 | BUG_ON(BTRFS_SUPER_INFO_SIZE & (PAGE_CACHE_SIZE - 1)); | ||
1876 | processed_len = BTRFS_SUPER_INFO_SIZE; | ||
1672 | if (state->print_mask & | 1877 | if (state->print_mask & |
1673 | BTRFSIC_PRINT_MASK_TREE_BEFORE_SB_WRITE) { | 1878 | BTRFSIC_PRINT_MASK_TREE_BEFORE_SB_WRITE) { |
1674 | printk(KERN_INFO | 1879 | printk(KERN_INFO |
@@ -1678,12 +1883,18 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1678 | } | 1883 | } |
1679 | if (is_metadata) { | 1884 | if (is_metadata) { |
1680 | if (!block->is_superblock) { | 1885 | if (!block->is_superblock) { |
1886 | if (num_pages * PAGE_CACHE_SIZE < | ||
1887 | state->metablock_size) { | ||
1888 | printk(KERN_INFO | ||
1889 | "btrfsic: cannot work with too short bios!\n"); | ||
1890 | return; | ||
1891 | } | ||
1892 | processed_len = state->metablock_size; | ||
1681 | bytenr = le64_to_cpu(((struct btrfs_header *) | 1893 | bytenr = le64_to_cpu(((struct btrfs_header *) |
1682 | mapped_data)->bytenr); | 1894 | mapped_datav[0])->bytenr); |
1683 | btrfsic_cmp_log_and_dev_bytenr(state, bytenr, | 1895 | btrfsic_cmp_log_and_dev_bytenr(state, bytenr, |
1684 | dev_state, | 1896 | dev_state, |
1685 | dev_bytenr, | 1897 | dev_bytenr); |
1686 | mapped_data); | ||
1687 | } | 1898 | } |
1688 | if (block->logical_bytenr != bytenr) { | 1899 | if (block->logical_bytenr != bytenr) { |
1689 | printk(KERN_INFO | 1900 | printk(KERN_INFO |
@@ -1710,6 +1921,13 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1710 | block->mirror_num, | 1921 | block->mirror_num, |
1711 | btrfsic_get_block_type(state, block)); | 1922 | btrfsic_get_block_type(state, block)); |
1712 | } else { | 1923 | } else { |
1924 | if (num_pages * PAGE_CACHE_SIZE < | ||
1925 | state->datablock_size) { | ||
1926 | printk(KERN_INFO | ||
1927 | "btrfsic: cannot work with too short bios!\n"); | ||
1928 | return; | ||
1929 | } | ||
1930 | processed_len = state->datablock_size; | ||
1713 | bytenr = block->logical_bytenr; | 1931 | bytenr = block->logical_bytenr; |
1714 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) | 1932 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) |
1715 | printk(KERN_INFO | 1933 | printk(KERN_INFO |
@@ -1747,7 +1965,7 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1747 | le64_to_cpu(block->disk_key.offset), | 1965 | le64_to_cpu(block->disk_key.offset), |
1748 | (unsigned long long) | 1966 | (unsigned long long) |
1749 | le64_to_cpu(((struct btrfs_header *) | 1967 | le64_to_cpu(((struct btrfs_header *) |
1750 | mapped_data)->generation), | 1968 | mapped_datav[0])->generation), |
1751 | (unsigned long long) | 1969 | (unsigned long long) |
1752 | state->max_superblock_generation); | 1970 | state->max_superblock_generation); |
1753 | btrfsic_dump_tree(state); | 1971 | btrfsic_dump_tree(state); |
@@ -1765,10 +1983,10 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1765 | (unsigned long long)block->generation, | 1983 | (unsigned long long)block->generation, |
1766 | (unsigned long long) | 1984 | (unsigned long long) |
1767 | le64_to_cpu(((struct btrfs_header *) | 1985 | le64_to_cpu(((struct btrfs_header *) |
1768 | mapped_data)->generation)); | 1986 | mapped_datav[0])->generation)); |
1769 | /* it would not be safe to go on */ | 1987 | /* it would not be safe to go on */ |
1770 | btrfsic_dump_tree(state); | 1988 | btrfsic_dump_tree(state); |
1771 | return; | 1989 | goto continue_loop; |
1772 | } | 1990 | } |
1773 | 1991 | ||
1774 | /* | 1992 | /* |
@@ -1796,18 +2014,19 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1796 | } | 2014 | } |
1797 | 2015 | ||
1798 | if (block->is_superblock) | 2016 | if (block->is_superblock) |
1799 | ret = btrfsic_map_superblock(state, bytenr, len, | 2017 | ret = btrfsic_map_superblock(state, bytenr, |
2018 | processed_len, | ||
1800 | bdev, &block_ctx); | 2019 | bdev, &block_ctx); |
1801 | else | 2020 | else |
1802 | ret = btrfsic_map_block(state, bytenr, len, | 2021 | ret = btrfsic_map_block(state, bytenr, processed_len, |
1803 | &block_ctx, 0); | 2022 | &block_ctx, 0); |
1804 | if (ret) { | 2023 | if (ret) { |
1805 | printk(KERN_INFO | 2024 | printk(KERN_INFO |
1806 | "btrfsic: btrfsic_map_block(root @%llu)" | 2025 | "btrfsic: btrfsic_map_block(root @%llu)" |
1807 | " failed!\n", (unsigned long long)bytenr); | 2026 | " failed!\n", (unsigned long long)bytenr); |
1808 | return; | 2027 | goto continue_loop; |
1809 | } | 2028 | } |
1810 | block_ctx.data = mapped_data; | 2029 | block_ctx.datav = mapped_datav; |
1811 | /* the following is required in case of writes to mirrors, | 2030 | /* the following is required in case of writes to mirrors, |
1812 | * use the same that was used for the lookup */ | 2031 | * use the same that was used for the lookup */ |
1813 | block_ctx.dev = dev_state; | 2032 | block_ctx.dev = dev_state; |
@@ -1863,11 +2082,13 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1863 | block->logical_bytenr = bytenr; | 2082 | block->logical_bytenr = bytenr; |
1864 | block->is_metadata = 1; | 2083 | block->is_metadata = 1; |
1865 | if (block->is_superblock) { | 2084 | if (block->is_superblock) { |
2085 | BUG_ON(PAGE_CACHE_SIZE != | ||
2086 | BTRFS_SUPER_INFO_SIZE); | ||
1866 | ret = btrfsic_process_written_superblock( | 2087 | ret = btrfsic_process_written_superblock( |
1867 | state, | 2088 | state, |
1868 | block, | 2089 | block, |
1869 | (struct btrfs_super_block *) | 2090 | (struct btrfs_super_block *) |
1870 | mapped_data); | 2091 | mapped_datav[0]); |
1871 | if (state->print_mask & | 2092 | if (state->print_mask & |
1872 | BTRFSIC_PRINT_MASK_TREE_AFTER_SB_WRITE) { | 2093 | BTRFSIC_PRINT_MASK_TREE_AFTER_SB_WRITE) { |
1873 | printk(KERN_INFO | 2094 | printk(KERN_INFO |
@@ -1880,8 +2101,6 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1880 | state, | 2101 | state, |
1881 | block, | 2102 | block, |
1882 | &block_ctx, | 2103 | &block_ctx, |
1883 | (struct btrfs_header *) | ||
1884 | block_ctx.data, | ||
1885 | 0, 0); | 2104 | 0, 0); |
1886 | } | 2105 | } |
1887 | if (ret) | 2106 | if (ret) |
@@ -1912,26 +2131,30 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1912 | u64 bytenr; | 2131 | u64 bytenr; |
1913 | 2132 | ||
1914 | if (!is_metadata) { | 2133 | if (!is_metadata) { |
2134 | processed_len = state->datablock_size; | ||
1915 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) | 2135 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) |
1916 | printk(KERN_INFO "Written block (%s/%llu/?)" | 2136 | printk(KERN_INFO "Written block (%s/%llu/?)" |
1917 | " !found in hash table, D.\n", | 2137 | " !found in hash table, D.\n", |
1918 | dev_state->name, | 2138 | dev_state->name, |
1919 | (unsigned long long)dev_bytenr); | 2139 | (unsigned long long)dev_bytenr); |
1920 | if (!state->include_extent_data) | 2140 | if (!state->include_extent_data) { |
1921 | return; /* ignore that written D block */ | 2141 | /* ignore that written D block */ |
2142 | goto continue_loop; | ||
2143 | } | ||
1922 | 2144 | ||
1923 | /* this is getting ugly for the | 2145 | /* this is getting ugly for the |
1924 | * include_extent_data case... */ | 2146 | * include_extent_data case... */ |
1925 | bytenr = 0; /* unknown */ | 2147 | bytenr = 0; /* unknown */ |
1926 | block_ctx.start = bytenr; | 2148 | block_ctx.start = bytenr; |
1927 | block_ctx.len = len; | 2149 | block_ctx.len = processed_len; |
1928 | block_ctx.bh = NULL; | 2150 | block_ctx.mem_to_free = NULL; |
2151 | block_ctx.pagev = NULL; | ||
1929 | } else { | 2152 | } else { |
2153 | processed_len = state->metablock_size; | ||
1930 | bytenr = le64_to_cpu(((struct btrfs_header *) | 2154 | bytenr = le64_to_cpu(((struct btrfs_header *) |
1931 | mapped_data)->bytenr); | 2155 | mapped_datav[0])->bytenr); |
1932 | btrfsic_cmp_log_and_dev_bytenr(state, bytenr, dev_state, | 2156 | btrfsic_cmp_log_and_dev_bytenr(state, bytenr, dev_state, |
1933 | dev_bytenr, | 2157 | dev_bytenr); |
1934 | mapped_data); | ||
1935 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) | 2158 | if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) |
1936 | printk(KERN_INFO | 2159 | printk(KERN_INFO |
1937 | "Written block @%llu (%s/%llu/?)" | 2160 | "Written block @%llu (%s/%llu/?)" |
@@ -1940,17 +2163,17 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1940 | dev_state->name, | 2163 | dev_state->name, |
1941 | (unsigned long long)dev_bytenr); | 2164 | (unsigned long long)dev_bytenr); |
1942 | 2165 | ||
1943 | ret = btrfsic_map_block(state, bytenr, len, &block_ctx, | 2166 | ret = btrfsic_map_block(state, bytenr, processed_len, |
1944 | 0); | 2167 | &block_ctx, 0); |
1945 | if (ret) { | 2168 | if (ret) { |
1946 | printk(KERN_INFO | 2169 | printk(KERN_INFO |
1947 | "btrfsic: btrfsic_map_block(root @%llu)" | 2170 | "btrfsic: btrfsic_map_block(root @%llu)" |
1948 | " failed!\n", | 2171 | " failed!\n", |
1949 | (unsigned long long)dev_bytenr); | 2172 | (unsigned long long)dev_bytenr); |
1950 | return; | 2173 | goto continue_loop; |
1951 | } | 2174 | } |
1952 | } | 2175 | } |
1953 | block_ctx.data = mapped_data; | 2176 | block_ctx.datav = mapped_datav; |
1954 | /* the following is required in case of writes to mirrors, | 2177 | /* the following is required in case of writes to mirrors, |
1955 | * use the same that was used for the lookup */ | 2178 | * use the same that was used for the lookup */ |
1956 | block_ctx.dev = dev_state; | 2179 | block_ctx.dev = dev_state; |
@@ -1960,7 +2183,7 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
1960 | if (NULL == block) { | 2183 | if (NULL == block) { |
1961 | printk(KERN_INFO "btrfsic: error, kmalloc failed!\n"); | 2184 | printk(KERN_INFO "btrfsic: error, kmalloc failed!\n"); |
1962 | btrfsic_release_block_ctx(&block_ctx); | 2185 | btrfsic_release_block_ctx(&block_ctx); |
1963 | return; | 2186 | goto continue_loop; |
1964 | } | 2187 | } |
1965 | block->dev_state = dev_state; | 2188 | block->dev_state = dev_state; |
1966 | block->dev_bytenr = dev_bytenr; | 2189 | block->dev_bytenr = dev_bytenr; |
@@ -2020,9 +2243,7 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
2020 | 2243 | ||
2021 | if (is_metadata) { | 2244 | if (is_metadata) { |
2022 | ret = btrfsic_process_metablock(state, block, | 2245 | ret = btrfsic_process_metablock(state, block, |
2023 | &block_ctx, | 2246 | &block_ctx, 0, 0); |
2024 | (struct btrfs_header *) | ||
2025 | block_ctx.data, 0, 0); | ||
2026 | if (ret) | 2247 | if (ret) |
2027 | printk(KERN_INFO | 2248 | printk(KERN_INFO |
2028 | "btrfsic: process_metablock(root @%llu)" | 2249 | "btrfsic: process_metablock(root @%llu)" |
@@ -2031,6 +2252,13 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, | |||
2031 | } | 2252 | } |
2032 | btrfsic_release_block_ctx(&block_ctx); | 2253 | btrfsic_release_block_ctx(&block_ctx); |
2033 | } | 2254 | } |
2255 | |||
2256 | continue_loop: | ||
2257 | BUG_ON(!processed_len); | ||
2258 | dev_bytenr += processed_len; | ||
2259 | mapped_datav += processed_len >> PAGE_CACHE_SHIFT; | ||
2260 | num_pages -= processed_len >> PAGE_CACHE_SHIFT; | ||
2261 | goto again; | ||
2034 | } | 2262 | } |
2035 | 2263 | ||
2036 | static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status) | 2264 | static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status) |
@@ -2213,7 +2441,7 @@ static int btrfsic_process_written_superblock( | |||
2213 | 2441 | ||
2214 | num_copies = | 2442 | num_copies = |
2215 | btrfs_num_copies(&state->root->fs_info->mapping_tree, | 2443 | btrfs_num_copies(&state->root->fs_info->mapping_tree, |
2216 | next_bytenr, PAGE_SIZE); | 2444 | next_bytenr, BTRFS_SUPER_INFO_SIZE); |
2217 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) | 2445 | if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES) |
2218 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", | 2446 | printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n", |
2219 | (unsigned long long)next_bytenr, num_copies); | 2447 | (unsigned long long)next_bytenr, num_copies); |
@@ -2224,7 +2452,8 @@ static int btrfsic_process_written_superblock( | |||
2224 | printk(KERN_INFO | 2452 | printk(KERN_INFO |
2225 | "btrfsic_process_written_superblock(" | 2453 | "btrfsic_process_written_superblock(" |
2226 | "mirror_num=%d)\n", mirror_num); | 2454 | "mirror_num=%d)\n", mirror_num); |
2227 | ret = btrfsic_map_block(state, next_bytenr, PAGE_SIZE, | 2455 | ret = btrfsic_map_block(state, next_bytenr, |
2456 | BTRFS_SUPER_INFO_SIZE, | ||
2228 | &tmp_next_block_ctx, | 2457 | &tmp_next_block_ctx, |
2229 | mirror_num); | 2458 | mirror_num); |
2230 | if (ret) { | 2459 | if (ret) { |
@@ -2689,7 +2918,7 @@ static struct btrfsic_block *btrfsic_block_lookup_or_add( | |||
2689 | static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | 2918 | static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, |
2690 | u64 bytenr, | 2919 | u64 bytenr, |
2691 | struct btrfsic_dev_state *dev_state, | 2920 | struct btrfsic_dev_state *dev_state, |
2692 | u64 dev_bytenr, char *data) | 2921 | u64 dev_bytenr) |
2693 | { | 2922 | { |
2694 | int num_copies; | 2923 | int num_copies; |
2695 | int mirror_num; | 2924 | int mirror_num; |
@@ -2698,10 +2927,10 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | |||
2698 | int match = 0; | 2927 | int match = 0; |
2699 | 2928 | ||
2700 | num_copies = btrfs_num_copies(&state->root->fs_info->mapping_tree, | 2929 | num_copies = btrfs_num_copies(&state->root->fs_info->mapping_tree, |
2701 | bytenr, PAGE_SIZE); | 2930 | bytenr, state->metablock_size); |
2702 | 2931 | ||
2703 | for (mirror_num = 1; mirror_num <= num_copies; mirror_num++) { | 2932 | for (mirror_num = 1; mirror_num <= num_copies; mirror_num++) { |
2704 | ret = btrfsic_map_block(state, bytenr, PAGE_SIZE, | 2933 | ret = btrfsic_map_block(state, bytenr, state->metablock_size, |
2705 | &block_ctx, mirror_num); | 2934 | &block_ctx, mirror_num); |
2706 | if (ret) { | 2935 | if (ret) { |
2707 | printk(KERN_INFO "btrfsic:" | 2936 | printk(KERN_INFO "btrfsic:" |
@@ -2727,7 +2956,8 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | |||
2727 | (unsigned long long)bytenr, dev_state->name, | 2956 | (unsigned long long)bytenr, dev_state->name, |
2728 | (unsigned long long)dev_bytenr); | 2957 | (unsigned long long)dev_bytenr); |
2729 | for (mirror_num = 1; mirror_num <= num_copies; mirror_num++) { | 2958 | for (mirror_num = 1; mirror_num <= num_copies; mirror_num++) { |
2730 | ret = btrfsic_map_block(state, bytenr, PAGE_SIZE, | 2959 | ret = btrfsic_map_block(state, bytenr, |
2960 | state->metablock_size, | ||
2731 | &block_ctx, mirror_num); | 2961 | &block_ctx, mirror_num); |
2732 | if (ret) | 2962 | if (ret) |
2733 | continue; | 2963 | continue; |
@@ -2781,13 +3011,13 @@ int btrfsic_submit_bh(int rw, struct buffer_head *bh) | |||
2781 | (unsigned long)bh->b_size, bh->b_data, | 3011 | (unsigned long)bh->b_size, bh->b_data, |
2782 | bh->b_bdev); | 3012 | bh->b_bdev); |
2783 | btrfsic_process_written_block(dev_state, dev_bytenr, | 3013 | btrfsic_process_written_block(dev_state, dev_bytenr, |
2784 | bh->b_data, bh->b_size, NULL, | 3014 | &bh->b_data, 1, NULL, |
2785 | NULL, bh, rw); | 3015 | NULL, bh, rw); |
2786 | } else if (NULL != dev_state && (rw & REQ_FLUSH)) { | 3016 | } else if (NULL != dev_state && (rw & REQ_FLUSH)) { |
2787 | if (dev_state->state->print_mask & | 3017 | if (dev_state->state->print_mask & |
2788 | BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) | 3018 | BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) |
2789 | printk(KERN_INFO | 3019 | printk(KERN_INFO |
2790 | "submit_bh(rw=0x%x) FLUSH, bdev=%p)\n", | 3020 | "submit_bh(rw=0x%x FLUSH, bdev=%p)\n", |
2791 | rw, bh->b_bdev); | 3021 | rw, bh->b_bdev); |
2792 | if (!dev_state->dummy_block_for_bio_bh_flush.is_iodone) { | 3022 | if (!dev_state->dummy_block_for_bio_bh_flush.is_iodone) { |
2793 | if ((dev_state->state->print_mask & | 3023 | if ((dev_state->state->print_mask & |
@@ -2836,6 +3066,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio) | |||
2836 | unsigned int i; | 3066 | unsigned int i; |
2837 | u64 dev_bytenr; | 3067 | u64 dev_bytenr; |
2838 | int bio_is_patched; | 3068 | int bio_is_patched; |
3069 | char **mapped_datav; | ||
2839 | 3070 | ||
2840 | dev_bytenr = 512 * bio->bi_sector; | 3071 | dev_bytenr = 512 * bio->bi_sector; |
2841 | bio_is_patched = 0; | 3072 | bio_is_patched = 0; |
@@ -2848,35 +3079,46 @@ void btrfsic_submit_bio(int rw, struct bio *bio) | |||
2848 | (unsigned long long)dev_bytenr, | 3079 | (unsigned long long)dev_bytenr, |
2849 | bio->bi_bdev); | 3080 | bio->bi_bdev); |
2850 | 3081 | ||
3082 | mapped_datav = kmalloc(sizeof(*mapped_datav) * bio->bi_vcnt, | ||
3083 | GFP_NOFS); | ||
3084 | if (!mapped_datav) | ||
3085 | goto leave; | ||
2851 | for (i = 0; i < bio->bi_vcnt; i++) { | 3086 | for (i = 0; i < bio->bi_vcnt; i++) { |
2852 | u8 *mapped_data; | 3087 | BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_CACHE_SIZE); |
2853 | 3088 | mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page); | |
2854 | mapped_data = kmap(bio->bi_io_vec[i].bv_page); | 3089 | if (!mapped_datav[i]) { |
3090 | while (i > 0) { | ||
3091 | i--; | ||
3092 | kunmap(bio->bi_io_vec[i].bv_page); | ||
3093 | } | ||
3094 | kfree(mapped_datav); | ||
3095 | goto leave; | ||
3096 | } | ||
2855 | if ((BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | | 3097 | if ((BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | |
2856 | BTRFSIC_PRINT_MASK_VERBOSE) == | 3098 | BTRFSIC_PRINT_MASK_VERBOSE) == |
2857 | (dev_state->state->print_mask & | 3099 | (dev_state->state->print_mask & |
2858 | (BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | | 3100 | (BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | |
2859 | BTRFSIC_PRINT_MASK_VERBOSE))) | 3101 | BTRFSIC_PRINT_MASK_VERBOSE))) |
2860 | printk(KERN_INFO | 3102 | printk(KERN_INFO |
2861 | "#%u: page=%p, mapped=%p, len=%u," | 3103 | "#%u: page=%p, len=%u, offset=%u\n", |
2862 | " offset=%u\n", | ||
2863 | i, bio->bi_io_vec[i].bv_page, | 3104 | i, bio->bi_io_vec[i].bv_page, |
2864 | mapped_data, | ||
2865 | bio->bi_io_vec[i].bv_len, | 3105 | bio->bi_io_vec[i].bv_len, |
2866 | bio->bi_io_vec[i].bv_offset); | 3106 | bio->bi_io_vec[i].bv_offset); |
2867 | btrfsic_process_written_block(dev_state, dev_bytenr, | 3107 | } |
2868 | mapped_data, | 3108 | btrfsic_process_written_block(dev_state, dev_bytenr, |
2869 | bio->bi_io_vec[i].bv_len, | 3109 | mapped_datav, bio->bi_vcnt, |
2870 | bio, &bio_is_patched, | 3110 | bio, &bio_is_patched, |
2871 | NULL, rw); | 3111 | NULL, rw); |
3112 | while (i > 0) { | ||
3113 | i--; | ||
2872 | kunmap(bio->bi_io_vec[i].bv_page); | 3114 | kunmap(bio->bi_io_vec[i].bv_page); |
2873 | dev_bytenr += bio->bi_io_vec[i].bv_len; | ||
2874 | } | 3115 | } |
3116 | kfree(mapped_datav); | ||
2875 | } else if (NULL != dev_state && (rw & REQ_FLUSH)) { | 3117 | } else if (NULL != dev_state && (rw & REQ_FLUSH)) { |
2876 | if (dev_state->state->print_mask & | 3118 | if (dev_state->state->print_mask & |
2877 | BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) | 3119 | BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) |
2878 | printk(KERN_INFO | 3120 | printk(KERN_INFO |
2879 | "submit_bio(rw=0x%x) FLUSH, bdev=%p)\n", | 3121 | "submit_bio(rw=0x%x FLUSH, bdev=%p)\n", |
2880 | rw, bio->bi_bdev); | 3122 | rw, bio->bi_bdev); |
2881 | if (!dev_state->dummy_block_for_bio_bh_flush.is_iodone) { | 3123 | if (!dev_state->dummy_block_for_bio_bh_flush.is_iodone) { |
2882 | if ((dev_state->state->print_mask & | 3124 | if ((dev_state->state->print_mask & |
@@ -2903,6 +3145,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio) | |||
2903 | bio->bi_end_io = btrfsic_bio_end_io; | 3145 | bio->bi_end_io = btrfsic_bio_end_io; |
2904 | } | 3146 | } |
2905 | } | 3147 | } |
3148 | leave: | ||
2906 | mutex_unlock(&btrfsic_mutex); | 3149 | mutex_unlock(&btrfsic_mutex); |
2907 | 3150 | ||
2908 | submit_bio(rw, bio); | 3151 | submit_bio(rw, bio); |
@@ -2917,6 +3160,30 @@ int btrfsic_mount(struct btrfs_root *root, | |||
2917 | struct list_head *dev_head = &fs_devices->devices; | 3160 | struct list_head *dev_head = &fs_devices->devices; |
2918 | struct btrfs_device *device; | 3161 | struct btrfs_device *device; |
2919 | 3162 | ||
3163 | if (root->nodesize != root->leafsize) { | ||
3164 | printk(KERN_INFO | ||
3165 | "btrfsic: cannot handle nodesize %d != leafsize %d!\n", | ||
3166 | root->nodesize, root->leafsize); | ||
3167 | return -1; | ||
3168 | } | ||
3169 | if (root->nodesize & ((u64)PAGE_CACHE_SIZE - 1)) { | ||
3170 | printk(KERN_INFO | ||
3171 | "btrfsic: cannot handle nodesize %d not being a multiple of PAGE_CACHE_SIZE %ld!\n", | ||
3172 | root->nodesize, (unsigned long)PAGE_CACHE_SIZE); | ||
3173 | return -1; | ||
3174 | } | ||
3175 | if (root->leafsize & ((u64)PAGE_CACHE_SIZE - 1)) { | ||
3176 | printk(KERN_INFO | ||
3177 | "btrfsic: cannot handle leafsize %d not being a multiple of PAGE_CACHE_SIZE %ld!\n", | ||
3178 | root->leafsize, (unsigned long)PAGE_CACHE_SIZE); | ||
3179 | return -1; | ||
3180 | } | ||
3181 | if (root->sectorsize & ((u64)PAGE_CACHE_SIZE - 1)) { | ||
3182 | printk(KERN_INFO | ||
3183 | "btrfsic: cannot handle sectorsize %d not being a multiple of PAGE_CACHE_SIZE %ld!\n", | ||
3184 | root->sectorsize, (unsigned long)PAGE_CACHE_SIZE); | ||
3185 | return -1; | ||
3186 | } | ||
2920 | state = kzalloc(sizeof(*state), GFP_NOFS); | 3187 | state = kzalloc(sizeof(*state), GFP_NOFS); |
2921 | if (NULL == state) { | 3188 | if (NULL == state) { |
2922 | printk(KERN_INFO "btrfs check-integrity: kmalloc() failed!\n"); | 3189 | printk(KERN_INFO "btrfs check-integrity: kmalloc() failed!\n"); |
@@ -2933,6 +3200,8 @@ int btrfsic_mount(struct btrfs_root *root, | |||
2933 | state->print_mask = print_mask; | 3200 | state->print_mask = print_mask; |
2934 | state->include_extent_data = including_extent_data; | 3201 | state->include_extent_data = including_extent_data; |
2935 | state->csum_size = 0; | 3202 | state->csum_size = 0; |
3203 | state->metablock_size = root->nodesize; | ||
3204 | state->datablock_size = root->sectorsize; | ||
2936 | INIT_LIST_HEAD(&state->all_blocks_list); | 3205 | INIT_LIST_HEAD(&state->all_blocks_list); |
2937 | btrfsic_block_hashtable_init(&state->block_hashtable); | 3206 | btrfsic_block_hashtable_init(&state->block_hashtable); |
2938 | btrfsic_block_link_hashtable_init(&state->block_link_hashtable); | 3207 | btrfsic_block_link_hashtable_init(&state->block_link_hashtable); |