diff options
author | Josef Bacik <jbacik@redhat.com> | 2008-12-02 07:17:45 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-12-02 07:17:45 -0500 |
commit | 607d432da0542e84ddcd358adfddac6f68500e3d (patch) | |
tree | 44425bf1fe8378022bc1b84425ca4ba9d0176566 /fs/btrfs/file-item.c | |
parent | c6e2bac1a52ffc36dd10769b594dfa3994e95f77 (diff) |
Btrfs: add support for multiple csum algorithms
This patch gives us the space we will need in order to have different csum
algorithims at some point in the future. We save the csum algorithim type
in the superblock, and use those instead of define's.
Signed-off-by: Josef Bacik <jbacik@redhat.com>
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r-- | fs/btrfs/file-item.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index f76378831407..234ed441736c 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -24,9 +24,9 @@ | |||
24 | #include "transaction.h" | 24 | #include "transaction.h" |
25 | #include "print-tree.h" | 25 | #include "print-tree.h" |
26 | 26 | ||
27 | #define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \ | 27 | #define MAX_CSUM_ITEMS(r,size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ |
28 | sizeof(struct btrfs_item) * 2) / \ | 28 | sizeof(struct btrfs_item) * 2) / \ |
29 | BTRFS_CRC32_SIZE) - 1)) | 29 | size) - 1)) |
30 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 30 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
31 | struct btrfs_root *root, | 31 | struct btrfs_root *root, |
32 | u64 objectid, u64 pos, | 32 | u64 objectid, u64 pos, |
@@ -83,6 +83,8 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
83 | struct btrfs_csum_item *item; | 83 | struct btrfs_csum_item *item; |
84 | struct extent_buffer *leaf; | 84 | struct extent_buffer *leaf; |
85 | u64 csum_offset = 0; | 85 | u64 csum_offset = 0; |
86 | u16 csum_size = | ||
87 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
86 | int csums_in_item; | 88 | int csums_in_item; |
87 | 89 | ||
88 | file_key.objectid = objectid; | 90 | file_key.objectid = objectid; |
@@ -105,7 +107,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
105 | csum_offset = (offset - found_key.offset) >> | 107 | csum_offset = (offset - found_key.offset) >> |
106 | root->fs_info->sb->s_blocksize_bits; | 108 | root->fs_info->sb->s_blocksize_bits; |
107 | csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]); | 109 | csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]); |
108 | csums_in_item /= BTRFS_CRC32_SIZE; | 110 | csums_in_item /= csum_size; |
109 | 111 | ||
110 | if (csum_offset >= csums_in_item) { | 112 | if (csum_offset >= csums_in_item) { |
111 | ret = -EFBIG; | 113 | ret = -EFBIG; |
@@ -114,7 +116,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
114 | } | 116 | } |
115 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 117 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
116 | item = (struct btrfs_csum_item *)((unsigned char *)item + | 118 | item = (struct btrfs_csum_item *)((unsigned char *)item + |
117 | csum_offset * BTRFS_CRC32_SIZE); | 119 | csum_offset * csum_size); |
118 | return item; | 120 | return item; |
119 | fail: | 121 | fail: |
120 | if (ret > 0) | 122 | if (ret > 0) |
@@ -150,6 +152,8 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
150 | u64 item_start_offset = 0; | 152 | u64 item_start_offset = 0; |
151 | u64 item_last_offset = 0; | 153 | u64 item_last_offset = 0; |
152 | u32 diff; | 154 | u32 diff; |
155 | u16 csum_size = | ||
156 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
153 | int ret; | 157 | int ret; |
154 | struct btrfs_path *path; | 158 | struct btrfs_path *path; |
155 | struct btrfs_csum_item *item = NULL; | 159 | struct btrfs_csum_item *item = NULL; |
@@ -195,7 +199,7 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
195 | item_size = btrfs_item_size_nr(path->nodes[0], | 199 | item_size = btrfs_item_size_nr(path->nodes[0], |
196 | path->slots[0]); | 200 | path->slots[0]); |
197 | item_last_offset = item_start_offset + | 201 | item_last_offset = item_start_offset + |
198 | (item_size / BTRFS_CRC32_SIZE) * | 202 | (item_size / csum_size) * |
199 | root->sectorsize; | 203 | root->sectorsize; |
200 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | 204 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], |
201 | struct btrfs_csum_item); | 205 | struct btrfs_csum_item); |
@@ -206,11 +210,11 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
206 | */ | 210 | */ |
207 | diff = offset - item_start_offset; | 211 | diff = offset - item_start_offset; |
208 | diff = diff / root->sectorsize; | 212 | diff = diff / root->sectorsize; |
209 | diff = diff * BTRFS_CRC32_SIZE; | 213 | diff = diff * csum_size; |
210 | 214 | ||
211 | read_extent_buffer(path->nodes[0], &sum, | 215 | read_extent_buffer(path->nodes[0], &sum, |
212 | ((unsigned long)item) + diff, | 216 | ((unsigned long)item) + diff, |
213 | BTRFS_CRC32_SIZE); | 217 | csum_size); |
214 | found: | 218 | found: |
215 | set_state_private(io_tree, offset, sum); | 219 | set_state_private(io_tree, offset, sum); |
216 | bio_index++; | 220 | bio_index++; |
@@ -383,6 +387,8 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, | |||
383 | char *eb_token; | 387 | char *eb_token; |
384 | unsigned long map_len; | 388 | unsigned long map_len; |
385 | unsigned long map_start; | 389 | unsigned long map_start; |
390 | u16 csum_size = | ||
391 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
386 | 392 | ||
387 | path = btrfs_alloc_path(); | 393 | path = btrfs_alloc_path(); |
388 | BUG_ON(!path); | 394 | BUG_ON(!path); |
@@ -408,7 +414,8 @@ again: | |||
408 | /* we found one, but it isn't big enough yet */ | 414 | /* we found one, but it isn't big enough yet */ |
409 | leaf = path->nodes[0]; | 415 | leaf = path->nodes[0]; |
410 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 416 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
411 | if ((item_size / BTRFS_CRC32_SIZE) >= MAX_CSUM_ITEMS(root)) { | 417 | if ((item_size / csum_size) >= |
418 | MAX_CSUM_ITEMS(root, csum_size)) { | ||
412 | /* already at max size, make a new one */ | 419 | /* already at max size, make a new one */ |
413 | goto insert; | 420 | goto insert; |
414 | } | 421 | } |
@@ -441,7 +448,7 @@ again: | |||
441 | */ | 448 | */ |
442 | btrfs_release_path(root, path); | 449 | btrfs_release_path(root, path); |
443 | ret = btrfs_search_slot(trans, root, &file_key, path, | 450 | ret = btrfs_search_slot(trans, root, &file_key, path, |
444 | BTRFS_CRC32_SIZE, 1); | 451 | csum_size, 1); |
445 | if (ret < 0) | 452 | if (ret < 0) |
446 | goto fail_unlock; | 453 | goto fail_unlock; |
447 | if (ret == 0) { | 454 | if (ret == 0) { |
@@ -457,14 +464,14 @@ again: | |||
457 | root->fs_info->sb->s_blocksize_bits; | 464 | root->fs_info->sb->s_blocksize_bits; |
458 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || | 465 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || |
459 | found_key.objectid != objectid || | 466 | found_key.objectid != objectid || |
460 | csum_offset >= MAX_CSUM_ITEMS(root)) { | 467 | csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) { |
461 | goto insert; | 468 | goto insert; |
462 | } | 469 | } |
463 | if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) / | 470 | if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) / |
464 | BTRFS_CRC32_SIZE) { | 471 | csum_size) { |
465 | u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE; | 472 | u32 diff = (csum_offset + 1) * csum_size; |
466 | diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); | 473 | diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); |
467 | if (diff != BTRFS_CRC32_SIZE) | 474 | if (diff != csum_size) |
468 | goto insert; | 475 | goto insert; |
469 | ret = btrfs_extend_item(trans, root, path, diff); | 476 | ret = btrfs_extend_item(trans, root, path, diff); |
470 | BUG_ON(ret); | 477 | BUG_ON(ret); |
@@ -479,10 +486,10 @@ insert: | |||
479 | tmp -= offset & ~((u64)root->sectorsize -1); | 486 | tmp -= offset & ~((u64)root->sectorsize -1); |
480 | tmp >>= root->fs_info->sb->s_blocksize_bits; | 487 | tmp >>= root->fs_info->sb->s_blocksize_bits; |
481 | tmp = max((u64)1, tmp); | 488 | tmp = max((u64)1, tmp); |
482 | tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root)); | 489 | tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size)); |
483 | ins_size = BTRFS_CRC32_SIZE * tmp; | 490 | ins_size = csum_size * tmp; |
484 | } else { | 491 | } else { |
485 | ins_size = BTRFS_CRC32_SIZE; | 492 | ins_size = csum_size; |
486 | } | 493 | } |
487 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, | 494 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
488 | ins_size); | 495 | ins_size); |
@@ -497,7 +504,7 @@ csum: | |||
497 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 504 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
498 | ret = 0; | 505 | ret = 0; |
499 | item = (struct btrfs_csum_item *)((unsigned char *)item + | 506 | item = (struct btrfs_csum_item *)((unsigned char *)item + |
500 | csum_offset * BTRFS_CRC32_SIZE); | 507 | csum_offset * csum_size); |
501 | found: | 508 | found: |
502 | item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 509 | item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
503 | item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + | 510 | item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + |
@@ -508,14 +515,14 @@ found: | |||
508 | next_sector: | 515 | next_sector: |
509 | 516 | ||
510 | if (!eb_token || | 517 | if (!eb_token || |
511 | (unsigned long)item + BTRFS_CRC32_SIZE >= map_start + map_len) { | 518 | (unsigned long)item + csum_size >= map_start + map_len) { |
512 | int err; | 519 | int err; |
513 | 520 | ||
514 | if (eb_token) | 521 | if (eb_token) |
515 | unmap_extent_buffer(leaf, eb_token, KM_USER1); | 522 | unmap_extent_buffer(leaf, eb_token, KM_USER1); |
516 | eb_token = NULL; | 523 | eb_token = NULL; |
517 | err = map_private_extent_buffer(leaf, (unsigned long)item, | 524 | err = map_private_extent_buffer(leaf, (unsigned long)item, |
518 | BTRFS_CRC32_SIZE, | 525 | csum_size, |
519 | &eb_token, &eb_map, | 526 | &eb_token, &eb_map, |
520 | &map_start, &map_len, KM_USER1); | 527 | &map_start, &map_len, KM_USER1); |
521 | if (err) | 528 | if (err) |
@@ -523,17 +530,17 @@ next_sector: | |||
523 | } | 530 | } |
524 | if (eb_token) { | 531 | if (eb_token) { |
525 | memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)), | 532 | memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)), |
526 | §or_sum->sum, BTRFS_CRC32_SIZE); | 533 | §or_sum->sum, csum_size); |
527 | } else { | 534 | } else { |
528 | write_extent_buffer(leaf, §or_sum->sum, | 535 | write_extent_buffer(leaf, §or_sum->sum, |
529 | (unsigned long)item, BTRFS_CRC32_SIZE); | 536 | (unsigned long)item, csum_size); |
530 | } | 537 | } |
531 | 538 | ||
532 | total_bytes += root->sectorsize; | 539 | total_bytes += root->sectorsize; |
533 | sector_sum++; | 540 | sector_sum++; |
534 | if (total_bytes < sums->len) { | 541 | if (total_bytes < sums->len) { |
535 | item = (struct btrfs_csum_item *)((char *)item + | 542 | item = (struct btrfs_csum_item *)((char *)item + |
536 | BTRFS_CRC32_SIZE); | 543 | csum_size); |
537 | if (item < item_end && offset + PAGE_CACHE_SIZE == | 544 | if (item < item_end && offset + PAGE_CACHE_SIZE == |
538 | sector_sum->offset) { | 545 | sector_sum->offset) { |
539 | offset = sector_sum->offset; | 546 | offset = sector_sum->offset; |
@@ -577,7 +584,8 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | |||
577 | new_item_span = isize - key.offset; | 584 | new_item_span = isize - key.offset; |
578 | blocks = (new_item_span + root->sectorsize - 1) >> | 585 | blocks = (new_item_span + root->sectorsize - 1) >> |
579 | root->fs_info->sb->s_blocksize_bits; | 586 | root->fs_info->sb->s_blocksize_bits; |
580 | new_item_size = blocks * BTRFS_CRC32_SIZE; | 587 | new_item_size = blocks * |
588 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
581 | if (new_item_size >= btrfs_item_size_nr(leaf, slot)) | 589 | if (new_item_size >= btrfs_item_size_nr(leaf, slot)) |
582 | return 0; | 590 | return 0; |
583 | ret = btrfs_truncate_item(trans, root, path, new_item_size, 1); | 591 | ret = btrfs_truncate_item(trans, root, path, new_item_size, 1); |