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