file-item.c 16.0 KB
Newer Older
C
Chris Mason 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

19 20 21
#include <linux/bio.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
C
Chris Mason 已提交
22
#include "ctree.h"
C
Chris Mason 已提交
23
#include "disk-io.h"
24
#include "transaction.h"
C
Chris Mason 已提交
25
#include "print-tree.h"
C
Chris Mason 已提交
26

27 28 29
#define MAX_CSUM_ITEMS(r,size) ((((BTRFS_LEAF_DATA_SIZE(r) - \
				   sizeof(struct btrfs_item) * 2) / \
				  size) - 1))
C
Chris Mason 已提交
30
int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
S
Sage Weil 已提交
31 32 33
			     struct btrfs_root *root,
			     u64 objectid, u64 pos,
			     u64 disk_offset, u64 disk_num_bytes,
C
Chris Mason 已提交
34 35
			     u64 num_bytes, u64 offset, u64 ram_bytes,
			     u8 compression, u8 encryption, u16 other_encoding)
36
{
C
Chris Mason 已提交
37 38 39
	int ret = 0;
	struct btrfs_file_extent_item *item;
	struct btrfs_key file_key;
40
	struct btrfs_path *path;
41
	struct extent_buffer *leaf;
C
Chris Mason 已提交
42

43 44
	path = btrfs_alloc_path();
	BUG_ON(!path);
C
Chris Mason 已提交
45
	file_key.objectid = objectid;
C
Chris Mason 已提交
46
	file_key.offset = pos;
C
Chris Mason 已提交
47 48
	btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);

49
	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
C
Chris Mason 已提交
50
				      sizeof(*item));
51 52
	if (ret < 0)
		goto out;
C
Chris Mason 已提交
53
	BUG_ON(ret);
54 55
	leaf = path->nodes[0];
	item = btrfs_item_ptr(leaf, path->slots[0],
C
Chris Mason 已提交
56
			      struct btrfs_file_extent_item);
S
Sage Weil 已提交
57
	btrfs_set_file_extent_disk_bytenr(leaf, item, disk_offset);
58
	btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes);
S
Sage Weil 已提交
59
	btrfs_set_file_extent_offset(leaf, item, offset);
60
	btrfs_set_file_extent_num_bytes(leaf, item, num_bytes);
C
Chris Mason 已提交
61
	btrfs_set_file_extent_ram_bytes(leaf, item, ram_bytes);
62 63
	btrfs_set_file_extent_generation(leaf, item, trans->transid);
	btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
C
Chris Mason 已提交
64 65 66 67
	btrfs_set_file_extent_compression(leaf, item, compression);
	btrfs_set_file_extent_encryption(leaf, item, encryption);
	btrfs_set_file_extent_other_encoding(leaf, item, other_encoding);

68
	btrfs_mark_buffer_dirty(leaf);
69
out:
70
	btrfs_free_path(path);
71
	return ret;
72
}
C
Chris Mason 已提交
73

C
Chris Mason 已提交
74 75 76 77 78
struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
					  struct btrfs_root *root,
					  struct btrfs_path *path,
					  u64 objectid, u64 offset,
					  int cow)
79 80 81 82 83
{
	int ret;
	struct btrfs_key file_key;
	struct btrfs_key found_key;
	struct btrfs_csum_item *item;
84
	struct extent_buffer *leaf;
85
	u64 csum_offset = 0;
86 87
	u16 csum_size =
		btrfs_super_csum_size(&root->fs_info->super_copy);
88
	int csums_in_item;
89 90 91 92

	file_key.objectid = objectid;
	file_key.offset = offset;
	btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
C
Chris Mason 已提交
93
	ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
94 95
	if (ret < 0)
		goto fail;
96
	leaf = path->nodes[0];
97 98
	if (ret > 0) {
		ret = 1;
99
		if (path->slots[0] == 0)
100 101
			goto fail;
		path->slots[0]--;
102
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
103 104 105 106 107 108
		if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
		    found_key.objectid != objectid) {
			goto fail;
		}
		csum_offset = (offset - found_key.offset) >>
				root->fs_info->sb->s_blocksize_bits;
109
		csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
110
		csums_in_item /= csum_size;
111 112 113

		if (csum_offset >= csums_in_item) {
			ret = -EFBIG;
114 115 116 117
			goto fail;
		}
	}
	item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
118
	item = (struct btrfs_csum_item *)((unsigned char *)item +
119
					  csum_offset * csum_size);
