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