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 "volumes.h" 27 #include "print-tree.h" 28 29 #define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \ 30 sizeof(struct btrfs_item) * 2) / \ 31 size) - 1)) 32 33 #define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \ 34 PAGE_CACHE_SIZE)) 35 36 #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \ 37 sizeof(struct btrfs_ordered_sum)) / \ 38 sizeof(u32) * (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 void btrfs_io_bio_endio_readpage(struct btrfs_io_bio *bio, int err) 157 { 158 kfree(bio->csum_allocated); 159 } 160 161 static int __btrfs_lookup_bio_sums(struct btrfs_root *root, 162 struct inode *inode, struct bio *bio, 163 u64 logical_offset, u32 *dst, int dio) 164 { 165 struct bio_vec *bvec = bio->bi_io_vec; 166 struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio); 167 struct btrfs_csum_item *item = NULL; 168 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 169 struct btrfs_path *path; 170 u8 *csum; 171 u64 offset = 0; 172 u64 item_start_offset = 0; 173 u64 item_last_offset = 0; 174 u64 disk_bytenr; 175 u32 diff; 176 int nblocks; 177 int bio_index = 0; 178 int count; 179 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 180 181 path = btrfs_alloc_path(); 182 if (!path) 183 return -ENOMEM; 184 185 nblocks = bio->bi_size >> inode->i_sb->s_blocksize_bits; 186 if (!dst) { 187 if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) { 188 btrfs_bio->csum_allocated = kmalloc(nblocks * csum_size, 189 GFP_NOFS); 190 if (!btrfs_bio->csum_allocated) { 191 btrfs_free_path(path); 192 return -ENOMEM; 193 } 194 btrfs_bio->csum = btrfs_bio->csum_allocated; 195 btrfs_bio->end_io = btrfs_io_bio_endio_readpage; 196 } else { 197 btrfs_bio->csum = btrfs_bio->csum_inline; 198 } 199 csum = btrfs_bio->csum; 200 } else { 201 csum = (u8 *)dst; 202 } 203 204 if (bio->bi_size > PAGE_CACHE_SIZE * 8) 205 path->reada = 2; 206 207 WARN_ON(bio->bi_vcnt <= 0); 208 209 /* 210 * the free space stuff is only read when it hasn't been 211 * updated in the current transaction. So, we can safely 212 * read from the commit root and sidestep a nasty deadlock 213 * between reading the free space cache and updating the csum tree. 214 */ 215 if (btrfs_is_free_space_inode(inode)) { 216 path->search_commit_root = 1; 217 path->skip_locking = 1; 218 } 219 220 disk_bytenr = (u64)bio->bi_sector << 9; 221 if (dio) 222 offset = logical_offset; 223 while (bio_index < bio->bi_vcnt) { 224 if (!dio) 225 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 226 count = btrfs_find_ordered_sum(inode, offset, disk_bytenr, 227 (u32 *)csum, nblocks); 228 if (count) 229 goto found; 230 231 if (!item || disk_bytenr < item_start_offset || 232 disk_bytenr >= item_last_offset) { 233 struct btrfs_key found_key; 234 u32 item_size; 235 236 if (item) 237 btrfs_release_path(path); 238 item = btrfs_lookup_csum(NULL, root->fs_info->csum_root, 239 path, disk_bytenr, 0); 240 if (IS_ERR(item)) { 241 count = 1; 242 memset(csum, 0, csum_size); 243 if (BTRFS_I(inode)->root->root_key.objectid == 244 BTRFS_DATA_RELOC_TREE_OBJECTID) { 245 set_extent_bits(io_tree, offset, 246 offset + bvec->bv_len - 1, 247 EXTENT_NODATASUM, GFP_NOFS); 248 } else { 249 printk(KERN_INFO "btrfs no csum found " 250 "for inode %llu start %llu\n", 251 (unsigned long long) 252 btrfs_ino(inode), 253 (unsigned long long)offset); 254 } 255 item = NULL; 256 btrfs_release_path(path); 257 goto found; 258 } 259 btrfs_item_key_to_cpu(path->nodes[0], &found_key, 260 path->slots[0]); 261 262 item_start_offset = found_key.offset; 263 item_size = btrfs_item_size_nr(path->nodes[0], 264 path->slots[0]); 265 item_last_offset = item_start_offset + 266 (item_size / csum_size) * 267 root->sectorsize; 268 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 269 struct btrfs_csum_item); 270 } 271 /* 272 * this byte range must be able to fit inside 273 * a single leaf so it will also fit inside a u32 274 */ 275 diff = disk_bytenr - item_start_offset; 276 diff = diff / root->sectorsize; 277 diff = diff * csum_size; 278 count = min_t(int, nblocks, (item_last_offset - disk_bytenr) >> 279 inode->i_sb->s_blocksize_bits); 280 read_extent_buffer(path->nodes[0], csum, 281 ((unsigned long)item) + diff, 282 csum_size * count); 283 found: 284 csum += count * csum_size; 285 nblocks -= count; 286 while (count--) { 287 disk_bytenr += bvec->bv_len; 288 offset += bvec->bv_len; 289 bio_index++; 290 bvec++; 291 } 292 } 293 btrfs_free_path(path); 294 return 0; 295 } 296 297 int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, 298 struct bio *bio, u32 *dst) 299 { 300 return __btrfs_lookup_bio_sums(root, inode, bio, 0, dst, 0); 301 } 302 303 int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, 304 struct btrfs_dio_private *dip, struct bio *bio, 305 u64 offset) 306 { 307 int len = (bio->bi_sector << 9) - dip->disk_bytenr; 308 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 309 int ret; 310 311 len >>= inode->i_sb->s_blocksize_bits; 312 len *= csum_size; 313 314 ret = __btrfs_lookup_bio_sums(root, inode, bio, offset, 315 (u32 *)(dip->csum + len), 1); 316 return ret; 317 } 318 319 int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, 320 struct list_head *list, int search_commit) 321 { 322 struct btrfs_key key; 323 struct btrfs_path *path; 324 struct extent_buffer *leaf; 325 struct btrfs_ordered_sum *sums; 326 struct btrfs_csum_item *item; 327 LIST_HEAD(tmplist); 328 unsigned long offset; 329 int ret; 330 size_t size; 331 u64 csum_end; 332 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 333 334 path = btrfs_alloc_path(); 335 if (!path) 336 return -ENOMEM; 337 338 if (search_commit) { 339 path->skip_locking = 1; 340 path->reada = 2; 341 path->search_commit_root = 1; 342 } 343 344 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 345 key.offset = start; 346 key.type = BTRFS_EXTENT_CSUM_KEY; 347 348 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 349 if (ret < 0) 350 goto fail; 351 if (ret > 0 && path->slots[0] > 0) { 352 leaf = path->nodes[0]; 353 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1); 354 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID && 355 key.type == BTRFS_EXTENT_CSUM_KEY) { 356 offset = (start - key.offset) >> 357 root->fs_info->sb->s_blocksize_bits; 358 if (offset * csum_size < 359 btrfs_item_size_nr(leaf, path->slots[0] - 1)) 360 path->slots[0]--; 361 } 362 } 363 364 while (start <= end) { 365 leaf = path->nodes[0]; 366 if (path->slots[0] >= btrfs_header_nritems(leaf)) { 367 ret = btrfs_next_leaf(root, path); 368 if (ret < 0) 369 goto fail; 370 if (ret > 0) 371 break; 372 leaf = path->nodes[0]; 373 } 374 375 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 376 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || 377 key.type != BTRFS_EXTENT_CSUM_KEY || 378 key.offset > end) 379 break; 380 381 if (key.offset > start) 382 start = key.offset; 383 384 size = btrfs_item_size_nr(leaf, path->slots[0]); 385 csum_end = key.offset + (size / csum_size) * root->sectorsize; 386 if (csum_end <= start) { 387 path->slots[0]++; 388 continue; 389 } 390 391 csum_end = min(csum_end, end + 1); 392 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 393 struct btrfs_csum_item); 394 while (start < csum_end) { 395 size = min_t(size_t, csum_end - start, 396 MAX_ORDERED_SUM_BYTES(root)); 397 sums = kzalloc(btrfs_ordered_sum_size(root, size), 398 GFP_NOFS); 399 if (!sums) { 400 ret = -ENOMEM; 401 goto fail; 402 } 403 404 sums->bytenr = start; 405 sums->len = (int)size; 406 407 offset = (start - key.offset) >> 408 root->fs_info->sb->s_blocksize_bits; 409 offset *= csum_size; 410 size >>= root->fs_info->sb->s_blocksize_bits; 411 412 read_extent_buffer(path->nodes[0], 413 sums->sums, 414 ((unsigned long)item) + offset, 415 csum_size * size); 416 417 start += root->sectorsize * size; 418 list_add_tail(&sums->list, &tmplist); 419 } 420 path->slots[0]++; 421 } 422 ret = 0; 423 fail: 424 while (ret < 0 && !list_empty(&tmplist)) { 425 sums = list_entry(&tmplist, struct btrfs_ordered_sum, list); 426 list_del(&sums->list); 427 kfree(sums); 428 } 429 list_splice_tail(&tmplist, list); 430 431 btrfs_free_path(path); 432 return ret; 433 } 434 435 int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, 436 struct bio *bio, u64 file_start, int contig) 437 { 438 struct btrfs_ordered_sum *sums; 439 struct btrfs_ordered_extent *ordered; 440 char *data; 441 struct bio_vec *bvec = bio->bi_io_vec; 442 int bio_index = 0; 443 int index; 444 unsigned long total_bytes = 0; 445 unsigned long this_sum_bytes = 0; 446 u64 offset; 447 448 WARN_ON(bio->bi_vcnt <= 0); 449 sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS); 450 if (!sums) 451 return -ENOMEM; 452 453 sums->len = bio->bi_size; 454 INIT_LIST_HEAD(&sums->list); 455 456 if (contig) 457 offset = file_start; 458 else 459 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 460 461 ordered = btrfs_lookup_ordered_extent(inode, offset); 462 BUG_ON(!ordered); /* Logic error */ 463 sums->bytenr = (u64)bio->bi_sector << 9; 464 index = 0; 465 466 while (bio_index < bio->bi_vcnt) { 467 if (!contig) 468 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 469 470 if (offset >= ordered->file_offset + ordered->len || 471 offset < ordered->file_offset) { 472 unsigned long bytes_left; 473 sums->len = this_sum_bytes; 474 this_sum_bytes = 0; 475 btrfs_add_ordered_sum(inode, ordered, sums); 476 btrfs_put_ordered_extent(ordered); 477 478 bytes_left = bio->bi_size - total_bytes; 479 480 sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), 481 GFP_NOFS); 482 BUG_ON(!sums); /* -ENOMEM */ 483 sums->len = bytes_left; 484 ordered = btrfs_lookup_ordered_extent(inode, offset); 485 BUG_ON(!ordered); /* Logic error */ 486 sums->bytenr = ((u64)bio->bi_sector << 9) + 487 total_bytes; 488 index = 0; 489 } 490 491 data = kmap_atomic(bvec->bv_page); 492 sums->sums[index] = ~(u32)0; 493 sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset, 494 sums->sums[index], 495 bvec->bv_len); 496 kunmap_atomic(data); 497 btrfs_csum_final(sums->sums[index], 498 (char *)(sums->sums + index)); 499 500 bio_index++; 501 index++; 502 total_bytes += bvec->bv_len; 503 this_sum_bytes += bvec->bv_len; 504 offset += bvec->bv_len; 505 bvec++; 506 } 507 this_sum_bytes = 0; 508 btrfs_add_ordered_sum(inode, ordered, sums); 509 btrfs_put_ordered_extent(ordered); 510 return 0; 511 } 512 513 /* 514 * helper function for csum removal, this expects the 515 * key to describe the csum pointed to by the path, and it expects 516 * the csum to overlap the range [bytenr, len] 517 * 518 * The csum should not be entirely contained in the range and the 519 * range should not be entirely contained in the csum. 520 * 521 * This calls btrfs_truncate_item with the correct args based on the 522 * overlap, and fixes up the key as required. 523 */ 524 static noinline void truncate_one_csum(struct btrfs_root *root, 525 struct btrfs_path *path, 526 struct btrfs_key *key, 527 u64 bytenr, u64 len) 528 { 529 struct extent_buffer *leaf; 530 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 531 u64 csum_end; 532 u64 end_byte = bytenr + len; 533 u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits; 534 535 leaf = path->nodes[0]; 536 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size; 537 csum_end <<= root->fs_info->sb->s_blocksize_bits; 538 csum_end += key->offset; 539 540 if (key->offset < bytenr && csum_end <= end_byte) { 541 /* 542 * [ bytenr - len ] 543 * [ ] 544 * [csum ] 545 * A simple truncate off the end of the item 546 */ 547 u32 new_size = (bytenr - key->offset) >> blocksize_bits; 548 new_size *= csum_size; 549 btrfs_truncate_item(root, path, new_size, 1); 550 } else if (key->offset >= bytenr && csum_end > end_byte && 551 end_byte > key->offset) { 552 /* 553 * [ bytenr - len ] 554 * [ ] 555 * [csum ] 556 * we need to truncate from the beginning of the csum 557 */ 558 u32 new_size = (csum_end - end_byte) >> blocksize_bits; 559 new_size *= csum_size; 560 561 btrfs_truncate_item(root, path, new_size, 0); 562 563 key->offset = end_byte; 564 btrfs_set_item_key_safe(root, path, key); 565 } else { 566 BUG(); 567 } 568 } 569 570 /* 571 * deletes the csum items from the csum tree for a given 572 * range of bytes. 573 */ 574 int btrfs_del_csums(struct btrfs_trans_handle *trans, 575 struct btrfs_root *root, u64 bytenr, u64 len) 576 { 577 struct btrfs_path *path; 578 struct btrfs_key key; 579 u64 end_byte = bytenr + len; 580 u64 csum_end; 581 struct extent_buffer *leaf; 582 int ret; 583 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 584 int blocksize_bits = root->fs_info->sb->s_blocksize_bits; 585 586 root = root->fs_info->csum_root; 587 588 path = btrfs_alloc_path(); 589 if (!path) 590 return -ENOMEM; 591 592 while (1) { 593 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 594 key.offset = end_byte - 1; 595 key.type = BTRFS_EXTENT_CSUM_KEY; 596 597 path->leave_spinning = 1; 598 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 599 if (ret > 0) { 600 if (path->slots[0] == 0) 601 break; 602 path->slots[0]--; 603 } else if (ret < 0) { 604 break; 605 } 606 607 leaf = path->nodes[0]; 608 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 609 610 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || 611 key.type != BTRFS_EXTENT_CSUM_KEY) { 612 break; 613 } 614 615 if (key.offset >= end_byte) 616 break; 617 618 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size; 619 csum_end <<= blocksize_bits; 620 csum_end += key.offset; 621 622 /* this csum ends before we start, we're done */ 623 if (csum_end <= bytenr) 624 break; 625 626 /* delete the entire item, it is inside our range */ 627 if (key.offset >= bytenr && csum_end <= end_byte) { 628 ret = btrfs_del_item(trans, root, path); 629 if (ret) 630 goto out; 631 if (key.offset == bytenr) 632 break; 633 } else if (key.offset < bytenr && csum_end > end_byte) { 634 unsigned long offset; 635 unsigned long shift_len; 636 unsigned long item_offset; 637 /* 638 * [ bytenr - len ] 639 * [csum ] 640 * 641 * Our bytes are in the middle of the csum, 642 * we need to split this item and insert a new one. 643 * 644 * But we can't drop the path because the 645 * csum could change, get removed, extended etc. 646 * 647 * The trick here is the max size of a csum item leaves 648 * enough room in the tree block for a single 649 * item header. So, we split the item in place, 650 * adding a new header pointing to the existing 651 * bytes. Then we loop around again and we have 652 * a nicely formed csum item that we can neatly 653 * truncate. 654 */ 655 offset = (bytenr - key.offset) >> blocksize_bits; 656 offset *= csum_size; 657 658 shift_len = (len >> blocksize_bits) * csum_size; 659 660 item_offset = btrfs_item_ptr_offset(leaf, 661 path->slots[0]); 662 663 memset_extent_buffer(leaf, 0, item_offset + offset, 664 shift_len); 665 key.offset = bytenr; 666 667 /* 668 * btrfs_split_item returns -EAGAIN when the 669 * item changed size or key 670 */ 671 ret = btrfs_split_item(trans, root, path, &key, offset); 672 if (ret && ret != -EAGAIN) { 673 btrfs_abort_transaction(trans, root, ret); 674 goto out; 675 } 676 677 key.offset = end_byte - 1; 678 } else { 679 truncate_one_csum(root, path, &key, bytenr, len); 680 if (key.offset < bytenr) 681 break; 682 } 683 btrfs_release_path(path); 684 } 685 ret = 0; 686 out: 687 btrfs_free_path(path); 688 return ret; 689 } 690 691 int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, 692 struct btrfs_root *root, 693 struct btrfs_ordered_sum *sums) 694 { 695 struct btrfs_key file_key; 696 struct btrfs_key found_key; 697 struct btrfs_path *path; 698 struct btrfs_csum_item *item; 699 struct btrfs_csum_item *item_end; 700 struct extent_buffer *leaf = NULL; 701 u64 next_offset; 702 u64 total_bytes = 0; 703 u64 csum_offset; 704 u64 bytenr; 705 u32 nritems; 706 u32 ins_size; 707 int index = 0; 708 int found_next; 709 int ret; 710 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 711 712 path = btrfs_alloc_path(); 713 if (!path) 714 return -ENOMEM; 715 again: 716 next_offset = (u64)-1; 717 found_next = 0; 718 bytenr = sums->bytenr + total_bytes; 719 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 720 file_key.offset = bytenr; 721 btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY); 722 723 item = btrfs_lookup_csum(trans, root, path, bytenr, 1); 724 if (!IS_ERR(item)) { 725 ret = 0; 726 leaf = path->nodes[0]; 727 item_end = btrfs_item_ptr(leaf, path->slots[0], 728 struct btrfs_csum_item); 729 item_end = (struct btrfs_csum_item *)((char *)item_end + 730 btrfs_item_size_nr(leaf, path->slots[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 = sums->len - total_bytes; 811 tmp >>= root->fs_info->sb->s_blocksize_bits; 812 WARN_ON(tmp < 1); 813 814 extend_nr = max_t(int, 1, (int)tmp); 815 diff = (csum_offset + extend_nr) * csum_size; 816 diff = min(diff, MAX_CSUM_ITEMS(root, csum_size) * csum_size); 817 818 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); 819 diff = min(free_space, diff); 820 diff /= csum_size; 821 diff *= csum_size; 822 823 btrfs_extend_item(root, path, diff); 824 ret = 0; 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 = sums->len - total_bytes; 835 tmp >>= root->fs_info->sb->s_blocksize_bits; 836 tmp = min(tmp, (next_offset - file_key.offset) >> 837 root->fs_info->sb->s_blocksize_bits); 838 839 tmp = max((u64)1, tmp); 840 tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size)); 841 ins_size = csum_size * tmp; 842 } else { 843 ins_size = csum_size; 844 } 845 path->leave_spinning = 1; 846 ret = btrfs_insert_empty_item(trans, root, path, &file_key, 847 ins_size); 848 path->leave_spinning = 0; 849 if (ret < 0) 850 goto fail_unlock; 851 if (ret != 0) { 852 WARN_ON(1); 853 goto fail_unlock; 854 } 855 leaf = path->nodes[0]; 856 csum: 857 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); 858 item_end = (struct btrfs_csum_item *)((unsigned char *)item + 859 btrfs_item_size_nr(leaf, path->slots[0])); 860 item = (struct btrfs_csum_item *)((unsigned char *)item + 861 csum_offset * csum_size); 862 found: 863 ins_size = (u32)(sums->len - total_bytes) >> 864 root->fs_info->sb->s_blocksize_bits; 865 ins_size *= csum_size; 866 ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item, 867 ins_size); 868 write_extent_buffer(leaf, sums->sums + index, (unsigned long)item, 869 ins_size); 870 871 ins_size /= csum_size; 872 total_bytes += ins_size * root->sectorsize; 873 index += ins_size; 874 875 btrfs_mark_buffer_dirty(path->nodes[0]); 876 if (total_bytes < sums->len) { 877 btrfs_release_path(path); 878 cond_resched(); 879 goto again; 880 } 881 out: 882 btrfs_free_path(path); 883 return ret; 884 885 fail_unlock: 886 goto out; 887 } 888