120 121 122
	return item;
fail:
	if (ret > 0)
C
Chris Mason 已提交
123
		ret = -ENOENT;
124 125 126 127
	return ERR_PTR(ret);
}


C
Chris Mason 已提交
128 129 130
int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root,
			     struct btrfs_path *path, u64 objectid,
C
Chris Mason 已提交
131
			     u64 offset, int mod)
C
Chris Mason 已提交
132 133 134 135 136 137 138
{
	int ret;
	struct btrfs_key file_key;
	int ins_len = mod < 0 ? -1 : 0;
	int cow = mod != 0;

	file_key.objectid = objectid;
139
	file_key.offset = offset;
C
Chris Mason 已提交
140 141 142 143
	btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
	ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
	return ret;
}
C
Chris Mason 已提交
144

145 146 147 148 149 150 151 152 153 154
int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
			  struct bio *bio)
{
	u32 sum;
	struct bio_vec *bvec = bio->bi_io_vec;
	int bio_index = 0;
	u64 offset;
	u64 item_start_offset = 0;
	u64 item_last_offset = 0;
	u32 diff;
155 156
	u16 csum_size =
		btrfs_super_csum_size(&root->fs_info->super_copy);
157 158 159 160 161 162
	int ret;
	struct btrfs_path *path;
	struct btrfs_csum_item *item = NULL;
	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;

	path = btrfs_alloc_path();
163 164
	if (bio->bi_size > PAGE_CACHE_SIZE * 8)
		path->reada = 2;
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190

	WARN_ON(bio->bi_vcnt <= 0);

	while(bio_index < bio->bi_vcnt) {
		offset = page_offset(bvec->bv_page) + bvec->bv_offset;
		ret = btrfs_find_ordered_sum(inode, offset, &sum);
		if (ret == 0)
			goto found;

		if (!item || offset < item_start_offset ||
		    offset >= item_last_offset) {
			struct btrfs_key found_key;
			u32 item_size;

			if (item)
				btrfs_release_path(root, path);
			item = btrfs_lookup_csum(NULL, root, path,
						 inode->i_ino, offset, 0);
			if (IS_ERR(item)) {
				ret = PTR_ERR(item);
				if (ret == -ENOENT || ret == -EFBIG)
					ret = 0;
				sum = 0;
				printk("no csum found for inode %lu start "
				       "%llu\n", inode->i_ino,
				       (unsigned long long)offset);
191
				item = NULL;
192
				btrfs_release_path(root, path);
193 194 195 196 197 198 199 200 201
				goto found;
			}
			btrfs_item_key_to_cpu(path->nodes[0], &found_key,
					      path->slots[0]);

			item_start_offset = found_key.offset;
			item_size = btrfs_item_size_nr(path->nodes[0],
						       path->slots[0]);
			item_last_offset = item_start_offset +
202
				(item_size / csum_size) *
203 204 205 206 207 208 209 210 211 212
				root->sectorsize;
			item = btrfs_item_ptr(path->nodes[0], path->slots[0],
					      struct btrfs_csum_item);
		}
		/*
		 * this byte range must be able to fit inside
		 * a single leaf so it will also fit inside a u32
		 */
		diff = offset - item_start_offset;
		diff = diff / root->sectorsize;
213
		diff = diff * csum_size;
214 215

		read_extent_buffer(path->nodes[0], &sum,
216
				   ((unsigned long)item) + diff,
217
				   csum_size);
218 219 220 221 222 223 224 225 226
found:
		set_state_private(io_tree, offset, sum);
		bio_index++;
		bvec++;
	}
	btrfs_free_path(path);
	return 0;
}

