file-item.c 31.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
C
Chris Mason 已提交
2 3 4 5
/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 */

6
#include <linux/bio.h>
7
#include <linux/slab.h>
8 9
#include <linux/pagemap.h>
#include <linux/highmem.h>
10
#include <linux/sched/mm.h>
11
#include <crypto/hash.h>
C
Chris Mason 已提交
12
#include "ctree.h"
C
Chris Mason 已提交
13
#include "disk-io.h"
14
#include "transaction.h"
15
#include "volumes.h"
C
Chris Mason 已提交
16
#include "print-tree.h"
17
#include "compression.h"
C
Chris Mason 已提交
18

C
Chris Mason 已提交
19 20 21
#define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \
				   sizeof(struct btrfs_item) * 2) / \
				  size) - 1))
Y
Yan Zheng 已提交
22

23
#define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
24
				       PAGE_SIZE))
25

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/**
 * @inode - the inode we want to update the disk_i_size for
 * @new_i_size - the i_size we want to set to, 0 if we use i_size
 *
 * With NO_HOLES set this simply sets the disk_is_size to whatever i_size_read()
 * returns as it is perfectly fine with a file that has holes without hole file
 * extent items.
 *
 * However without NO_HOLES we need to only return the area that is contiguous
 * from the 0 offset of the file.  Otherwise we could end up adjust i_size up
 * to an extent that has a gap in between.
 *
 * Finally new_i_size should only be set in the case of truncate where we're not
 * ready to use i_size_read() as the limiter yet.
 */
void btrfs_inode_safe_disk_i_size_write(struct inode *inode, u64 new_i_size)
{
	struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
	u64 start, end, i_size;
	int ret;

	i_size = new_i_size ?: i_size_read(inode);
	if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
		BTRFS_I(inode)->disk_i_size = i_size;
		return;
	}

	spin_lock(&BTRFS_I(inode)->lock);
	ret = find_contiguous_extent_bit(&BTRFS_I(inode)->file_extent_tree, 0,
					 &start, &end, EXTENT_DIRTY);
	if (!ret && start == 0)
		i_size = min(i_size, end + 1);
	else
		i_size = 0;
	BTRFS_I(inode)->disk_i_size = i_size;
	spin_unlock(&BTRFS_I(inode)->lock);
}

/**
 * @inode - the inode we're modifying
 * @start - the start file offset of the file extent we've inserted
 * @len - the logical length of the file extent item
 *
 * Call when we are inserting a new file extent where there was none before.
 * Does not need to call this in the case where we're replacing an existing file
 * extent, however if not sure it's fine to call this multiple times.
 *
 * The start and len must match the file extent item, so thus must be sectorsize
 * aligned.
 */
int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start,
				      u64 len)
{
	if (len == 0)
		return 0;

	ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize));

	if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
		return 0;
	return set_extent_bits(&inode->file_extent_tree, start, start + len - 1,
			       EXTENT_DIRTY);
}

/**
 * @inode - the inode we're modifying
 * @start - the start file offset of the file extent we've inserted
 * @len - the logical length of the file extent item
 *
 * Called when we drop a file extent, for example when we truncate.  Doesn't
 * need to be called for cases where we're replacing a file extent, like when
 * we've COWed a file extent.
 *
 * The start and len must match the file extent item, so thus must be sectorsize
 * aligned.
 */
int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start,
					u64 len)
{
	if (len == 0)
		return 0;

	ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize) ||
	       len == (u64)-1);

	if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
		return 0;
	return clear_extent_bit(&inode->file_extent_tree, start,
				start + len - 1, EXTENT_DIRTY, 0, 0, NULL);
}

117 118 119 120 121 122 123
static inline u32 max_ordered_sum_bytes(struct btrfs_fs_info *fs_info,
					u16 csum_size)
{
	u32 ncsums = (PAGE_SIZE - sizeof(struct btrfs_ordered_sum)) / csum_size;

	return ncsums * fs_info->sectorsize;
}
Y
Yan Zheng 已提交
124

C
Chris Mason 已提交
125
int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
S
Sage Weil 已提交
126 127 128
			     struct btrfs_root *root,
			     u64 objectid, u64 pos,
			     u64 disk_offset, u64 disk_num_bytes,
C
Chris Mason 已提交
129 130
			     u64 num_bytes, u64 offset, u64 ram_bytes,
			     u8 compression, u8 encryption, u16 other_encoding)
131
{
C
Chris Mason 已提交
132 133 134
	int ret = 0;
	struct btrfs_file_extent_item *item;
	struct btrfs_key file_key;
135
	struct btrfs_path *path;
136
	struct extent_buffer *leaf;
C
Chris Mason 已提交
137

138
	path = btrfs_alloc_path();
T
Tsutomu Itoh 已提交
139 140
	if (!path)
		return -ENOMEM;
C
Chris Mason 已提交
141
	file_key.objectid = objectid;
C
Chris Mason 已提交
142
	file_key.offset = pos;
143
	file_key.type = BTRFS_EXTENT_DATA_KEY;
C
Chris Mason 已提交
144

145
	path->leave_spinning = 1;
146
	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
C
Chris Mason 已提交
147
				      sizeof(*item));
