1 /* 2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public 14 * License along with this program; if not, write to the 15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 * Boston, MA 021110-1307, USA. 17 */ 18 19 #include <linux/bio.h> 20 #include <linux/slab.h> 21 #include <linux/pagemap.h> 22 #include <linux/highmem.h> 23 #include "ctree.h" 24 #include "disk-io.h" 25 #include "transaction.h" 26 #include "print-tree.h" 27 28 #define MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ 29 sizeof(struct btrfs_item) * 2) / \ 30 size) - 1)) 31 32 #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \ 33 sizeof(struct btrfs_ordered_sum)) / \ 34 sizeof(struct btrfs_sector_sum) * \ 35 (r)->sectorsize - (r)->sectorsize) 36 37 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, 38 struct btrfs_root *root, 39 u64 objectid, u64 pos, 40 u64 disk_offset, u64 disk_num_bytes, 41 u64 num_bytes, u64 offset, u64 ram_bytes, 42 u8 compression, u8 encryption, u16 other_encoding) 43 { 44 int ret = 0; 45 struct btrfs_file_extent_item *item; 46 struct btrfs_key file_key; 47 struct btrfs_path *path; 48 struct extent_buffer *leaf; 49 50 path = btrfs_alloc_path(); 51 BUG_ON(!path); 52 file_key.objectid = objectid; 53 file_key.offset = pos; 54 btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); 55 56 path->leave_spinning = 1; 57 ret = btrfs_insert_empty_item(trans, root, path, &file_key, 58 sizeof(*item)); 59 if (ret < 0) 60 goto out; 61 BUG_ON(ret); 62 leaf = path->nodes[0]; 63 item = btrfs_item_ptr(leaf, path->slots[0], 64 struct btrfs_file_extent_item); 65 btrfs_set_file_extent_disk_bytenr(leaf, item, disk_offset); 66 btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes); 67 btrfs_set_file_extent_offset(leaf, item, offset); 68 btrfs_set_file_extent_num_bytes(leaf, item, num_bytes); 69 btrfs_set_file_extent_ram_bytes(leaf, item, ram_bytes); 70 btrfs_set_file_extent_generation(leaf, item, trans->transid); 71 btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG); 72 btrfs_set_file_extent_compression(leaf, item, compression); 73 btrfs_set_file_extent_encryption(leaf, item, encryption); 74 btrfs_set_file_extent_other_encoding(leaf, item, other_encoding); 75 76 btrfs_mark_buffer_dirty(leaf); 77 out: 78 btrfs_free_path(path); 79 return ret; 80 } 81 82 struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, 83 struct btrfs_root *root, 84 struct btrfs_path *path, 85 u64 bytenr, int cow) 86 { 87 int ret; 88 struct btrfs_key file_key; 89 struct btrfs_key found_key; 90 struct btrfs_csum_item *item; 91 struct extent_buffer *leaf; 92 u64 csum_offset = 0; 93 u16 csum_size = 94 btrfs_super_csum_size(&root->fs_info->super_copy); 95 int csums_in_item; 96 97 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 98 file_key.offset = bytenr; 99 btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY); 100 ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow); 101 if (ret < 0) 102 goto fail; 103 leaf = path->nodes[0]; 104 if (ret > 0) { 105 ret = 1; 106 if (path->slots[0] == 0) 107 goto fail; 108 path->slots[0]--; 109 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 110 if (btrfs_key_type(&found_key) != BTRFS_EXTENT_CSUM_KEY) 111 goto fail; 112 113 csum_offset = (bytenr - found_key.offset) >> 114 root->fs_info->sb->s_blocksize_bits; 115 csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]); 116 csums_in_item /= csum_size; 117 118 if (csum_offset >= csums_in_item) { 119 ret = -EFBIG; 120 goto fail; 121 } 122 } 123 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); 124 item = (struct btrfs_csum_item *)((unsigned char *)item + 125 csum_offset * csum_size); 126 return item; 127 fail: 128 if (ret > 0) 129 ret = -ENOENT; 130 return ERR_PTR(ret); 131 } 132 133 134 int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, 135 struct btrfs_root *root, 136 struct btrfs_path *path, u64 objectid, 137 u64 offset, int mod) 138 { 139 int ret; 140 struct btrfs_key file_key; 141 int ins_len = mod < 0 ? -1 : 0; 142 int cow = mod != 0; 143 144 file_key.objectid = objectid; 145 file_key.offset = offset; 146 btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); 147 ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow); 148 return ret; 149 } 150 151 152 static int __btrfs_lookup_bio_sums(struct btrfs_root *root, 153 struct inode *inode, struct bio *bio, 154 u64 logical_offset, u32 *dst, int dio) 155 { 156 u32 sum; 157 struct bio_vec *bvec = bio->bi_io_vec; 158 int bio_index = 0; 159 u64 offset = 0; 160 u64 item_start_offset = 0; 161 u64 item_last_offset = 0; 162 u64 disk_bytenr; 163 u32 diff; 164 u16 csum_size = 165 btrfs_super_csum_size(&root->fs_info->super_copy); 166 int ret; 167 struct btrfs_path *path; 168 struct btrfs_csum_item *item = NULL; 169 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 170 171 path = btrfs_alloc_path(); 172 if (bio->bi_size > PAGE_CACHE_SIZE * 8) 173 path->reada = 2; 174 175 WARN_ON(bio->bi_vcnt <= 0); 176 177 disk_bytenr = (u64)bio->bi_sector << 9; 178 if (dio) 179 offset = logical_offset; 180 while (bio_index < bio->bi_vcnt) { 181 if (!dio) 182 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 183 ret = btrfs_find_ordered_sum(inode, offset, disk_bytenr, &sum); 184 if (ret == 0) 185 goto found; 186 187 if (!item || disk_bytenr < item_start_offset || 188 disk_bytenr >= item_last_offset) { 189 struct btrfs_key found_key; 190 u32 item_size; 191 192 if (item) 193 btrfs_release_path(root, path); 194 item = btrfs_lookup_csum(NULL, root->fs_info->csum_root, 195 path, disk_bytenr, 0); 196 if (IS_ERR(item)) { 197 ret = PTR_ERR(item); 198 if (ret == -ENOENT || ret == -EFBIG) 199 ret = 0; 200 sum = 0; 201 if (BTRFS_I(inode)->root->root_key.objectid == 202 BTRFS_DATA_RELOC_TREE_OBJECTID) { 203 set_extent_bits(io_tree, offset, 204 offset + bvec->bv_len - 1, 205 EXTENT_NODATASUM, GFP_NOFS); 206 } else { 207 printk(KERN_INFO "btrfs no csum found " 208 "for inode %lu start %llu\n", 209 inode->i_ino, 210 (unsigned long long)offset); 211 } 212 item = NULL; 213 btrfs_release_path(root, path); 214 goto found; 215 } 216 btrfs_item_key_to_cpu(path->nodes[0], &found_key, 217 path->slots[0]); 218 219 item_start_offset = found_key.offset; 220 item_size = btrfs_item_size_nr(path->nodes[0], 221 path->slots[0]); 222 item_last_offset = item_start_offset + 223 (item_size / csum_size) * 224 root->sectorsize; 225 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 226 struct btrfs_csum_item); 227 } 228 /* 229 * this byte range must be able to fit inside 230 * a single leaf so it will also fit inside a u32 231 */ 232 diff = disk_bytenr - item_start_offset; 233 diff = diff / root->sectorsize; 234 diff = diff * csum_size; 235 236 read_extent_buffer(path->nodes[0], &sum, 237 ((unsigned long)item) + diff, 238 csum_size); 239 found: 240 if (dst) 241 *dst++ = sum; 242 else 243 set_state_private(io_tree, offset, sum); 244 disk_bytenr += bvec->bv_len; 245 offset += bvec->bv_len; 246 bio_index++; 247 bvec++; 248 } 249 btrfs_free_path(path); 250 return 0; 251 } 252 253 int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, 254 struct bio *bio, u32 *dst) 255 { 256 return __btrfs_lookup_bio_sums(root, inode, bio, 0, dst, 0); 257 } 258 259 int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, 260 struct bio *bio, u64 offset, u32 *dst) 261 { 262 return __btrfs_lookup_bio_sums(root, inode, bio, offset, dst, 1); 263 } 264 265 int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, 266 struct list_head *list) 267 { 268 struct btrfs_key key; 269 struct btrfs_path *path; 270 struct extent_buffer *leaf; 271 struct btrfs_ordered_sum *sums; 272 struct btrfs_sector_sum *sector_sum; 273 struct btrfs_csum_item *item; 274 unsigned long offset; 275 int ret; 276 size_t size; 277 u64 csum_end; 278 u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy); 279 280 path = btrfs_alloc_path(); 281 BUG_ON(!path); 282 283 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 284 key.offset = start; 285 key.type = BTRFS_EXTENT_CSUM_KEY; 286 287 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 288 if (ret < 0) 289 goto fail; 290 if (ret > 0 && path->slots[0] > 0) { 291 leaf = path->nodes[0]; 292 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1); 293 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID && 294 key.type == BTRFS_EXTENT_CSUM_KEY) { 295 offset = (start - key.offset) >> 296 root->fs_info->sb->s_blocksize_bits; 297 if (offset * csum_size < 298 btrfs_item_size_nr(leaf, path->slots[0] - 1)) 299 path->slots[0]--; 300 } 301 } 302 303 while (start <= end) { 304 leaf = path->nodes[0]; 305 if (path->slots[0] >= btrfs_header_nritems(leaf)) { 306 ret = btrfs_next_leaf(root, path); 307 if (ret < 0) 308 goto fail; 309 if (ret > 0) 310 break; 311 leaf = path->nodes[0]; 312 } 313 314 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 315 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || 316 key.type != BTRFS_EXTENT_CSUM_KEY) 317 break; 318 319 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 320 if (key.offset > end) 321 break; 322 323 if (key.offset > start) 324 start = key.offset; 325 326 size = btrfs_item_size_nr(leaf, path->slots[0]); 327 csum_end = key.offset + (size / csum_size) * root->sectorsize; 328 if (csum_end <= start) { 329 path->slots[0]++; 330 continue; 331 } 332 333 csum_end = min(csum_end, end + 1); 334 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 335 struct btrfs_csum_item); 336 while (start < csum_end) { 337 size = min_t(size_t, csum_end - start, 338 MAX_ORDERED_SUM_BYTES(root)); 339 sums = kzalloc(btrfs_ordered_sum_size(root, size), 340 GFP_NOFS); 341 BUG_ON(!sums); 342 343 sector_sum = sums->sums; 344 sums->bytenr = start; 345 sums->len = size; 346 347 offset = (start - key.offset) >> 348 root->fs_info->sb->s_blocksize_bits; 349 offset *= csum_size; 350 351 while (size > 0) { 352 read_extent_buffer(path->nodes[0], 353 §or_sum->sum, 354 ((unsigned long)item) + 355 offset, csum_size); 356 sector_sum->bytenr = start; 357 358 size -= root->sectorsize; 359 start += root->sectorsize; 360 offset += csum_size; 361 sector_sum++; 362 } 363 list_add_tail(&sums->list, list); 364 } 365 path->slots[0]++; 366 } 367 ret = 0; 368 fail: 369 btrfs_free_path(path); 370 return ret; 371 } 372 373 int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, 374 struct bio *bio, u64 file_start, int contig) 375 { 376 struct btrfs_ordered_sum *sums; 377 struct btrfs_sector_sum *sector_sum; 378 struct btrfs_ordered_extent *ordered; 379 char *data; 380 struct bio_vec *bvec = bio->bi_io_vec; 381 int bio_index = 0; 382 unsigned long total_bytes = 0; 383 unsigned long this_sum_bytes = 0; 384 u64 offset; 385 u64 disk_bytenr; 386 387 WARN_ON(bio->bi_vcnt <= 0); 388 sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS); 389 if (!sums) 390 return -ENOMEM; 391 392 sector_sum = sums->sums; 393 disk_bytenr = (u64)bio->bi_sector << 9; 394 sums->len = bio->bi_size; 395 INIT_LIST_HEAD(&sums->list); 396 397 if (contig) 398 offset = file_start; 399 else 400 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 401 402 ordered = btrfs_lookup_ordered_extent(inode, offset); 403 BUG_ON(!ordered); 404 sums->bytenr = ordered->start; 405 406 while (bio_index < bio->bi_vcnt) { 407 if (!contig) 408 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 409 410 if (!contig && (offset >= ordered->file_offset + ordered->len || 411 offset < ordered->file_offset)) { 412 unsigned long bytes_left; 413 sums->len = this_sum_bytes; 414 this_sum_bytes = 0; 415 btrfs_add_ordered_sum(inode, ordered, sums); 416 btrfs_put_ordered_extent(ordered); 417 418 bytes_left = bio->bi_size - total_bytes; 419 420 sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), 421 GFP_NOFS); 422 BUG_ON(!sums); 423 sector_sum = sums->sums; 424 sums->len = bytes_left; 425 ordered = btrfs_lookup_ordered_extent(inode, offset); 426 BUG_ON(!ordered); 427 sums->bytenr = ordered->start; 428 } 429 430 data = kmap_atomic(bvec->bv_page, KM_USER0); 431 sector_sum->sum = ~(u32)0; 432 sector_sum->sum = btrfs_csum_data(root, 433 data + bvec->bv_offset, 434 sector_sum->sum, 435 bvec->bv_len); 436 kunmap_atomic(data, KM_USER0); 437 btrfs_csum_final(sector_sum->sum, 438 (char *)§or_sum->sum); 439 sector_sum->bytenr = disk_bytenr; 440 441 sector_sum++; 442 bio_index++; 443 total_bytes += bvec->bv_len; 444 this_sum_bytes += bvec->bv_len; 445 disk_bytenr += bvec->bv_len; 446 offset += bvec->bv_len; 447 bvec++; 448 } 449 this_sum_bytes = 0; 450 btrfs_add_ordered_sum(inode, ordered, sums); 451 btrfs_put_ordered_extent(ordered); 452 return 0; 453 } 454 455 /* 456 * helper function for csum removal, this expects the 457 * key to describe the csum pointed to by the path, and it expects 458 * the csum to overlap the range [bytenr, len] 459 * 460 * The csum should not be entirely contained in the range and the 461 * range should not be entirely contained in the csum. 462 * 463 * This calls btrfs_truncate_item with the correct args based on the 464 * overlap, and fixes up the key as required. 465 */ 466 static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, 467 struct btrfs_root *root, 468 struct btrfs_path *path, 469 struct btrfs_key *key, 470 u64 bytenr, u64 len) 471 { 472 struct extent_buffer *leaf; 473 u16 csum_size = 474 btrfs_super_csum_size(&root->fs_info->super_copy); 475 u64 csum_end; 476 u64 end_byte = bytenr + len; 477 u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits; 478 int ret; 479 480 leaf = path->nodes[0]; 481 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size; 482 csum_end <<= root->fs_info->sb->s_blocksize_bits; 483 csum_end += key->offset; 484 485 if (key->offset < bytenr && csum_end <= end_byte) { 486 /* 487 * [ bytenr - len ] 488 * [ ] 489 * [csum ] 490 * A simple truncate off the end of the item 491 */ 492 u32 new_size = (bytenr - key->offset) >> blocksize_bits; 493 new_size *= csum_size; 494 ret = btrfs_truncate_item(trans, root, path, new_size, 1); 495 BUG_ON(ret); 496 } else if (key->offset >= bytenr && csum_end > end_byte && 497 end_byte > key->offset) { 498 /* 499 * [ bytenr - len ] 500 * [ ] 501 * [csum ] 502 * we need to truncate from the beginning of the csum 503 */ 504 u32 new_size = (csum_end - end_byte) >> blocksize_bits; 505 new_size *= csum_size; 506 507 ret = btrfs_truncate_item(trans, root, path, new_size, 0); 508 BUG_ON(ret); 509 510 key->offset = end_byte; 511 ret = btrfs_set_item_key_safe(trans, root, path, key); 512 BUG_ON(ret); 513 } else { 514 BUG(); 515 } 516 return 0; 517 } 518 519 /* 520 * deletes the csum items from the csum tree for a given 521 * range of bytes. 522 */ 523 int btrfs_del_csums(struct btrfs_trans_handle *trans, 524 struct btrfs_root *root, u64 bytenr, u64 len) 525 { 526 struct btrfs_path *path; 527 struct btrfs_key key; 528 u64 end_byte = bytenr + len; 529 u64 csum_end; 530 struct extent_buffer *leaf; 531 int ret; 532 u16 csum_size = 533 btrfs_super_csum_size(&root->fs_info->super_copy); 534 int blocksize_bits = root->fs_info->sb->s_blocksize_bits; 535 536 root = root->fs_info->csum_root; 537 538 path = btrfs_alloc_path(); 539 if (!path) 540 return -ENOMEM; 541 542 while (1) { 543 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 544 key.offset = end_byte - 1; 545 key.type = BTRFS_EXTENT_CSUM_KEY; 546 547 path->leave_spinning = 1; 548 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 549 if (ret > 0) { 550 if (path->slots[0] == 0) 551 goto out; 552 path->slots[0]--; 553 } else if (ret < 0) { 554 goto out; 555 } 556 557 leaf = path->nodes[0]; 558 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 559 560 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || 561 key.type != BTRFS_EXTENT_CSUM_KEY) { 562 break; 563 } 564 565 if (key.offset >= end_byte) 566 break; 567 568 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size; 569 csum_end <<= blocksize_bits; 570 csum_end += key.offset; 571 572 /* this csum ends before we start, we're done */ 573 if (csum_end <= bytenr) 574 break; 575 576 /* delete the entire item, it is inside our range */ 577 if (key.offset >= bytenr && csum_end <= end_byte) { 578 ret = btrfs_del_item(trans, root, path); 579 BUG_ON(ret); 580 if (key.offset == bytenr) 581 break; 582 } else if (key.offset < bytenr && csum_end > end_byte) { 583 unsigned long offset; 584 unsigned long shift_len; 585 unsigned long item_offset; 586 /* 587 * [ bytenr - len ] 588 * [csum ] 589 * 590 * Our bytes are in the middle of the csum, 591 * we need to split this item and insert a new one. 592 * 593 * But we can't drop the path because the 594 * csum could change, get removed, extended etc. 595 * 596 * The trick here is the max size of a csum item leaves 597 * enough room in the tree block for a single 598 * item header. So, we split the item in place, 599 * adding a new header pointing to the existing 600 * bytes. Then we loop around again and we have 601 * a nicely formed csum item that we can neatly 602 * truncate. 603 */ 604 offset = (bytenr - key.offset) >> blocksize_bits; 605 offset *= csum_size; 606 607 shift_len = (len >> blocksize_bits) * csum_size; 608 609 item_offset = btrfs_item_ptr_offset(leaf, 610 path->slots[0]); 611 612 memset_extent_buffer(leaf, 0, item_offset + offset, 613 shift_len); 614 key.offset = bytenr; 615 616 /* 617 * btrfs_split_item returns -EAGAIN when the 618 * item changed size or key 619 */ 620 ret = btrfs_split_item(trans, root, path, &key, offset); 621 BUG_ON(ret && ret != -EAGAIN); 622 623 key.offset = end_byte - 1; 624 } else { 625 ret = truncate_one_csum(trans, root, path, 626 &key, bytenr, len); 627 BUG_ON(ret); 628 if (key.offset < bytenr) 629 break; 630 } 631 btrfs_release_path(root, path); 632 } 633 out: 634 btrfs_free_path(path); 635 return 0; 636 } 637 638 int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, 639 struct btrfs_root *root, 640 struct btrfs_ordered_sum *sums) 641 { 642 u64 bytenr; 643 int ret; 644 struct btrfs_key file_key; 645 struct btrfs_key found_key; 646 u64 next_offset; 647 u64 total_bytes = 0; 648 int found_next; 649 struct btrfs_path *path; 650 struct btrfs_csum_item *item; 651 struct btrfs_csum_item *item_end; 652 struct extent_buffer *leaf = NULL; 653 u64 csum_offset; 654 struct btrfs_sector_sum *sector_sum; 655 u32 nritems; 656 u32 ins_size; 657 char *eb_map; 658 char *eb_token; 659 unsigned long map_len; 660 unsigned long map_start; 661 u16 csum_size = 662 btrfs_super_csum_size(&root->fs_info->super_copy); 663 664 path = btrfs_alloc_path(); 665 BUG_ON(!path); 666 sector_sum = sums->sums; 667 again: 668 next_offset = (u64)-1; 669 found_next = 0; 670 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 671 file_key.offset = sector_sum->bytenr; 672 bytenr = sector_sum->bytenr; 673 btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY); 674 675 item = btrfs_lookup_csum(trans, root, path, sector_sum->bytenr, 1); 676 if (!IS_ERR(item)) { 677 leaf = path->nodes[0]; 678 ret = 0; 679 goto found; 680 } 681 ret = PTR_ERR(item); 682 if (ret != -EFBIG && ret != -ENOENT) 683 goto fail_unlock; 684 685 if (ret == -EFBIG) { 686 u32 item_size; 687 /* we found one, but it isn't big enough yet */ 688 leaf = path->nodes[0]; 689 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 690 if ((item_size / csum_size) >= 691 MAX_CSUM_ITEMS(root, csum_size)) { 692 /* already at max size, make a new one */ 693 goto insert; 694 } 695 } else { 696 int slot = path->slots[0] + 1; 697 /* we didn't find a csum item, insert one */ 698 nritems = btrfs_header_nritems(path->nodes[0]); 699 if (path->slots[0] >= nritems - 1) { 700 ret = btrfs_next_leaf(root, path); 701 if (ret == 1) 702 found_next = 1; 703 if (ret != 0) 704 goto insert; 705 slot = 0; 706 } 707 btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); 708 if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || 709 found_key.type != BTRFS_EXTENT_CSUM_KEY) { 710 found_next = 1; 711 goto insert; 712 } 713 next_offset = found_key.offset; 714 found_next = 1; 715 goto insert; 716 } 717 718 /* 719 * at this point, we know the tree has an item, but it isn't big 720 * enough yet to put our csum in. Grow it 721 */ 722 btrfs_release_path(root, path); 723 ret = btrfs_search_slot(trans, root, &file_key, path, 724 csum_size, 1); 725 if (ret < 0) 726 goto fail_unlock; 727 728 if (ret > 0) { 729 if (path->slots[0] == 0) 730 goto insert; 731 path->slots[0]--; 732 } 733 734 leaf = path->nodes[0]; 735 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 736 csum_offset = (bytenr - found_key.offset) >> 737 root->fs_info->sb->s_blocksize_bits; 738 739 if (btrfs_key_type(&found_key) != BTRFS_EXTENT_CSUM_KEY || 740 found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || 741 csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) { 742 goto insert; 743 } 744 745 if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) / 746 csum_size) { 747 u32 diff = (csum_offset + 1) * csum_size; 748 749 /* 750 * is the item big enough already? we dropped our lock 751 * before and need to recheck 752 */ 753 if (diff < btrfs_item_size_nr(leaf, path->slots[0])) 754 goto csum; 755 756 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); 757 if (diff != csum_size) 758 goto insert; 759 760 ret = btrfs_extend_item(trans, root, path, diff); 761 BUG_ON(ret); 762 goto csum; 763 } 764 765 insert: 766 btrfs_release_path(root, path); 767 csum_offset = 0; 768 if (found_next) { 769 u64 tmp = total_bytes + root->sectorsize; 770 u64 next_sector = sector_sum->bytenr; 771 struct btrfs_sector_sum *next = sector_sum + 1; 772 773 while (tmp < sums->len) { 774 if (next_sector + root->sectorsize != next->bytenr) 775 break; 776 tmp += root->sectorsize; 777 next_sector = next->bytenr; 778 next++; 779 } 780 tmp = min(tmp, next_offset - file_key.offset); 781 tmp >>= root->fs_info->sb->s_blocksize_bits; 782 tmp = max((u64)1, tmp); 783 tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size)); 784 ins_size = csum_size * tmp; 785 } else { 786 ins_size = csum_size; 787 } 788 path->leave_spinning = 1; 789 ret = btrfs_insert_empty_item(trans, root, path, &file_key, 790 ins_size); 791 path->leave_spinning = 0; 792 if (ret < 0) 793 goto fail_unlock; 794 if (ret != 0) { 795 WARN_ON(1); 796 goto fail_unlock; 797 } 798 csum: 799 leaf = path->nodes[0]; 800 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); 801 ret = 0; 802 item = (struct btrfs_csum_item *)((unsigned char *)item + 803 csum_offset * csum_size); 804 found: 805 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); 806 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + 807 btrfs_item_size_nr(leaf, path->slots[0])); 808 eb_token = NULL; 809 next_sector: 810 811 if (!eb_token || 812 (unsigned long)item + csum_size >= map_start + map_len) { 813 int err; 814 815 if (eb_token) 816 unmap_extent_buffer(leaf, eb_token, KM_USER1); 817 eb_token = NULL; 818 err = map_private_extent_buffer(leaf, (unsigned long)item, 819 csum_size, 820 &eb_token, &eb_map, 821 &map_start, &map_len, KM_USER1); 822 if (err) 823 eb_token = NULL; 824 } 825 if (eb_token) { 826 memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)), 827 §or_sum->sum, csum_size); 828 } else { 829 write_extent_buffer(leaf, §or_sum->sum, 830 (unsigned long)item, csum_size); 831 } 832 833 total_bytes += root->sectorsize; 834 sector_sum++; 835 if (total_bytes < sums->len) { 836 item = (struct btrfs_csum_item *)((char *)item + 837 csum_size); 838 if (item < item_end && bytenr + PAGE_CACHE_SIZE == 839 sector_sum->bytenr) { 840 bytenr = sector_sum->bytenr; 841 goto next_sector; 842 } 843 } 844 if (eb_token) { 845 unmap_extent_buffer(leaf, eb_token, KM_USER1); 846 eb_token = NULL; 847 } 848 btrfs_mark_buffer_dirty(path->nodes[0]); 849 if (total_bytes < sums->len) { 850 btrfs_release_path(root, path); 851 cond_resched(); 852 goto again; 853 } 854 out: 855 btrfs_free_path(path); 856 return ret; 857 858 fail_unlock: 859 goto out; 860 } 861