diff options
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); |