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