file-item.c 15.8 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
#define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \
28 29
			       sizeof(struct btrfs_item) * 2) / \
			       BTRFS_CRC32_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
	int csums_in_item;
87 88 89 90

	file_key.objectid = objectid;
	file_key.offset = offset;
	btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
C
Chris Mason 已提交
91
	ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
92 93
	if (ret < 0)
		goto fail;
94
	leaf = path->nodes[0];
95 96
	if (ret > 0) {
		ret = 1;
97
		if (path->slots[0] == 0)
98 99
			goto fail;
		path->slots[0]--;
100
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
101 102 103 104 105 106
		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;
107
		csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
108
		csums_in_item /= BTRFS_CRC32_SIZE;
109 110 111

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


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

	file_key.objectid = objectid;
137
	file_key.offset = offset;
C
Chris Mason 已提交
138 139 140 141
	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 已提交
142

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
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;
	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();
159 160
	if (bio->bi_size > PAGE_CACHE_SIZE * 8)
		path->reada = 2;
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

	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);
187
				item = NULL;
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
				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 +
				(item_size / BTRFS_CRC32_SIZE) *
				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;
		diff = diff * BTRFS_CRC32_SIZE;

		read_extent_buffer(path->nodes[0], &sum,
211
				   ((unsigned long)item) + diff,
212 213 214 215 216 217 218 219 220 221
				   BTRFS_CRC32_SIZE);
found:
		set_state_private(io_tree, offset, sum);
		bio_index++;
		bvec++;
	}
	btrfs_free_path(path);
	return 0;
}

C
Chris Mason 已提交
222 223 224 225 226 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
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;
}

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

302 303
	WARN_ON(bio->bi_vcnt <= 0);
	sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS);
304 305
	if (!sums)
		return -ENOMEM;
306

307
	sector_sum = sums->sums;
308
	sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset;
309 310
	sums->len = bio->bi_size;
	INIT_LIST_HEAD(&sums->list);
311 312
	ordered = btrfs_lookup_ordered_extent(inode, sums->file_offset);
	BUG_ON(!ordered);
313 314

	while(bio_index < bio->bi_vcnt) {
315
		offset = page_offset(bvec->bv_page) + bvec->bv_offset;
316 317
		if (offset >= ordered->file_offset + ordered->len ||
		    offset < ordered->file_offset) {
318 319 320 321 322 323 324 325 326 327 328
			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);
329
			sector_sum = sums->sums;
330 331 332 333 334 335 336
			sums->len = bytes_left;
			sums->file_offset = offset;
			ordered = btrfs_lookup_ordered_extent(inode,
						      sums->file_offset);
			BUG_ON(!ordered);
		}

337
		data = kmap_atomic(bvec->bv_page, KM_USER0);
338 339 340 341 342
		sector_sum->sum = ~(u32)0;
		sector_sum->sum = btrfs_csum_data(root,
						  data + bvec->bv_offset,
						  sector_sum->sum,
						  bvec->bv_len);
343
		kunmap_atomic(data, KM_USER0);
344 345 346 347
		btrfs_csum_final(sector_sum->sum,
				 (char *)&sector_sum->sum);
		sector_sum->offset = page_offset(bvec->bv_page) +
			bvec->bv_offset;
348

349
		sector_sum++;
350
		bio_index++;
351 352
		total_bytes += bvec->bv_len;
		this_sum_bytes += bvec->bv_len;
353 354
		bvec++;
	}
355
	this_sum_bytes = 0;
356 357
	btrfs_add_ordered_sum(inode, ordered, sums);
	btrfs_put_ordered_extent(ordered);
358 359 360
	return 0;
}

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

386 387
	path = btrfs_alloc_path();
	BUG_ON(!path);
388
	sector_sum = sums->sums;
389 390 391
again:
	next_offset = (u64)-1;
	found_next = 0;
392
	offset = sector_sum->offset;
C
Chris Mason 已提交
393 394 395
	file_key.objectid = objectid;
	file_key.offset = offset;
	btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
396

397
	mutex_lock(&BTRFS_I(inode)->csum_mutex);
398
	item = btrfs_lookup_csum(trans, root, path, objectid, offset, 1);