148 149
	if (ret < 0)
		goto out;
150
	BUG_ON(ret); /* Can't happen */
151 152
	leaf = path->nodes[0];
	item = btrfs_item_ptr(leaf, path->slots[0],
C
Chris Mason 已提交
153
			      struct btrfs_file_extent_item);
S
Sage Weil 已提交
154
	btrfs_set_file_extent_disk_bytenr(leaf, item, disk_offset);
155
	btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes);
S
Sage Weil 已提交
156
	btrfs_set_file_extent_offset(leaf, item, offset);
157
	btrfs_set_file_extent_num_bytes(leaf, item, num_bytes);
C
Chris Mason 已提交
158
	btrfs_set_file_extent_ram_bytes(leaf, item, ram_bytes);
159 160
	btrfs_set_file_extent_generation(leaf, item, trans->transid);
	btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
C
Chris Mason 已提交
161 162 163 164
	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);

165
	btrfs_mark_buffer_dirty(leaf);
166
out:
167
	btrfs_free_path(path);
168
	return ret;
169
}
C
Chris Mason 已提交
170

171 172 173 174 175
static struct btrfs_csum_item *
btrfs_lookup_csum(struct btrfs_trans_handle *trans,
		  struct btrfs_root *root,
		  struct btrfs_path *path,
		  u64 bytenr, int cow)
176
{
177
	struct btrfs_fs_info *fs_info = root->fs_info;
178 179 180 181
	int ret;
	struct btrfs_key file_key;
	struct btrfs_key found_key;
	struct btrfs_csum_item *item;
182
	struct extent_buffer *leaf;
183
	u64 csum_offset = 0;
184
	u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
185
	int csums_in_item;
186

187 188
	file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
	file_key.offset = bytenr;
189
	file_key.type = BTRFS_EXTENT_CSUM_KEY;
C
Chris Mason 已提交
190
	ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
191 192
	if (ret < 0)
		goto fail;
193
	leaf = path->nodes[0];
194 195
	if (ret > 0) {
		ret = 1;
196
		if (path->slots[0] == 0)
197 198
			goto fail;
		path->slots[0]--;
199
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
200
		if (found_key.type != BTRFS_EXTENT_CSUM_KEY)
201
			goto fail;
202 203

		csum_offset = (bytenr - found_key.offset) >>
204
				fs_info->sb->s_blocksize_bits;
205
		csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
206
		csums_in_item /= csum_size;
207

208
		if (csum_offset == csums_in_item) {
209
			ret = -EFBIG;
210
			goto fail;
211 212
		} else if (csum_offset > csums_in_item) {
			goto fail;
213 214 215
		}
	}
	item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
216
	item = (struct btrfs_csum_item *)((unsigned char *)item +
217
					  csum_offset * csum_size);
218 219 220
	return item;
fail:
	if (ret > 0)
C
Chris Mason 已提交
221
		ret = -ENOENT;
222 223 224
	return ERR_PTR(ret);
}

C
Chris Mason 已提交
225 226 227
int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root,
			     struct btrfs_path *path, u64 objectid,
C
Chris Mason 已提交
228
			     u64 offset, int mod)
C
Chris Mason 已提交
229 230 231 232 233 234 235
{
	int ret;
	struct btrfs_key file_key;
	int ins_len = mod < 0 ? -1 : 0;
	int cow = mod != 0;

	file_key.objectid = objectid;
236
	file_key.offset = offset;
237
	file_key.type = BTRFS_EXTENT_DATA_KEY;
C
Chris Mason 已提交
238 239 240
	ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
	return ret;
}
C
Chris Mason 已提交
241

242 243 244
/**
 * btrfs_lookup_bio_sums - Look up checksums for a bio.
 * @inode: inode that the bio is for.
245
 * @bio: bio to look up.
246 247
 * @offset: Unless (u64)-1, look up checksums for this offset in the file.
 *          If (u64)-1, use the page offsets from the bio instead.
248 249 250 251
 * @dst: Buffer of size nblocks * btrfs_super_csum_size() used to return
 *       checksum (nblocks = bio->bi_iter.bi_size / fs_info->sectorsize). If
 *       NULL, the checksum buffer is allocated and returned in
 *       btrfs_io_bio(bio)->csum instead.
252 253 254 255
 *
 * Return: BLK_STS_RESOURCE if allocating memory fails, BLK_STS_OK otherwise.
 */
blk_status_t btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio,
256
				   u64 offset, u8 *dst)