C
Chris Mason 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
int btrfs_csum_file_bytes(struct btrfs_root *root, struct inode *inode,
			  u64 start, unsigned long len)
{
	struct btrfs_ordered_sum *sums;
	struct btrfs_sector_sum *sector_sum;
	struct btrfs_ordered_extent *ordered;
	char *data;
	struct page *page;
	unsigned long total_bytes = 0;
	unsigned long this_sum_bytes = 0;

	sums = kzalloc(btrfs_ordered_sum_size(root, len), GFP_NOFS);
	if (!sums)
		return -ENOMEM;

	sector_sum = sums->sums;
	sums->file_offset = start;
	sums->len = len;
	INIT_LIST_HEAD(&sums->list);
	ordered = btrfs_lookup_ordered_extent(inode, sums->file_offset);
	BUG_ON(!ordered);

	while(len > 0) {
		if (start >= ordered->file_offset + ordered->len ||
		    start < ordered->file_offset) {
			sums->len = this_sum_bytes;
			this_sum_bytes = 0;
			btrfs_add_ordered_sum(inode, ordered, sums);
			btrfs_put_ordered_extent(ordered);

			sums = kzalloc(btrfs_ordered_sum_size(root, len),
				       GFP_NOFS);
			BUG_ON(!sums);
			sector_sum = sums->sums;
			sums->len = len;
			sums->file_offset = start;
			ordered = btrfs_lookup_ordered_extent(inode,
						      sums->file_offset);
			BUG_ON(!ordered);
		}

		page = find_get_page(inode->i_mapping,
				     start >> PAGE_CACHE_SHIFT);

		data = kmap_atomic(page, KM_USER0);
		sector_sum->sum = ~(u32)0;
		sector_sum->sum = btrfs_csum_data(root, data, sector_sum->sum,
						  PAGE_CACHE_SIZE);
		kunmap_atomic(data, KM_USER0);
		btrfs_csum_final(sector_sum->sum,
				 (char *)&sector_sum->sum);
		sector_sum->offset = page_offset(page);
		page_cache_release(page);

		sector_sum++;
		total_bytes += PAGE_CACHE_SIZE;
		this_sum_bytes += PAGE_CACHE_SIZE;
		start += PAGE_CACHE_SIZE;

		WARN_ON(len < PAGE_CACHE_SIZE);
		len -= PAGE_CACHE_SIZE;
	}
	btrfs_add_ordered_sum(inode, ordered, sums);
	btrfs_put_ordered_extent(ordered);
	return 0;
}

294 295
int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
		       struct bio *bio)
296
{
297 298
	struct btrfs_ordered_sum *sums;
	struct btrfs_sector_sum *sector_sum;
299
	struct btrfs_ordered_extent *ordered;
300 301 302
	char *data;
	struct bio_vec *bvec = bio->bi_io_vec;
	int bio_index = 0;
303 304 305
	unsigned long total_bytes = 0;
	unsigned long this_sum_bytes = 0;
	u64 offset;
306

307 308
	WARN_ON(bio->bi_vcnt <= 0);
	sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS);
309 310
	if (!sums)
		return -ENOMEM;
311

312
	sector_sum = sums->sums;
313
	sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset;
314 315
	sums->len = bio->bi_size;
	INIT_LIST_HEAD(&sums->list);
316 317
	ordered = btrfs_lookup_ordered_extent(inode, sums->file_offset);
	BUG_ON(!ordered);
318 319

	while(bio_index < bio->bi_vcnt) {
320
		offset = page_offset(bvec->bv_page) + bvec->bv_offset;
321 322
		if (offset >= ordered->file_offset + ordered->len ||
		    offset < ordered->file_offset) {
323 324 325 326 327 328 329 330 331 332 333
			unsigned long bytes_left;
			sums->len = this_sum_bytes;
			this_sum_bytes = 0;
			btrfs_add_ordered_sum(inode, ordered, sums);
			btrfs_put_ordered_extent(ordered);

			bytes_left = bio->bi_size - total_bytes;

			sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
				       GFP_NOFS);
			BUG_ON(!sums);
334
			sector_sum = sums->sums;
335 336 337 338 339 340 341
			sums->len = bytes_left;
			sums->file_offset = offset;
			ordered = btrfs_lookup_ordered_extent(inode,
						      sums->file_offset);
			BUG_ON(!ordered);
		}

342
		data = kmap_atomic(bvec->bv_page, KM_USER0);
343 344 345 346 347
		sector_sum->sum = ~(u32)0;
		sector_sum->sum = btrfs_csum_data(root,
						  data + bvec->bv_offset,
						  sector_sum->sum,
						  bvec->bv_len);
348
		kunmap_atomic(data, KM_USER0);
349 350 351 352
		btrfs_csum_final(sector_sum->sum,
				 (char *)&sector_sum->sum);
		sector_sum->offset = page_offset(bvec->bv_page) +
			bvec->bv_offset;
353

354
		sector_sum++;
355
		bio_index++;
356 357
		total_bytes += bvec->bv_len;
		this_sum_bytes += bvec->bv_len;
358 359
		bvec++;
	}
360
	this_sum_bytes = 0;
