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