257
{
258
	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
259 260
	struct bio_vec bvec;
	struct bvec_iter iter;
261 262 263
	struct btrfs_csum_item *item = NULL;
	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
	struct btrfs_path *path;
264
	const bool page_offsets = (offset == (u64)-1);
265
	u8 *csum;
266 267
	u64 item_start_offset = 0;
	u64 item_last_offset = 0;
268
	u64 disk_bytenr;
269
	u64 page_bytes_left;
270
	u32 diff;
271
	int nblocks;
272
	int count = 0;
273
	u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
274

275
	if (!fs_info->csum_root || (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
276 277
		return BLK_STS_OK;

278
	path = btrfs_alloc_path();
279
	if (!path)
280
		return BLK_STS_RESOURCE;
281

282
	nblocks = bio->bi_iter.bi_size >> inode->i_sb->s_blocksize_bits;
283
	if (!dst) {
284 285
		struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio);

286
		if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
287 288 289
			btrfs_bio->csum = kmalloc_array(nblocks, csum_size,
							GFP_NOFS);
			if (!btrfs_bio->csum) {
290
				btrfs_free_path(path);
291
				return BLK_STS_RESOURCE;
292 293 294 295 296 297
			}
		} else {
			btrfs_bio->csum = btrfs_bio->csum_inline;
		}
		csum = btrfs_bio->csum;
	} else {
298
		csum = dst;
299 300
	}

301
	if (bio->bi_iter.bi_size > PAGE_SIZE * 8)
302
		path->reada = READA_FORWARD;
303

304 305 306 307 308 309
	/*
	 * the free space stuff is only read when it hasn't been
	 * updated in the current transaction.  So, we can safely
	 * read from the commit root and sidestep a nasty deadlock
	 * between reading the free space cache and updating the csum tree.
	 */
310
	if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
311
		path->search_commit_root = 1;
312 313
		path->skip_locking = 1;
	}
314

315
	disk_bytenr = (u64)bio->bi_iter.bi_sector << 9;
316

317 318
	bio_for_each_segment(bvec, bio, iter) {
		page_bytes_left = bvec.bv_len;
319 320 321
		if (count)
			goto next;

322
		if (page_offsets)
323
			offset = page_offset(bvec.bv_page) + bvec.bv_offset;
324 325
		count = btrfs_find_ordered_sum(BTRFS_I(inode), offset,
					       disk_bytenr, csum, nblocks);
326
		if (count)
327 328
			goto found;

329 330
		if (!item || disk_bytenr < item_start_offset ||
		    disk_bytenr >= item_last_offset) {
331 332 333 334
			struct btrfs_key found_key;
			u32 item_size;

			if (item)
335
				btrfs_release_path(path);
336
			item = btrfs_lookup_csum(NULL, fs_info->csum_root,
337
						 path, disk_bytenr, 0);
338
			if (IS_ERR(item)) {
339
				count = 1;
340
				memset(csum, 0, csum_size);
341 342 343
				if (BTRFS_I(inode)->root->root_key.objectid ==
				    BTRFS_DATA_RELOC_TREE_OBJECTID) {
					set_extent_bits(io_tree, offset,
344
						offset + fs_info->sectorsize - 1,
345
						EXTENT_NODATASUM);
346
				} else {
347
					btrfs_info_rl(fs_info,
348
						   "no csum found for inode %llu start %llu",
349
					       btrfs_ino(BTRFS_I(inode)), offset);
350
				}
351
				item = NULL;
352
				btrfs_release_path(path);
353 354 355 356 357 358 359 360 361
				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 +
362
				(item_size / csum_size) *
363
				fs_info->sectorsize;
364 365 366 367 368 369 370
			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
		 */
371
		diff = disk_bytenr - item_start_offset;
372
		diff = diff >> fs_info->sectorsize_bits;
373
		diff = diff * csum_size;
374 375 376
		count = min_t(int, nblocks, (item_last_offset - disk_bytenr) >>
					    inode->i_sb->s_blocksize_bits);
		read_extent_buffer(path->nodes[0], csum,
377
				   ((unsigned long)item) + diff,
378
				   csum_size * count);
379
found:
380 381
		csum += count * csum_size;
		nblocks -= count;
382
next:
383 384
		while (count > 0) {
			count--;
385 386 387
			disk_bytenr += fs_info->sectorsize;
			offset += fs_info->sectorsize;
			page_bytes_left -= fs_info->sectorsize;
388 389
			if (!page_bytes_left)
				break; /* move to next bio */
390
		}
391
	}
392

393
	WARN_ON_ONCE(count);
394
	btrfs_free_path(path);
395
	return BLK_STS_OK;
396 397
}

398
int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
A
Arne Jansen 已提交
399
			     struct list_head *list, int search_commit)
400
{
401
	struct btrfs_fs_info *fs_info = root->fs_info;
402 403 404 405 406
	struct btrfs_key key;
	struct btrfs_path *path;
	struct extent_buffer *leaf;
	struct btrfs_ordered_sum *sums;
	struct btrfs_csum_item *item;
407
	LIST_HEAD(tmplist);
408 409 410 411
	unsigned long offset;
	int ret;
	size_t size;
	u64 csum_end;
412
	u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
413

414 415
	ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
	       IS_ALIGNED(end + 1, fs_info->sectorsize));
416

417
	path = btrfs_alloc_path();
418 419
	if (!path)
		return -ENOMEM;
420