361 362
	btrfs_add_ordered_sum(inode, ordered, sums);
	btrfs_put_ordered_extent(ordered);
363 364 365
	return 0;
}

366 367
int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
			   struct btrfs_root *root, struct inode *inode,
368
			   struct btrfs_ordered_sum *sums)
C
Chris Mason 已提交
369
{
370 371
	u64 objectid = inode->i_ino;
	u64 offset;
C
Chris Mason 已提交
372 373
	int ret;
	struct btrfs_key file_key;
374
	struct btrfs_key found_key;
375
	u64 next_offset;
376
	u64 total_bytes = 0;
377
	int found_next;
378
	struct btrfs_path *path;
C
Chris Mason 已提交
379
	struct btrfs_csum_item *item;
380
	struct btrfs_csum_item *item_end;
381
	struct extent_buffer *leaf = NULL;
382
	u64 csum_offset;
383
	struct btrfs_sector_sum *sector_sum;
384 385
	u32 nritems;
	u32 ins_size;
386 387 388 389
	char *eb_map;
	char *eb_token;
	unsigned long map_len;
	unsigned long map_start;
390 391
	u16 csum_size =
		btrfs_super_csum_size(&root->fs_info->super_copy);
392

393 394
	path = btrfs_alloc_path();
	BUG_ON(!path);
395
	sector_sum = sums->sums;
396 397 398
again:
	next_offset = (u64)-1;
	found_next = 0;
399
	offset = sector_sum->offset;
C
Chris Mason 已提交
400 401 402
	file_key.objectid = objectid;
	file_key.offset = offset;
	btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
403

404
	mutex_lock(&BTRFS_I(inode)->csum_mutex);
405
	item = btrfs_lookup_csum(trans, root, path, objectid, offset, 1);
406 407
	if (!IS_ERR(item)) {
		leaf = path->nodes[0];
408
		ret = 0;
409
		goto found;
410
	}
411 412 413 414
	ret = PTR_ERR(item);
	if (ret == -EFBIG) {
		u32 item_size;
		/* we found one, but it isn't big enough yet */
415 416
		leaf = path->nodes[0];
		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
417 418
		if ((item_size / csum_size) >=
		    MAX_CSUM_ITEMS(root, csum_size)) {
419 420 421 422
			/* already at max size, make a new one */
			goto insert;
		}
	} else {
423
		int slot = path->slots[0] + 1;
424
		/* we didn't find a csum item, insert one */
425 426 427
		nritems = btrfs_header_nritems(path->nodes[0]);
		if (path->slots[0] >= nritems - 1) {
			ret = btrfs_next_leaf(root, path);
Y
Yan 已提交
428
			if (ret == 1)
429
				found_next = 1;
Y
Yan 已提交
430
			if (ret != 0)
431
				goto insert;
Y
Yan 已提交
432
			slot = 0;
433 434 435 436 437 438 439 440 441
		}
		btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
		if (found_key.objectid != objectid ||
		    found_key.type != BTRFS_CSUM_ITEM_KEY) {
			found_next = 1;
			goto insert;
		}
		next_offset = found_key.offset;
		found_next = 1;
442 443 444 445 446 447 448 449
		goto insert;
	}

	/*
	 * at this point, we know the tree has an item, but it isn't big
	 * enough yet to put our csum in.  Grow it
	 */
	btrfs_release_path(root, path);
450
	ret = btrfs_search_slot(trans, root, &file_key, path,
451
				csum_size, 1);
452
	if (ret < 0)
453
		goto fail_unlock;
454
	if (ret == 0) {
C
Chris Mason 已提交
455
		BUG();
456 457 458 459 460
	}
	if (path->slots[0] == 0) {
		goto insert;
	}
	path->slots[0]--;
461 462
	leaf = path->nodes[0];
	btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
463 464 465 466
	csum_offset = (offset - found_key.offset) >>
			root->fs_info->sb->s_blocksize_bits;
	if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
	    found_key.objectid != objectid ||
467
	    csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) {
468 469
		goto insert;
	}
470
	if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) /
471 472
	    csum_size) {
		u32 diff = (csum_offset + 1) * csum_size;
473
		diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
474
		if (diff != csum_size)
C
Chris Mason 已提交
475
			goto insert;
476
		ret = btrfs_extend_item(trans, root, path, diff);
477 478 479 480 481
		BUG_ON(ret);
		goto csum;
	}

insert:
482
	btrfs_release_path(root, path);