399 400
	if (!IS_ERR(item)) {
		leaf = path->nodes[0];
401
		ret = 0;
402
		goto found;
403
	}
404 405 406 407
	ret = PTR_ERR(item);
	if (ret == -EFBIG) {
		u32 item_size;
		/* we found one, but it isn't big enough yet */
408 409
		leaf = path->nodes[0];
		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
410
		if ((item_size / BTRFS_CRC32_SIZE) >= MAX_CSUM_ITEMS(root)) {
411 412 413 414
			/* already at max size, make a new one */
			goto insert;
		}
	} else {
415
		int slot = path->slots[0] + 1;
416
		/* we didn't find a csum item, insert one */
417 418 419
		nritems = btrfs_header_nritems(path->nodes[0]);
		if (path->slots[0] >= nritems - 1) {
			ret = btrfs_next_leaf(root, path);
Y
Yan 已提交
420
			if (ret == 1)
421
				found_next = 1;
Y
Yan 已提交
422
			if (ret != 0)
423
				goto insert;
Y
Yan 已提交
424
			slot = 0;
425 426 427 428 429 430 431 432 433
		}
		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;
434 435 436 437 438 439 440 441
		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);
442
	ret = btrfs_search_slot(trans, root, &file_key, path,
443
				BTRFS_CRC32_SIZE, 1);
444
	if (ret < 0)
445
		goto fail_unlock;
446
	if (ret == 0) {
C
Chris Mason 已提交
447
		BUG();
448 449 450 451 452
	}
	if (path->slots[0] == 0) {
		goto insert;
	}
	path->slots[0]--;
453 454
	leaf = path->nodes[0];
	btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
455 456 457 458 459 460 461
	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 ||
	    csum_offset >= MAX_CSUM_ITEMS(root)) {
		goto insert;
	}
462
	if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) /
463 464
	    BTRFS_CRC32_SIZE) {
		u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE;
465
		diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
C
Chris Mason 已提交
466 467
		if (diff != BTRFS_CRC32_SIZE)
			goto insert;
468
		ret = btrfs_extend_item(trans, root, path, diff);
469 470 471 472 473
		BUG_ON(ret);
		goto csum;
	}

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

509 510 511 512 513
	if (!eb_token ||
	   (unsigned long)item  + BTRFS_CRC32_SIZE >= map_start + map_len) {
		int err;

		if (eb_token)
514
			unmap_extent_buffer(leaf, eb_token, KM_USER1);
515 516 517 518
		eb_token = NULL;
		err = map_private_extent_buffer(leaf, (unsigned long)item,
						BTRFS_CRC32_SIZE,
						&eb_token, &eb_map,
519
						&map_start, &map_len, KM_USER1);
520 521 522 523 524
		if (err)
			eb_token = NULL;
	}
	if (eb_token) {
		memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)),
525
		       &sector_sum->sum, BTRFS_CRC32_SIZE);
526
	} else {
527 528
		write_extent_buffer(leaf, &sector_sum->sum,
				    (unsigned long)item, BTRFS_CRC32_SIZE);
529
	}
530

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

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

C
Chris Mason 已提交
561 562 563 564 565
int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
			struct btrfs_root *root, struct btrfs_path *path,
			u64 isize)
{
	struct btrfs_key key;
566
	struct extent_buffer *leaf = path->nodes[0];
C
Chris Mason 已提交
567 568 569 570 571 572
	int slot = path->slots[0];
	int ret;
	u32 new_item_size;
	u64 new_item_span;
	u64 blocks;

573
	btrfs_item_key_to_cpu(leaf, &key, slot);
C
Chris Mason 已提交
574 575 576
	if (isize <= key.offset)
		return 0;
	new_item_span = isize - key.offset;
577
	blocks = (new_item_span + root->sectorsize - 1) >>
C
Chris Mason 已提交
578
		root->fs_info->sb->s_blocksize_bits;
C
Chris Mason 已提交
579
	new_item_size = blocks * BTRFS_CRC32_SIZE;
580
	if (new_item_size >= btrfs_item_size_nr(leaf, slot))
C
Chris Mason 已提交
581
		return 0;
582
	ret = btrfs_truncate_item(trans, root, path, new_item_size, 1);
C
Chris Mason 已提交
583 584 585
	BUG_ON(ret);
	return ret;
}