A
Arne Jansen 已提交
421 422
	if (search_commit) {
		path->skip_locking = 1;
423
		path->reada = READA_FORWARD;
A
Arne Jansen 已提交
424 425 426
		path->search_commit_root = 1;
	}

427 428 429 430
	key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
	key.offset = start;
	key.type = BTRFS_EXTENT_CSUM_KEY;

Y
Yan Zheng 已提交
431
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
432 433 434 435 436 437 438 439
	if (ret < 0)
		goto fail;
	if (ret > 0 && path->slots[0] > 0) {
		leaf = path->nodes[0];
		btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1);
		if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
		    key.type == BTRFS_EXTENT_CSUM_KEY) {
			offset = (start - key.offset) >>
440
				 fs_info->sb->s_blocksize_bits;
441 442 443 444 445 446 447 448 449
			if (offset * csum_size <
			    btrfs_item_size_nr(leaf, path->slots[0] - 1))
				path->slots[0]--;
		}
	}

	while (start <= end) {
		leaf = path->nodes[0];
		if (path->slots[0] >= btrfs_header_nritems(leaf)) {
Y
Yan Zheng 已提交
450
			ret = btrfs_next_leaf(root, path);
451 452 453 454 455 456 457 458 459
			if (ret < 0)
				goto fail;
			if (ret > 0)
				break;
			leaf = path->nodes[0];
		}

		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
		if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
460 461
		    key.type != BTRFS_EXTENT_CSUM_KEY ||
		    key.offset > end)
462 463 464 465 466 467
			break;

		if (key.offset > start)
			start = key.offset;

		size = btrfs_item_size_nr(leaf, path->slots[0]);
468
		csum_end = key.offset + (size / csum_size) * fs_info->sectorsize;
469 470 471 472
		if (csum_end <= start) {
			path->slots[0]++;
			continue;
		}
473

Y
Yan Zheng 已提交
474
		csum_end = min(csum_end, end + 1);
475 476
		item = btrfs_item_ptr(path->nodes[0], path->slots[0],
				      struct btrfs_csum_item);
Y
Yan Zheng 已提交
477 478
		while (start < csum_end) {
			size = min_t(size_t, csum_end - start,
479
				     max_ordered_sum_bytes(fs_info, csum_size));
480
			sums = kzalloc(btrfs_ordered_sum_size(fs_info, size),
481
				       GFP_NOFS);
482 483 484 485
			if (!sums) {
				ret = -ENOMEM;
				goto fail;
			}
486

Y
Yan Zheng 已提交
487
			sums->bytenr = start;
488
			sums->len = (int)size;
Y
Yan Zheng 已提交
489 490

			offset = (start - key.offset) >>
491
				fs_info->sb->s_blocksize_bits;
Y
Yan Zheng 已提交
492
			offset *= csum_size;
493
			size >>= fs_info->sb->s_blocksize_bits;
Y
Yan Zheng 已提交
494

495 496 497 498 499
			read_extent_buffer(path->nodes[0],
					   sums->sums,
					   ((unsigned long)item) + offset,
					   csum_size * size);

500
			start += fs_info->sectorsize * size;
501
			list_add_tail(&sums->list, &tmplist);
Y
Yan Zheng 已提交
502
		}
503 504 505 506
		path->slots[0]++;
	}
	ret = 0;
fail:
507
	while (ret < 0 && !list_empty(&tmplist)) {
508
		sums = list_entry(tmplist.next, struct btrfs_ordered_sum, list);
509 510 511 512 513
		list_del(&sums->list);
		kfree(sums);
	}
	list_splice_tail(&tmplist, list);

514 515 516 517
	btrfs_free_path(path);
	return ret;
}

518 519 520 521 522 523 524 525 526 527
/*
 * btrfs_csum_one_bio - Calculates checksums of the data contained inside a bio
 * @inode:	 Owner of the data inside the bio
 * @bio:	 Contains the data to be checksummed
 * @file_start:  offset in file this bio begins to describe
 * @contig:	 Boolean. If true/1 means all bio vecs in this bio are
 *		 contiguous and they begin at @file_start in the file. False/0
 *		 means this bio can contains potentially discontigous bio vecs
 *		 so the logical offset of each should be calculated separately.
 */
528
blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
529
		       u64 file_start, int contig)