483
	csum_offset = 0;
484 485
	if (found_next) {
		u64 tmp = min((u64)i_size_read(inode), next_offset);
Y
Yan 已提交
486
		tmp -= offset & ~((u64)root->sectorsize -1);
487 488
		tmp >>= root->fs_info->sb->s_blocksize_bits;
		tmp = max((u64)1, tmp);
489 490
		tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size));
		ins_size = csum_size * tmp;
491
	} else {
492
		ins_size = csum_size;
493
	}
494
	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
495
				      ins_size);
496
	if (ret < 0)
497
		goto fail_unlock;
498 499
	if (ret != 0) {
		WARN_ON(1);
500
		goto fail_unlock;
501
	}
502
csum:
503 504
	leaf = path->nodes[0];
	item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
C
Chris Mason 已提交
505
	ret = 0;
506
	item = (struct btrfs_csum_item *)((unsigned char *)item +
507
					  csum_offset * csum_size);
C
Chris Mason 已提交
508
found:
509 510 511
	item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
	item_end = (struct btrfs_csum_item *)((unsigned char *)item_end +
				      btrfs_item_size_nr(leaf, path->slots[0]));
512
	eb_token = NULL;
513 514
	mutex_unlock(&BTRFS_I(inode)->csum_mutex);
	cond_resched();
515
next_sector:
516

517
	if (!eb_token ||
518
	   (unsigned long)item + csum_size >= map_start + map_len) {
519 520 521
		int err;

		if (eb_token)
522
			unmap_extent_buffer(leaf, eb_token, KM_USER1);
523 524
		eb_token = NULL;
		err = map_private_extent_buffer(leaf, (unsigned long)item,
525
						csum_size,
526
						&eb_token, &eb_map,
527
						&map_start, &map_len, KM_USER1);
528 529 530 531 532
		if (err)
			eb_token = NULL;
	}
	if (eb_token) {
		memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)),
533
		       &sector_sum->sum, csum_size);
534
	} else {
535
		write_extent_buffer(leaf, &sector_sum->sum,
536
				    (unsigned long)item, csum_size);
537
	}
538

539 540 541
	total_bytes += root->sectorsize;
	sector_sum++;
	if (total_bytes < sums->len) {
542
		item = (struct btrfs_csum_item *)((char *)item +
543
						  csum_size);
544
		if (item < item_end && offset + PAGE_CACHE_SIZE ==
545 546 547
		    sector_sum->offset) {
			    offset = sector_sum->offset;
			goto next_sector;
548
		}
549
	}
550
	if (eb_token) {
551
		unmap_extent_buffer(leaf, eb_token, KM_USER1);
552 553
		eb_token = NULL;
	}
554
	btrfs_mark_buffer_dirty(path->nodes[0]);
555
	cond_resched();
556
	if (total_bytes < sums->len) {
557 558 559
		btrfs_release_path(root, path);
		goto again;
	}
560
out:
561
	btrfs_free_path(path);
C
Chris Mason 已提交
562
	return ret;
563 564 565 566

fail_unlock:
	mutex_unlock(&BTRFS_I(inode)->csum_mutex);
	goto out;
C
Chris Mason 已提交
567 568
}

C
Chris Mason 已提交
569 570 571 572 573
int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
			struct btrfs_root *root, struct btrfs_path *path,
			u64 isize)
{
	struct btrfs_key key;
574
	struct extent_buffer *leaf = path->nodes[0];
C
Chris Mason 已提交
575 576 577 578 579 580
	int slot = path->slots[0];
	int ret;
	u32 new_item_size;
	u64 new_item_span;
	u64 blocks;

581
	btrfs_item_key_to_cpu(leaf, &key, slot);
C
Chris Mason 已提交
582 583 584
	if (isize <= key.offset)
		return 0;
	new_item_span = isize - key.offset;
585
	blocks = (new_item_span + root->sectorsize - 1) >>
C
Chris Mason 已提交
586
		root->fs_info->sb->s_blocksize_bits;
587 588
	new_item_size = blocks *
		btrfs_super_csum_size(&root->fs_info->super_copy);
589
	if (new_item_size >= btrfs_item_size_nr(leaf, slot))
C
Chris Mason 已提交
590
		return 0;
591
	ret = btrfs_truncate_item(trans, root, path, new_item_size, 1);
C
Chris Mason 已提交
592 593 594
	BUG_ON(ret);
	return ret;
}