aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file-item.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@redhat.com>2008-12-02 07:17:45 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-02 07:17:45 -0500
commit607d432da0542e84ddcd358adfddac6f68500e3d (patch)
tree44425bf1fe8378022bc1b84425ca4ba9d0176566 /fs/btrfs/file-item.c
parentc6e2bac1a52ffc36dd10769b594dfa3994e95f77 (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.c56
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))
30int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, 30int 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;
119fail: 121fail:
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);
214found: 218found:
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);
501found: 508found:
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:
508next_sector: 515next_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 &sector_sum->sum, BTRFS_CRC32_SIZE); 533 &sector_sum->sum, csum_size);
527 } else { 534 } else {
528 write_extent_buffer(leaf, &sector_sum->sum, 535 write_extent_buffer(leaf, &sector_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);