530
{
531
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
532
	SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
533
	struct btrfs_ordered_sum *sums;
534
	struct btrfs_ordered_extent *ordered = NULL;
535
	char *data;
536 537
	struct bvec_iter iter;
	struct bio_vec bvec;
538
	int index;
539
	int nr_sectors;
540 541
	unsigned long total_bytes = 0;
	unsigned long this_sum_bytes = 0;
542
	int i;
543
	u64 offset;
544
	unsigned nofs_flag;
545
	const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
546 547 548 549 550

	nofs_flag = memalloc_nofs_save();
	sums = kvzalloc(btrfs_ordered_sum_size(fs_info, bio->bi_iter.bi_size),
		       GFP_KERNEL);
	memalloc_nofs_restore(nofs_flag);
551 552

	if (!sums)
553
		return BLK_STS_RESOURCE;
554

555
	sums->len = bio->bi_iter.bi_size;
556
	INIT_LIST_HEAD(&sums->list);
557 558 559 560

	if (contig)
		offset = file_start;
	else
561
		offset = 0; /* shut up gcc */
562

563
	sums->bytenr = (u64)bio->bi_iter.bi_sector << 9;
564
	index = 0;
565

566 567
	shash->tfm = fs_info->csum_shash;

568
	bio_for_each_segment(bvec, bio, iter) {
569
		if (!contig)
570
			offset = page_offset(bvec.bv_page) + bvec.bv_offset;
571

572 573 574 575 576
		if (!ordered) {
			ordered = btrfs_lookup_ordered_extent(inode, offset);
			BUG_ON(!ordered); /* Logic error */
		}

577
		nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info,
578
						 bvec.bv_len + fs_info->sectorsize
579
						 - 1);
580 581

		for (i = 0; i < nr_sectors; i++) {
582 583
			if (offset >= ordered->file_offset + ordered->num_bytes ||
			    offset < ordered->file_offset) {
584 585 586 587
				unsigned long bytes_left;

				sums->len = this_sum_bytes;
				this_sum_bytes = 0;
588
				btrfs_add_ordered_sum(ordered, sums);
589 590 591 592
				btrfs_put_ordered_extent(ordered);

				bytes_left = bio->bi_iter.bi_size - total_bytes;

593 594 595 596
				nofs_flag = memalloc_nofs_save();
				sums = kvzalloc(btrfs_ordered_sum_size(fs_info,
						      bytes_left), GFP_KERNEL);
				memalloc_nofs_restore(nofs_flag);
597 598 599 600 601 602 603 604 605
				BUG_ON(!sums); /* -ENOMEM */
				sums->len = bytes_left;
				ordered = btrfs_lookup_ordered_extent(inode,
								offset);
				ASSERT(ordered); /* Logic error */
				sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9)
					+ total_bytes;
				index = 0;
			}
606

607
			data = kmap_atomic(bvec.bv_page);
608
			crypto_shash_digest(shash, data + bvec.bv_offset
609
					    + (i * fs_info->sectorsize),
610 611
					    fs_info->sectorsize,
					    sums->sums + index);
612
			kunmap_atomic(data);
613
			index += csum_size;
614 615 616
			offset += fs_info->sectorsize;
			this_sum_bytes += fs_info->sectorsize;
			total_bytes += fs_info->sectorsize;
617 618
		}

619
	}
620
	this_sum_bytes = 0;
621
	btrfs_add_ordered_sum(ordered, sums);
622
	btrfs_put_ordered_extent(ordered);
623 624 625
	return 0;
}

626 627 628 629 630 631 632 633 634 635 636
/*
 * helper function for csum removal, this expects the
 * key to describe the csum pointed to by the path, and it expects
 * the csum to overlap the range [bytenr, len]
 *
 * The csum should not be entirely contained in the range and the
 * range should not be entirely contained in the csum.
 *
 * This calls btrfs_truncate_item with the correct args based on the
 * overlap, and fixes up the key as required.
 */
637
static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
638 639 640
				       struct btrfs_path *path,
				       struct btrfs_key *key,
				       u64 bytenr, u64 len)
641 642
{
	struct extent_buffer *leaf;
643
	u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
644 645
	u64 csum_end;
	u64 end_byte = bytenr + len;
646
	u32 blocksize_bits = fs_info->sb->s_blocksize_bits;
647 648 649

	leaf = path->nodes[0];
	csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
650
	csum_end <<= fs_info->sb->s_blocksize_bits;
651 652 653 654 655 656 657 658 659 660 661
	csum_end += key->offset;

	if (key->offset < bytenr && csum_end <= end_byte) {
		/*
		 *         [ bytenr - len ]
		 *         [   ]
		 *   [csum     ]
		 *   A simple truncate off the end of the item
		 */
		u32 new_size = (bytenr - key->offset) >> blocksize_bits;
		new_size *= csum_size;
662
		btrfs_truncate_item(path, new_size, 1);
663 664 665 666 667 668 669 670 671 672 673
	} else if (key->offset >= bytenr && csum_end > end_byte &&
		   end_byte > key->offset) {
		/*
		 *         [ bytenr - len ]
		 *                 [ ]
		 *                 [csum     ]
		 * we need to truncate from the beginning of the csum
		 */
		u32 new_size = (csum_end - end_byte) >> blocksize_bits;
		new_size *= csum_size;

674
		btrfs_truncate_item(path, new_size, 0);
675 676

		key->offset = end_byte;
677
		btrfs_set_item_key_safe(fs_info, path, key);
678 679 680 681 682 683 684 685 686 687
	} else {
		BUG();
	}
}

/*
 * deletes the csum items from the csum tree for a given
 * range of bytes.
 */
int btrfs_del_csums(struct btrfs_trans_handle *trans,
688
		    struct btrfs_root *root, u64 bytenr, u64 len)
