xref: /openbmc/linux/fs/btrfs/file-item.c (revision ecba1060)
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 
36 int 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);
76 out:
77 	btrfs_free_path(path);
78 	return ret;
79 }
80 
81 struct 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;
126 fail:
127 	if (ret > 0)
128 		ret = -ENOENT;
129 	return ERR_PTR(ret);
130 }
131 
132 
133 int 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 
151 int 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);
234 found:
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 
247 int 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 						&sector_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;
350 fail:
351 	btrfs_free_path(path);
352 	return ret;
353 }
354 
355 int 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 *)&sector_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  */
448 static 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  */
505 int 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 	}
610 out:
611 	btrfs_free_path(path);
612 	return 0;
613 }
614 
615 int 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;
644 again:
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 
739 insert:
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 	}
772 csum:
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);
778 found:
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;
783 next_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 		       &sector_sum->sum, csum_size);
802 	} else {
803 		write_extent_buffer(leaf, &sector_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 	}
828 out:
829 	btrfs_free_path(path);
830 	return ret;
831 
832 fail_unlock:
833 	goto out;
834 }
835