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