689
{
690
	struct btrfs_fs_info *fs_info = trans->fs_info;
691 692 693 694 695 696
	struct btrfs_path *path;
	struct btrfs_key key;
	u64 end_byte = bytenr + len;
	u64 csum_end;
	struct extent_buffer *leaf;
	int ret;
697 698
	u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
	int blocksize_bits = fs_info->sb->s_blocksize_bits;
699

700 701 702
	ASSERT(root == fs_info->csum_root ||
	       root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID);

703
	path = btrfs_alloc_path();
704 705
	if (!path)
		return -ENOMEM;
706

C
Chris Mason 已提交
707
	while (1) {
708 709 710 711
		key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
		key.offset = end_byte - 1;
		key.type = BTRFS_EXTENT_CSUM_KEY;

712
		path->leave_spinning = 1;
713 714 715
		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
		if (ret > 0) {
			if (path->slots[0] == 0)
716
				break;
717
			path->slots[0]--;
718
		} else if (ret < 0) {
719
			break;
720
		}
721

722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
		leaf = path->nodes[0];
		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);

		if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
		    key.type != BTRFS_EXTENT_CSUM_KEY) {
			break;
		}

		if (key.offset >= end_byte)
			break;

		csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
		csum_end <<= blocksize_bits;
		csum_end += key.offset;

		/* this csum ends before we start, we're done */
		if (csum_end <= bytenr)
			break;

		/* delete the entire item, it is inside our range */
		if (key.offset >= bytenr && csum_end <= end_byte) {
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
			int del_nr = 1;

			/*
			 * Check how many csum items preceding this one in this
			 * leaf correspond to our range and then delete them all
			 * at once.
			 */
			if (key.offset > bytenr && path->slots[0] > 0) {
				int slot = path->slots[0] - 1;

				while (slot >= 0) {
					struct btrfs_key pk;

					btrfs_item_key_to_cpu(leaf, &pk, slot);
					if (pk.offset < bytenr ||
					    pk.type != BTRFS_EXTENT_CSUM_KEY ||
					    pk.objectid !=
					    BTRFS_EXTENT_CSUM_OBJECTID)
						break;
					path->slots[0] = slot;
					del_nr++;
					key.offset = pk.offset;
					slot--;
				}
			}
			ret = btrfs_del_items(trans, root, path,
					      path->slots[0], del_nr);
770 771
			if (ret)
				goto out;
772 773
			if (key.offset == bytenr)
				break;
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
		} else if (key.offset < bytenr && csum_end > end_byte) {
			unsigned long offset;
			unsigned long shift_len;
			unsigned long item_offset;
			/*
			 *        [ bytenr - len ]
			 *     [csum                ]
			 *
			 * Our bytes are in the middle of the csum,
			 * we need to split this item and insert a new one.
			 *
			 * But we can't drop the path because the
			 * csum could change, get removed, extended etc.
			 *
			 * The trick here is the max size of a csum item leaves
			 * enough room in the tree block for a single
			 * item header.  So, we split the item in place,
			 * adding a new header pointing to the existing
			 * bytes.  Then we loop around again and we have
			 * a nicely formed csum item that we can neatly
			 * truncate.
			 */
			offset = (bytenr - key.offset) >> blocksize_bits;
			offset *= csum_size;

			shift_len = (len >> blocksize_bits) * csum_size;

			item_offset = btrfs_item_ptr_offset(leaf,
							    path->slots[0]);

804
			memzero_extent_buffer(leaf, item_offset + offset,
805 806 807 808 809 810 811 812
					     shift_len);
			key.offset = bytenr;

			/*
			 * btrfs_split_item returns -EAGAIN when the
			 * item changed size or key
			 */
			ret = btrfs_split_item(trans, root, path, &key, offset);
813
			if (ret && ret != -EAGAIN) {
814
				btrfs_abort_transaction(trans, ret);
815 816
				goto out;
			}
817 818 819

			key.offset = end_byte - 1;
		} else {
820
			truncate_one_csum(fs_info, path, &key, bytenr, len);
821 822
			if (key.offset < bytenr)
				break;
823
		}
824
		btrfs_release_path(path);
825
	}
826
	ret = 0;
827 828
out:
	btrfs_free_path(path);
829
	return ret;
830 831
}

832
int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
833
			   struct btrfs_root *root,
834
			   struct btrfs_ordered_sum *sums)
