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