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