C
Chris Mason 已提交
835
{
836
	struct btrfs_fs_info *fs_info = root->fs_info;
C
Chris Mason 已提交
837
	struct btrfs_key file_key;
838
	struct btrfs_key found_key;
839
	struct btrfs_path *path;
C
Chris Mason 已提交
840
	struct btrfs_csum_item *item;
841
	struct btrfs_csum_item *item_end;
842
	struct extent_buffer *leaf = NULL;
843 844
	u64 next_offset;
	u64 total_bytes = 0;
845
	u64 csum_offset;
846
	u64 bytenr;
847 848
	u32 nritems;
	u32 ins_size;
849 850 851
	int index = 0;
	int found_next;
	int ret;
852
	u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
853

854
	path = btrfs_alloc_path();
855 856
	if (!path)
		return -ENOMEM;
857 858 859
again:
	next_offset = (u64)-1;
	found_next = 0;
860
	bytenr = sums->bytenr + total_bytes;
861
	file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
862
	file_key.offset = bytenr;
863
	file_key.type = BTRFS_EXTENT_CSUM_KEY;
864

865
	item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
866
	if (!IS_ERR(item)) {
867
		ret = 0;
868 869 870 871 872
		leaf = path->nodes[0];
		item_end = btrfs_item_ptr(leaf, path->slots[0],
					  struct btrfs_csum_item);
		item_end = (struct btrfs_csum_item *)((char *)item_end +
			   btrfs_item_size_nr(leaf, path->slots[0]));
873
		goto found;
874
	}
875
	ret = PTR_ERR(item);
876
	if (ret != -EFBIG && ret != -ENOENT)
877
		goto out;
878

879 880 881
	if (ret == -EFBIG) {
		u32 item_size;
		/* we found one, but it isn't big enough yet */
882 883
		leaf = path->nodes[0];
		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
884
		if ((item_size / csum_size) >=
885
		    MAX_CSUM_ITEMS(fs_info, csum_size)) {
886 887 888 889
			/* already at max size, make a new one */
			goto insert;
		}
	} else {
890
		int slot = path->slots[0] + 1;
891
		/* we didn't find a csum item, insert one */
892
		nritems = btrfs_header_nritems(path->nodes[0]);
893
		if (!nritems || (path->slots[0] >= nritems - 1)) {
894
			ret = btrfs_next_leaf(root, path);
895 896 897
			if (ret < 0) {
				goto out;
			} else if (ret > 0) {
898 899
				found_next = 1;
				goto insert;
900
			}
901
			slot = path->slots[0];
902 903
		}
		btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
904 905
		if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
		    found_key.type != BTRFS_EXTENT_CSUM_KEY) {
906 907 908 909 910
			found_next = 1;
			goto insert;
		}
		next_offset = found_key.offset;
		found_next = 1;
911 912 913 914
		goto insert;
	}

	/*
915 916 917 918 919 920 921 922
	 * At this point, we know the tree has a checksum item that ends at an
	 * offset matching the start of the checksum range we want to insert.
	 * We try to extend that item as much as possible and then add as many
	 * checksums to it as they fit.
	 *
	 * First check if the leaf has enough free space for at least one
	 * checksum. If it has go directly to the item extension code, otherwise
	 * release the path and do a search for insertion before the extension.
923
	 */
924 925 926 927 928 929 930
	if (btrfs_leaf_free_space(leaf) >= csum_size) {
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
		csum_offset = (bytenr - found_key.offset) >>
			fs_info->sb->s_blocksize_bits;
		goto extend_csum;
	}

931
	btrfs_release_path(path);
932
	ret = btrfs_search_slot(trans, root, &file_key, path,
933
				csum_size, 1);
934
	if (ret < 0)
935
		goto out;
936 937 938 939 940

	if (ret > 0) {
		if (path->slots[0] == 0)
			goto insert;
		path->slots[0]--;
941
	}
942

943 944
	leaf = path->nodes[0];
	btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
945
	csum_offset = (bytenr - found_key.offset) >>
946
			fs_info->sb->s_blocksize_bits;
947

948
	if (found_key.type != BTRFS_EXTENT_CSUM_KEY ||
949
	    found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
950
	    csum_offset >= MAX_CSUM_ITEMS(fs_info, csum_size)) {
951 952
		goto insert;
	}
953

954
extend_csum:
955
	if (csum_offset == btrfs_item_size_nr(leaf, path->slots[0]) /
956
	    csum_size) {
957 958 959 960
		int extend_nr;
		u64 tmp;
		u32 diff;

961
		tmp = sums->len - total_bytes;
962
		tmp >>= fs_info->sb->s_blocksize_bits;
963 964 965 966
		WARN_ON(tmp < 1);

		extend_nr = max_t(int, 1, (int)tmp);
		diff = (csum_offset + extend_nr) * csum_size;
967 968
		diff = min(diff,
			   MAX_CSUM_ITEMS(fs_info, csum_size) * csum_size);
969

970
		diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
971
		diff = min_t(u32, btrfs_leaf_free_space(leaf), diff);
972 973
		diff /= csum_size;
		diff *= csum_size;
974

975
		btrfs_extend_item(path, diff);
976
		ret = 0;
977 978 979 980
		goto csum;
	}

insert:
981
	btrfs_release_path(path);
982
	csum_offset = 0;
983
	if (found_next) {
984
		u64 tmp;
985

986
		tmp = sums->len - total_bytes;
987
		tmp >>= fs_info->sb->s_blocksize_bits;
988
		tmp = min(tmp, (next_offset - file_key.offset) >>
989
					 fs_info->sb->s_blocksize_bits);
990

991 992
		tmp = max_t(u64, 1, tmp);
		tmp = min_t(u64, tmp, MAX_CSUM_ITEMS(fs_info, csum_size));
993
		ins_size = csum_size * tmp;
994
	} else {
995
		ins_size = csum_size;
996
	}
997
	path->leave_spinning = 1;
998
	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
999
				      ins_size);
1000
	path->leave_spinning = 0;
1001
	if (ret < 0)
1002
		goto out;
1003
	if (WARN_ON(ret != 0))
1004
		goto out;
1005
	leaf = path->nodes[0];
1006
csum:
1007
	item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
1008 1009
	item_end = (struct btrfs_csum_item *)((unsigned char *)item +
				      btrfs_item_size_nr(leaf, path->slots[0]));
1010
	item = (struct btrfs_csum_item *)((unsigned char *)item +
1011
					  csum_offset * csum_size);
C
Chris Mason 已提交
1012
found:
1013
	ins_size = (u32)(sums->len - total_bytes) >>
1014
		   fs_info->sb->s_blocksize_bits;
1015 1016 1017 1018 1019 1020
	ins_size *= csum_size;
	ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item,
			      ins_size);
	write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
			    ins_size);

1021
	index += ins_size;
1022
	ins_size /= csum_size;
1023
	total_bytes += ins_size * fs_info->sectorsize;
1024

1025
	btrfs_mark_buffer_dirty(path->nodes[0]);
1026
	if (total_bytes < sums->len) {
1027
		btrfs_release_path(path);
1028
		cond_resched();
1029 1030
		goto again;
	}
1031
out:
1032
	btrfs_free_path(path);
C
Chris Mason 已提交
1033 1034
	return ret;
}
1035

1036
void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
1037 1038 1039 1040 1041
				     const struct btrfs_path *path,
				     struct btrfs_file_extent_item *fi,
				     const bool new_inline,
				     struct extent_map *em)
{
1042
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
1043
	struct btrfs_root *root = inode->root;
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
	struct extent_buffer *leaf = path->nodes[0];
	const int slot = path->slots[0];
	struct btrfs_key key;
	u64 extent_start, extent_end;
	u64 bytenr;
	u8 type = btrfs_file_extent_type(leaf, fi);
	int compress_type = btrfs_file_extent_compression(leaf, fi);

	btrfs_item_key_to_cpu(leaf, &key, slot);
	extent_start = key.offset;
1054
	extent_end = btrfs_file_extent_end(path);
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
	em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
	if (type == BTRFS_FILE_EXTENT_REG ||
	    type == BTRFS_FILE_EXTENT_PREALLOC) {
		em->start = extent_start;
		em->len = extent_end - extent_start;
		em->orig_start = extent_start -
			btrfs_file_extent_offset(leaf, fi);
		em->orig_block_len = btrfs_file_extent_disk_num_bytes(leaf, fi);
		bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
		if (bytenr == 0) {
			em->block_start = EXTENT_MAP_HOLE;
			return;
		}
		if (compress_type != BTRFS_COMPRESS_NONE) {
			set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
			em->compress_type = compress_type;
			em->block_start = bytenr;
			em->block_len = em->orig_block_len;
		} else {
			bytenr += btrfs_file_extent_offset(leaf, fi);
			em->block_start = bytenr;
			em->block_len = em->len;
			if (type == BTRFS_FILE_EXTENT_PREALLOC)
				set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
		}
	} else if (type == BTRFS_FILE_EXTENT_INLINE) {
		em->block_start = EXTENT_MAP_INLINE;
		em->start = extent_start;
		em->len = extent_end - extent_start;
		/*
		 * Initialize orig_start and block_len with the same values
		 * as in inode.c:btrfs_get_extent().
		 */
		em->orig_start = EXTENT_MAP_HOLE;
		em->block_len = (u64)-1;
		if (!new_inline && compress_type != BTRFS_COMPRESS_NONE) {
			set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
			em->compress_type = compress_type;
		}
	} else {
1095
		btrfs_err(fs_info,
1096 1097
			  "unknown file extent item type %d, inode %llu, offset %llu, "
			  "root %llu", type, btrfs_ino(inode), extent_start,
1098 1099 1100
			  root->root_key.objectid);
	}
}
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127

/*
 * Returns the end offset (non inclusive) of the file extent item the given path
 * points to. If it points to an inline extent, the returned offset is rounded
 * up to the sector size.
 */
u64 btrfs_file_extent_end(const struct btrfs_path *path)
{
	const struct extent_buffer *leaf = path->nodes[0];
	const int slot = path->slots[0];
	struct btrfs_file_extent_item *fi;
	struct btrfs_key key;
	u64 end;

	btrfs_item_key_to_cpu(leaf, &key, slot);
	ASSERT(key.type == BTRFS_EXTENT_DATA_KEY);
	fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);

	if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
		end = btrfs_file_extent_ram_bytes(leaf, fi);
		end = ALIGN(key.offset + end, leaf->fs_info->sectorsize);
	} else {
		end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
	}

	return end;
}