162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/init.h>
462306a36Sopenharmony_ci#include <linux/fs.h>
562306a36Sopenharmony_ci#include <linux/slab.h>
662306a36Sopenharmony_ci#include <linux/rwsem.h>
762306a36Sopenharmony_ci#include <linux/xattr.h>
862306a36Sopenharmony_ci#include <linux/security.h>
962306a36Sopenharmony_ci#include <linux/posix_acl_xattr.h>
1062306a36Sopenharmony_ci#include <linux/iversion.h>
1162306a36Sopenharmony_ci#include <linux/fsverity.h>
1262306a36Sopenharmony_ci#include <linux/sched/mm.h>
1362306a36Sopenharmony_ci#include "messages.h"
1462306a36Sopenharmony_ci#include "ctree.h"
1562306a36Sopenharmony_ci#include "btrfs_inode.h"
1662306a36Sopenharmony_ci#include "transaction.h"
1762306a36Sopenharmony_ci#include "disk-io.h"
1862306a36Sopenharmony_ci#include "locking.h"
1962306a36Sopenharmony_ci#include "fs.h"
2062306a36Sopenharmony_ci#include "accessors.h"
2162306a36Sopenharmony_ci#include "ioctl.h"
2262306a36Sopenharmony_ci#include "verity.h"
2362306a36Sopenharmony_ci#include "orphan.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/*
2662306a36Sopenharmony_ci * Implementation of the interface defined in struct fsverity_operations.
2762306a36Sopenharmony_ci *
2862306a36Sopenharmony_ci * The main question is how and where to store the verity descriptor and the
2962306a36Sopenharmony_ci * Merkle tree. We store both in dedicated btree items in the filesystem tree,
3062306a36Sopenharmony_ci * together with the rest of the inode metadata. This means we'll need to do
3162306a36Sopenharmony_ci * extra work to encrypt them once encryption is supported in btrfs, but btrfs
3262306a36Sopenharmony_ci * has a lot of careful code around i_size and it seems better to make a new key
3362306a36Sopenharmony_ci * type than try and adjust all of our expectations for i_size.
3462306a36Sopenharmony_ci *
3562306a36Sopenharmony_ci * Note that this differs from the implementation in ext4 and f2fs, where
3662306a36Sopenharmony_ci * this data is stored as if it were in the file, but past EOF. However, btrfs
3762306a36Sopenharmony_ci * does not have a widespread mechanism for caching opaque metadata pages, so we
3862306a36Sopenharmony_ci * do pretend that the Merkle tree pages themselves are past EOF for the
3962306a36Sopenharmony_ci * purposes of caching them (as opposed to creating a virtual inode).
4062306a36Sopenharmony_ci *
4162306a36Sopenharmony_ci * fs verity items are stored under two different key types on disk.
4262306a36Sopenharmony_ci * The descriptor items:
4362306a36Sopenharmony_ci * [ inode objectid, BTRFS_VERITY_DESC_ITEM_KEY, offset ]
4462306a36Sopenharmony_ci *
4562306a36Sopenharmony_ci * At offset 0, we store a btrfs_verity_descriptor_item which tracks the
4662306a36Sopenharmony_ci * size of the descriptor item and some extra data for encryption.
4762306a36Sopenharmony_ci * Starting at offset 1, these hold the generic fs verity descriptor.
4862306a36Sopenharmony_ci * The latter are opaque to btrfs, we just read and write them as a blob for
4962306a36Sopenharmony_ci * the higher level verity code.  The most common descriptor size is 256 bytes.
5062306a36Sopenharmony_ci *
5162306a36Sopenharmony_ci * The merkle tree items:
5262306a36Sopenharmony_ci * [ inode objectid, BTRFS_VERITY_MERKLE_ITEM_KEY, offset ]
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * These also start at offset 0, and correspond to the merkle tree bytes.
5562306a36Sopenharmony_ci * So when fsverity asks for page 0 of the merkle tree, we pull up one page
5662306a36Sopenharmony_ci * starting at offset 0 for this key type.  These are also opaque to btrfs,
5762306a36Sopenharmony_ci * we're blindly storing whatever fsverity sends down.
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * Another important consideration is the fact that the Merkle tree data scales
6062306a36Sopenharmony_ci * linearly with the size of the file (with 4K pages/blocks and SHA-256, it's
6162306a36Sopenharmony_ci * ~1/127th the size) so for large files, writing the tree can be a lengthy
6262306a36Sopenharmony_ci * operation. For that reason, we guard the whole enable verity operation
6362306a36Sopenharmony_ci * (between begin_enable_verity and end_enable_verity) with an orphan item.
6462306a36Sopenharmony_ci * Again, because the data can be pretty large, it's quite possible that we
6562306a36Sopenharmony_ci * could run out of space writing it, so we try our best to handle errors by
6662306a36Sopenharmony_ci * stopping and rolling back rather than aborting the victim transaction.
6762306a36Sopenharmony_ci */
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#define MERKLE_START_ALIGN			65536
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci/*
7262306a36Sopenharmony_ci * Compute the logical file offset where we cache the Merkle tree.
7362306a36Sopenharmony_ci *
7462306a36Sopenharmony_ci * @inode:  inode of the verity file
7562306a36Sopenharmony_ci *
7662306a36Sopenharmony_ci * For the purposes of caching the Merkle tree pages, as required by
7762306a36Sopenharmony_ci * fs-verity, it is convenient to do size computations in terms of a file
7862306a36Sopenharmony_ci * offset, rather than in terms of page indices.
7962306a36Sopenharmony_ci *
8062306a36Sopenharmony_ci * Use 64K to be sure it's past the last page in the file, even with 64K pages.
8162306a36Sopenharmony_ci * That rounding operation itself can overflow loff_t, so we do it in u64 and
8262306a36Sopenharmony_ci * check.
8362306a36Sopenharmony_ci *
8462306a36Sopenharmony_ci * Returns the file offset on success, negative error code on failure.
8562306a36Sopenharmony_ci */
8662306a36Sopenharmony_cistatic loff_t merkle_file_pos(const struct inode *inode)
8762306a36Sopenharmony_ci{
8862306a36Sopenharmony_ci	u64 sz = inode->i_size;
8962306a36Sopenharmony_ci	u64 rounded = round_up(sz, MERKLE_START_ALIGN);
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	if (rounded > inode->i_sb->s_maxbytes)
9262306a36Sopenharmony_ci		return -EFBIG;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	return rounded;
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * Drop all the items for this inode with this key_type.
9962306a36Sopenharmony_ci *
10062306a36Sopenharmony_ci * @inode:     inode to drop items for
10162306a36Sopenharmony_ci * @key_type:  type of items to drop (BTRFS_VERITY_DESC_ITEM or
10262306a36Sopenharmony_ci *             BTRFS_VERITY_MERKLE_ITEM)
10362306a36Sopenharmony_ci *
10462306a36Sopenharmony_ci * Before doing a verity enable we cleanup any existing verity items.
10562306a36Sopenharmony_ci * This is also used to clean up if a verity enable failed half way through.
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * Returns number of dropped items on success, negative error code on failure.
10862306a36Sopenharmony_ci */
10962306a36Sopenharmony_cistatic int drop_verity_items(struct btrfs_inode *inode, u8 key_type)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	struct btrfs_trans_handle *trans;
11262306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
11362306a36Sopenharmony_ci	struct btrfs_path *path;
11462306a36Sopenharmony_ci	struct btrfs_key key;
11562306a36Sopenharmony_ci	int count = 0;
11662306a36Sopenharmony_ci	int ret;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	path = btrfs_alloc_path();
11962306a36Sopenharmony_ci	if (!path)
12062306a36Sopenharmony_ci		return -ENOMEM;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	while (1) {
12362306a36Sopenharmony_ci		/* 1 for the item being dropped */
12462306a36Sopenharmony_ci		trans = btrfs_start_transaction(root, 1);
12562306a36Sopenharmony_ci		if (IS_ERR(trans)) {
12662306a36Sopenharmony_ci			ret = PTR_ERR(trans);
12762306a36Sopenharmony_ci			goto out;
12862306a36Sopenharmony_ci		}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci		/*
13162306a36Sopenharmony_ci		 * Walk backwards through all the items until we find one that
13262306a36Sopenharmony_ci		 * isn't from our key type or objectid
13362306a36Sopenharmony_ci		 */
13462306a36Sopenharmony_ci		key.objectid = btrfs_ino(inode);
13562306a36Sopenharmony_ci		key.type = key_type;
13662306a36Sopenharmony_ci		key.offset = (u64)-1;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
13962306a36Sopenharmony_ci		if (ret > 0) {
14062306a36Sopenharmony_ci			ret = 0;
14162306a36Sopenharmony_ci			/* No more keys of this type, we're done */
14262306a36Sopenharmony_ci			if (path->slots[0] == 0)
14362306a36Sopenharmony_ci				break;
14462306a36Sopenharmony_ci			path->slots[0]--;
14562306a36Sopenharmony_ci		} else if (ret < 0) {
14662306a36Sopenharmony_ci			btrfs_end_transaction(trans);
14762306a36Sopenharmony_ci			goto out;
14862306a36Sopenharmony_ci		}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci		/* No more keys of this type, we're done */
15362306a36Sopenharmony_ci		if (key.objectid != btrfs_ino(inode) || key.type != key_type)
15462306a36Sopenharmony_ci			break;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci		/*
15762306a36Sopenharmony_ci		 * This shouldn't be a performance sensitive function because
15862306a36Sopenharmony_ci		 * it's not used as part of truncate.  If it ever becomes
15962306a36Sopenharmony_ci		 * perf sensitive, change this to walk forward and bulk delete
16062306a36Sopenharmony_ci		 * items
16162306a36Sopenharmony_ci		 */
16262306a36Sopenharmony_ci		ret = btrfs_del_items(trans, root, path, path->slots[0], 1);
16362306a36Sopenharmony_ci		if (ret) {
16462306a36Sopenharmony_ci			btrfs_end_transaction(trans);
16562306a36Sopenharmony_ci			goto out;
16662306a36Sopenharmony_ci		}
16762306a36Sopenharmony_ci		count++;
16862306a36Sopenharmony_ci		btrfs_release_path(path);
16962306a36Sopenharmony_ci		btrfs_end_transaction(trans);
17062306a36Sopenharmony_ci	}
17162306a36Sopenharmony_ci	ret = count;
17262306a36Sopenharmony_ci	btrfs_end_transaction(trans);
17362306a36Sopenharmony_ciout:
17462306a36Sopenharmony_ci	btrfs_free_path(path);
17562306a36Sopenharmony_ci	return ret;
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci/*
17962306a36Sopenharmony_ci * Drop all verity items
18062306a36Sopenharmony_ci *
18162306a36Sopenharmony_ci * @inode:  inode to drop verity items for
18262306a36Sopenharmony_ci *
18362306a36Sopenharmony_ci * In most contexts where we are dropping verity items, we want to do it for all
18462306a36Sopenharmony_ci * the types of verity items, not a particular one.
18562306a36Sopenharmony_ci *
18662306a36Sopenharmony_ci * Returns: 0 on success, negative error code on failure.
18762306a36Sopenharmony_ci */
18862306a36Sopenharmony_ciint btrfs_drop_verity_items(struct btrfs_inode *inode)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	int ret;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	ret = drop_verity_items(inode, BTRFS_VERITY_DESC_ITEM_KEY);
19362306a36Sopenharmony_ci	if (ret < 0)
19462306a36Sopenharmony_ci		return ret;
19562306a36Sopenharmony_ci	ret = drop_verity_items(inode, BTRFS_VERITY_MERKLE_ITEM_KEY);
19662306a36Sopenharmony_ci	if (ret < 0)
19762306a36Sopenharmony_ci		return ret;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return 0;
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/*
20362306a36Sopenharmony_ci * Insert and write inode items with a given key type and offset.
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci * @inode:     inode to insert for
20662306a36Sopenharmony_ci * @key_type:  key type to insert
20762306a36Sopenharmony_ci * @offset:    item offset to insert at
20862306a36Sopenharmony_ci * @src:       source data to write
20962306a36Sopenharmony_ci * @len:       length of source data to write
21062306a36Sopenharmony_ci *
21162306a36Sopenharmony_ci * Write len bytes from src into items of up to 2K length.
21262306a36Sopenharmony_ci * The inserted items will have key (ino, key_type, offset + off) where off is
21362306a36Sopenharmony_ci * consecutively increasing from 0 up to the last item ending at offset + len.
21462306a36Sopenharmony_ci *
21562306a36Sopenharmony_ci * Returns 0 on success and a negative error code on failure.
21662306a36Sopenharmony_ci */
21762306a36Sopenharmony_cistatic int write_key_bytes(struct btrfs_inode *inode, u8 key_type, u64 offset,
21862306a36Sopenharmony_ci			   const char *src, u64 len)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	struct btrfs_trans_handle *trans;
22162306a36Sopenharmony_ci	struct btrfs_path *path;
22262306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
22362306a36Sopenharmony_ci	struct extent_buffer *leaf;
22462306a36Sopenharmony_ci	struct btrfs_key key;
22562306a36Sopenharmony_ci	unsigned long copy_bytes;
22662306a36Sopenharmony_ci	unsigned long src_offset = 0;
22762306a36Sopenharmony_ci	void *data;
22862306a36Sopenharmony_ci	int ret = 0;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	path = btrfs_alloc_path();
23162306a36Sopenharmony_ci	if (!path)
23262306a36Sopenharmony_ci		return -ENOMEM;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	while (len > 0) {
23562306a36Sopenharmony_ci		/* 1 for the new item being inserted */
23662306a36Sopenharmony_ci		trans = btrfs_start_transaction(root, 1);
23762306a36Sopenharmony_ci		if (IS_ERR(trans)) {
23862306a36Sopenharmony_ci			ret = PTR_ERR(trans);
23962306a36Sopenharmony_ci			break;
24062306a36Sopenharmony_ci		}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci		key.objectid = btrfs_ino(inode);
24362306a36Sopenharmony_ci		key.type = key_type;
24462306a36Sopenharmony_ci		key.offset = offset;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci		/*
24762306a36Sopenharmony_ci		 * Insert 2K at a time mostly to be friendly for smaller leaf
24862306a36Sopenharmony_ci		 * size filesystems
24962306a36Sopenharmony_ci		 */
25062306a36Sopenharmony_ci		copy_bytes = min_t(u64, len, 2048);
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci		ret = btrfs_insert_empty_item(trans, root, path, &key, copy_bytes);
25362306a36Sopenharmony_ci		if (ret) {
25462306a36Sopenharmony_ci			btrfs_end_transaction(trans);
25562306a36Sopenharmony_ci			break;
25662306a36Sopenharmony_ci		}
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci		leaf = path->nodes[0];
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci		data = btrfs_item_ptr(leaf, path->slots[0], void);
26162306a36Sopenharmony_ci		write_extent_buffer(leaf, src + src_offset,
26262306a36Sopenharmony_ci				    (unsigned long)data, copy_bytes);
26362306a36Sopenharmony_ci		offset += copy_bytes;
26462306a36Sopenharmony_ci		src_offset += copy_bytes;
26562306a36Sopenharmony_ci		len -= copy_bytes;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci		btrfs_release_path(path);
26862306a36Sopenharmony_ci		btrfs_end_transaction(trans);
26962306a36Sopenharmony_ci	}
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	btrfs_free_path(path);
27262306a36Sopenharmony_ci	return ret;
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/*
27662306a36Sopenharmony_ci * Read inode items of the given key type and offset from the btree.
27762306a36Sopenharmony_ci *
27862306a36Sopenharmony_ci * @inode:      inode to read items of
27962306a36Sopenharmony_ci * @key_type:   key type to read
28062306a36Sopenharmony_ci * @offset:     item offset to read from
28162306a36Sopenharmony_ci * @dest:       Buffer to read into. This parameter has slightly tricky
28262306a36Sopenharmony_ci *              semantics.  If it is NULL, the function will not do any copying
28362306a36Sopenharmony_ci *              and will just return the size of all the items up to len bytes.
28462306a36Sopenharmony_ci *              If dest_page is passed, then the function will kmap_local the
28562306a36Sopenharmony_ci *              page and ignore dest, but it must still be non-NULL to avoid the
28662306a36Sopenharmony_ci *              counting-only behavior.
28762306a36Sopenharmony_ci * @len:        length in bytes to read
28862306a36Sopenharmony_ci * @dest_page:  copy into this page instead of the dest buffer
28962306a36Sopenharmony_ci *
29062306a36Sopenharmony_ci * Helper function to read items from the btree.  This returns the number of
29162306a36Sopenharmony_ci * bytes read or < 0 for errors.  We can return short reads if the items don't
29262306a36Sopenharmony_ci * exist on disk or aren't big enough to fill the desired length.  Supports
29362306a36Sopenharmony_ci * reading into a provided buffer (dest) or into the page cache
29462306a36Sopenharmony_ci *
29562306a36Sopenharmony_ci * Returns number of bytes read or a negative error code on failure.
29662306a36Sopenharmony_ci */
29762306a36Sopenharmony_cistatic int read_key_bytes(struct btrfs_inode *inode, u8 key_type, u64 offset,
29862306a36Sopenharmony_ci			  char *dest, u64 len, struct page *dest_page)
29962306a36Sopenharmony_ci{
30062306a36Sopenharmony_ci	struct btrfs_path *path;
30162306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
30262306a36Sopenharmony_ci	struct extent_buffer *leaf;
30362306a36Sopenharmony_ci	struct btrfs_key key;
30462306a36Sopenharmony_ci	u64 item_end;
30562306a36Sopenharmony_ci	u64 copy_end;
30662306a36Sopenharmony_ci	int copied = 0;
30762306a36Sopenharmony_ci	u32 copy_offset;
30862306a36Sopenharmony_ci	unsigned long copy_bytes;
30962306a36Sopenharmony_ci	unsigned long dest_offset = 0;
31062306a36Sopenharmony_ci	void *data;
31162306a36Sopenharmony_ci	char *kaddr = dest;
31262306a36Sopenharmony_ci	int ret;
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	path = btrfs_alloc_path();
31562306a36Sopenharmony_ci	if (!path)
31662306a36Sopenharmony_ci		return -ENOMEM;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	if (dest_page)
31962306a36Sopenharmony_ci		path->reada = READA_FORWARD;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	key.objectid = btrfs_ino(inode);
32262306a36Sopenharmony_ci	key.type = key_type;
32362306a36Sopenharmony_ci	key.offset = offset;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
32662306a36Sopenharmony_ci	if (ret < 0) {
32762306a36Sopenharmony_ci		goto out;
32862306a36Sopenharmony_ci	} else if (ret > 0) {
32962306a36Sopenharmony_ci		ret = 0;
33062306a36Sopenharmony_ci		if (path->slots[0] == 0)
33162306a36Sopenharmony_ci			goto out;
33262306a36Sopenharmony_ci		path->slots[0]--;
33362306a36Sopenharmony_ci	}
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	while (len > 0) {
33662306a36Sopenharmony_ci		leaf = path->nodes[0];
33762306a36Sopenharmony_ci		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci		if (key.objectid != btrfs_ino(inode) || key.type != key_type)
34062306a36Sopenharmony_ci			break;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci		item_end = btrfs_item_size(leaf, path->slots[0]) + key.offset;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci		if (copied > 0) {
34562306a36Sopenharmony_ci			/*
34662306a36Sopenharmony_ci			 * Once we've copied something, we want all of the items
34762306a36Sopenharmony_ci			 * to be sequential
34862306a36Sopenharmony_ci			 */
34962306a36Sopenharmony_ci			if (key.offset != offset)
35062306a36Sopenharmony_ci				break;
35162306a36Sopenharmony_ci		} else {
35262306a36Sopenharmony_ci			/*
35362306a36Sopenharmony_ci			 * Our initial offset might be in the middle of an
35462306a36Sopenharmony_ci			 * item.  Make sure it all makes sense.
35562306a36Sopenharmony_ci			 */
35662306a36Sopenharmony_ci			if (key.offset > offset)
35762306a36Sopenharmony_ci				break;
35862306a36Sopenharmony_ci			if (item_end <= offset)
35962306a36Sopenharmony_ci				break;
36062306a36Sopenharmony_ci		}
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci		/* desc = NULL to just sum all the item lengths */
36362306a36Sopenharmony_ci		if (!dest)
36462306a36Sopenharmony_ci			copy_end = item_end;
36562306a36Sopenharmony_ci		else
36662306a36Sopenharmony_ci			copy_end = min(offset + len, item_end);
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci		/* Number of bytes in this item we want to copy */
36962306a36Sopenharmony_ci		copy_bytes = copy_end - offset;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci		/* Offset from the start of item for copying */
37262306a36Sopenharmony_ci		copy_offset = offset - key.offset;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci		if (dest) {
37562306a36Sopenharmony_ci			if (dest_page)
37662306a36Sopenharmony_ci				kaddr = kmap_local_page(dest_page);
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci			data = btrfs_item_ptr(leaf, path->slots[0], void);
37962306a36Sopenharmony_ci			read_extent_buffer(leaf, kaddr + dest_offset,
38062306a36Sopenharmony_ci					   (unsigned long)data + copy_offset,
38162306a36Sopenharmony_ci					   copy_bytes);
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci			if (dest_page)
38462306a36Sopenharmony_ci				kunmap_local(kaddr);
38562306a36Sopenharmony_ci		}
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci		offset += copy_bytes;
38862306a36Sopenharmony_ci		dest_offset += copy_bytes;
38962306a36Sopenharmony_ci		len -= copy_bytes;
39062306a36Sopenharmony_ci		copied += copy_bytes;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci		path->slots[0]++;
39362306a36Sopenharmony_ci		if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
39462306a36Sopenharmony_ci			/*
39562306a36Sopenharmony_ci			 * We've reached the last slot in this leaf and we need
39662306a36Sopenharmony_ci			 * to go to the next leaf.
39762306a36Sopenharmony_ci			 */
39862306a36Sopenharmony_ci			ret = btrfs_next_leaf(root, path);
39962306a36Sopenharmony_ci			if (ret < 0) {
40062306a36Sopenharmony_ci				break;
40162306a36Sopenharmony_ci			} else if (ret > 0) {
40262306a36Sopenharmony_ci				ret = 0;
40362306a36Sopenharmony_ci				break;
40462306a36Sopenharmony_ci			}
40562306a36Sopenharmony_ci		}
40662306a36Sopenharmony_ci	}
40762306a36Sopenharmony_ciout:
40862306a36Sopenharmony_ci	btrfs_free_path(path);
40962306a36Sopenharmony_ci	if (!ret)
41062306a36Sopenharmony_ci		ret = copied;
41162306a36Sopenharmony_ci	return ret;
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci/*
41562306a36Sopenharmony_ci * Delete an fsverity orphan
41662306a36Sopenharmony_ci *
41762306a36Sopenharmony_ci * @trans:  transaction to do the delete in
41862306a36Sopenharmony_ci * @inode:  inode to orphan
41962306a36Sopenharmony_ci *
42062306a36Sopenharmony_ci * Capture verity orphan specific logic that is repeated in the couple places
42162306a36Sopenharmony_ci * we delete verity orphans. Specifically, handling ENOENT and ignoring inodes
42262306a36Sopenharmony_ci * with 0 links.
42362306a36Sopenharmony_ci *
42462306a36Sopenharmony_ci * Returns zero on success or a negative error code on failure.
42562306a36Sopenharmony_ci */
42662306a36Sopenharmony_cistatic int del_orphan(struct btrfs_trans_handle *trans, struct btrfs_inode *inode)
42762306a36Sopenharmony_ci{
42862306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
42962306a36Sopenharmony_ci	int ret;
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	/*
43262306a36Sopenharmony_ci	 * If the inode has no links, it is either already unlinked, or was
43362306a36Sopenharmony_ci	 * created with O_TMPFILE. In either case, it should have an orphan from
43462306a36Sopenharmony_ci	 * that other operation. Rather than reference count the orphans, we
43562306a36Sopenharmony_ci	 * simply ignore them here, because we only invoke the verity path in
43662306a36Sopenharmony_ci	 * the orphan logic when i_nlink is 1.
43762306a36Sopenharmony_ci	 */
43862306a36Sopenharmony_ci	if (!inode->vfs_inode.i_nlink)
43962306a36Sopenharmony_ci		return 0;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode));
44262306a36Sopenharmony_ci	if (ret == -ENOENT)
44362306a36Sopenharmony_ci		ret = 0;
44462306a36Sopenharmony_ci	return ret;
44562306a36Sopenharmony_ci}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci/*
44862306a36Sopenharmony_ci * Rollback in-progress verity if we encounter an error.
44962306a36Sopenharmony_ci *
45062306a36Sopenharmony_ci * @inode:  inode verity had an error for
45162306a36Sopenharmony_ci *
45262306a36Sopenharmony_ci * We try to handle recoverable errors while enabling verity by rolling it back
45362306a36Sopenharmony_ci * and just failing the operation, rather than having an fs level error no
45462306a36Sopenharmony_ci * matter what. However, any error in rollback is unrecoverable.
45562306a36Sopenharmony_ci *
45662306a36Sopenharmony_ci * Returns 0 on success, negative error code on failure.
45762306a36Sopenharmony_ci */
45862306a36Sopenharmony_cistatic int rollback_verity(struct btrfs_inode *inode)
45962306a36Sopenharmony_ci{
46062306a36Sopenharmony_ci	struct btrfs_trans_handle *trans = NULL;
46162306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
46262306a36Sopenharmony_ci	int ret;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	ASSERT(inode_is_locked(&inode->vfs_inode));
46562306a36Sopenharmony_ci	truncate_inode_pages(inode->vfs_inode.i_mapping, inode->vfs_inode.i_size);
46662306a36Sopenharmony_ci	clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
46762306a36Sopenharmony_ci	ret = btrfs_drop_verity_items(inode);
46862306a36Sopenharmony_ci	if (ret) {
46962306a36Sopenharmony_ci		btrfs_handle_fs_error(root->fs_info, ret,
47062306a36Sopenharmony_ci				"failed to drop verity items in rollback %llu",
47162306a36Sopenharmony_ci				(u64)inode->vfs_inode.i_ino);
47262306a36Sopenharmony_ci		goto out;
47362306a36Sopenharmony_ci	}
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	/*
47662306a36Sopenharmony_ci	 * 1 for updating the inode flag
47762306a36Sopenharmony_ci	 * 1 for deleting the orphan
47862306a36Sopenharmony_ci	 */
47962306a36Sopenharmony_ci	trans = btrfs_start_transaction(root, 2);
48062306a36Sopenharmony_ci	if (IS_ERR(trans)) {
48162306a36Sopenharmony_ci		ret = PTR_ERR(trans);
48262306a36Sopenharmony_ci		trans = NULL;
48362306a36Sopenharmony_ci		btrfs_handle_fs_error(root->fs_info, ret,
48462306a36Sopenharmony_ci			"failed to start transaction in verity rollback %llu",
48562306a36Sopenharmony_ci			(u64)inode->vfs_inode.i_ino);
48662306a36Sopenharmony_ci		goto out;
48762306a36Sopenharmony_ci	}
48862306a36Sopenharmony_ci	inode->ro_flags &= ~BTRFS_INODE_RO_VERITY;
48962306a36Sopenharmony_ci	btrfs_sync_inode_flags_to_i_flags(&inode->vfs_inode);
49062306a36Sopenharmony_ci	ret = btrfs_update_inode(trans, root, inode);
49162306a36Sopenharmony_ci	if (ret) {
49262306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
49362306a36Sopenharmony_ci		goto out;
49462306a36Sopenharmony_ci	}
49562306a36Sopenharmony_ci	ret = del_orphan(trans, inode);
49662306a36Sopenharmony_ci	if (ret) {
49762306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
49862306a36Sopenharmony_ci		goto out;
49962306a36Sopenharmony_ci	}
50062306a36Sopenharmony_ciout:
50162306a36Sopenharmony_ci	if (trans)
50262306a36Sopenharmony_ci		btrfs_end_transaction(trans);
50362306a36Sopenharmony_ci	return ret;
50462306a36Sopenharmony_ci}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci/*
50762306a36Sopenharmony_ci * Finalize making the file a valid verity file
50862306a36Sopenharmony_ci *
50962306a36Sopenharmony_ci * @inode:      inode to be marked as verity
51062306a36Sopenharmony_ci * @desc:       contents of the verity descriptor to write (not NULL)
51162306a36Sopenharmony_ci * @desc_size:  size of the verity descriptor
51262306a36Sopenharmony_ci *
51362306a36Sopenharmony_ci * Do the actual work of finalizing verity after successfully writing the Merkle
51462306a36Sopenharmony_ci * tree:
51562306a36Sopenharmony_ci *
51662306a36Sopenharmony_ci * - write out the descriptor items
51762306a36Sopenharmony_ci * - mark the inode with the verity flag
51862306a36Sopenharmony_ci * - delete the orphan item
51962306a36Sopenharmony_ci * - mark the ro compat bit
52062306a36Sopenharmony_ci * - clear the in progress bit
52162306a36Sopenharmony_ci *
52262306a36Sopenharmony_ci * Returns 0 on success, negative error code on failure.
52362306a36Sopenharmony_ci */
52462306a36Sopenharmony_cistatic int finish_verity(struct btrfs_inode *inode, const void *desc,
52562306a36Sopenharmony_ci			 size_t desc_size)
52662306a36Sopenharmony_ci{
52762306a36Sopenharmony_ci	struct btrfs_trans_handle *trans = NULL;
52862306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
52962306a36Sopenharmony_ci	struct btrfs_verity_descriptor_item item;
53062306a36Sopenharmony_ci	int ret;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	/* Write out the descriptor item */
53362306a36Sopenharmony_ci	memset(&item, 0, sizeof(item));
53462306a36Sopenharmony_ci	btrfs_set_stack_verity_descriptor_size(&item, desc_size);
53562306a36Sopenharmony_ci	ret = write_key_bytes(inode, BTRFS_VERITY_DESC_ITEM_KEY, 0,
53662306a36Sopenharmony_ci			      (const char *)&item, sizeof(item));
53762306a36Sopenharmony_ci	if (ret)
53862306a36Sopenharmony_ci		goto out;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	/* Write out the descriptor itself */
54162306a36Sopenharmony_ci	ret = write_key_bytes(inode, BTRFS_VERITY_DESC_ITEM_KEY, 1,
54262306a36Sopenharmony_ci			      desc, desc_size);
54362306a36Sopenharmony_ci	if (ret)
54462306a36Sopenharmony_ci		goto out;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	/*
54762306a36Sopenharmony_ci	 * 1 for updating the inode flag
54862306a36Sopenharmony_ci	 * 1 for deleting the orphan
54962306a36Sopenharmony_ci	 */
55062306a36Sopenharmony_ci	trans = btrfs_start_transaction(root, 2);
55162306a36Sopenharmony_ci	if (IS_ERR(trans)) {
55262306a36Sopenharmony_ci		ret = PTR_ERR(trans);
55362306a36Sopenharmony_ci		goto out;
55462306a36Sopenharmony_ci	}
55562306a36Sopenharmony_ci	inode->ro_flags |= BTRFS_INODE_RO_VERITY;
55662306a36Sopenharmony_ci	btrfs_sync_inode_flags_to_i_flags(&inode->vfs_inode);
55762306a36Sopenharmony_ci	ret = btrfs_update_inode(trans, root, inode);
55862306a36Sopenharmony_ci	if (ret)
55962306a36Sopenharmony_ci		goto end_trans;
56062306a36Sopenharmony_ci	ret = del_orphan(trans, inode);
56162306a36Sopenharmony_ci	if (ret)
56262306a36Sopenharmony_ci		goto end_trans;
56362306a36Sopenharmony_ci	clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
56462306a36Sopenharmony_ci	btrfs_set_fs_compat_ro(root->fs_info, VERITY);
56562306a36Sopenharmony_ciend_trans:
56662306a36Sopenharmony_ci	btrfs_end_transaction(trans);
56762306a36Sopenharmony_ciout:
56862306a36Sopenharmony_ci	return ret;
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci/*
57362306a36Sopenharmony_ci * fsverity op that begins enabling verity.
57462306a36Sopenharmony_ci *
57562306a36Sopenharmony_ci * @filp:  file to enable verity on
57662306a36Sopenharmony_ci *
57762306a36Sopenharmony_ci * Begin enabling fsverity for the file. We drop any existing verity items, add
57862306a36Sopenharmony_ci * an orphan and set the in progress bit.
57962306a36Sopenharmony_ci *
58062306a36Sopenharmony_ci * Returns 0 on success, negative error code on failure.
58162306a36Sopenharmony_ci */
58262306a36Sopenharmony_cistatic int btrfs_begin_enable_verity(struct file *filp)
58362306a36Sopenharmony_ci{
58462306a36Sopenharmony_ci	struct btrfs_inode *inode = BTRFS_I(file_inode(filp));
58562306a36Sopenharmony_ci	struct btrfs_root *root = inode->root;
58662306a36Sopenharmony_ci	struct btrfs_trans_handle *trans;
58762306a36Sopenharmony_ci	int ret;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	ASSERT(inode_is_locked(file_inode(filp)));
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci	if (test_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags))
59262306a36Sopenharmony_ci		return -EBUSY;
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	/*
59562306a36Sopenharmony_ci	 * This should almost never do anything, but theoretically, it's
59662306a36Sopenharmony_ci	 * possible that we failed to enable verity on a file, then were
59762306a36Sopenharmony_ci	 * interrupted or failed while rolling back, failed to cleanup the
59862306a36Sopenharmony_ci	 * orphan, and finally attempt to enable verity again.
59962306a36Sopenharmony_ci	 */
60062306a36Sopenharmony_ci	ret = btrfs_drop_verity_items(inode);
60162306a36Sopenharmony_ci	if (ret)
60262306a36Sopenharmony_ci		return ret;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	/* 1 for the orphan item */
60562306a36Sopenharmony_ci	trans = btrfs_start_transaction(root, 1);
60662306a36Sopenharmony_ci	if (IS_ERR(trans))
60762306a36Sopenharmony_ci		return PTR_ERR(trans);
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci	ret = btrfs_orphan_add(trans, inode);
61062306a36Sopenharmony_ci	if (!ret)
61162306a36Sopenharmony_ci		set_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
61262306a36Sopenharmony_ci	btrfs_end_transaction(trans);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	return 0;
61562306a36Sopenharmony_ci}
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci/*
61862306a36Sopenharmony_ci * fsverity op that ends enabling verity.
61962306a36Sopenharmony_ci *
62062306a36Sopenharmony_ci * @filp:              file we are finishing enabling verity on
62162306a36Sopenharmony_ci * @desc:              verity descriptor to write out (NULL in error conditions)
62262306a36Sopenharmony_ci * @desc_size:         size of the verity descriptor (variable with signatures)
62362306a36Sopenharmony_ci * @merkle_tree_size:  size of the merkle tree in bytes
62462306a36Sopenharmony_ci *
62562306a36Sopenharmony_ci * If desc is null, then VFS is signaling an error occurred during verity
62662306a36Sopenharmony_ci * enable, and we should try to rollback. Otherwise, attempt to finish verity.
62762306a36Sopenharmony_ci *
62862306a36Sopenharmony_ci * Returns 0 on success, negative error code on error.
62962306a36Sopenharmony_ci */
63062306a36Sopenharmony_cistatic int btrfs_end_enable_verity(struct file *filp, const void *desc,
63162306a36Sopenharmony_ci				   size_t desc_size, u64 merkle_tree_size)
63262306a36Sopenharmony_ci{
63362306a36Sopenharmony_ci	struct btrfs_inode *inode = BTRFS_I(file_inode(filp));
63462306a36Sopenharmony_ci	int ret = 0;
63562306a36Sopenharmony_ci	int rollback_ret;
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	ASSERT(inode_is_locked(file_inode(filp)));
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	if (desc == NULL)
64062306a36Sopenharmony_ci		goto rollback;
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	ret = finish_verity(inode, desc, desc_size);
64362306a36Sopenharmony_ci	if (ret)
64462306a36Sopenharmony_ci		goto rollback;
64562306a36Sopenharmony_ci	return ret;
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_cirollback:
64862306a36Sopenharmony_ci	rollback_ret = rollback_verity(inode);
64962306a36Sopenharmony_ci	if (rollback_ret)
65062306a36Sopenharmony_ci		btrfs_err(inode->root->fs_info,
65162306a36Sopenharmony_ci			  "failed to rollback verity items: %d", rollback_ret);
65262306a36Sopenharmony_ci	return ret;
65362306a36Sopenharmony_ci}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci/*
65662306a36Sopenharmony_ci * fsverity op that gets the struct fsverity_descriptor.
65762306a36Sopenharmony_ci *
65862306a36Sopenharmony_ci * @inode:     inode to get the descriptor of
65962306a36Sopenharmony_ci * @buf:       output buffer for the descriptor contents
66062306a36Sopenharmony_ci * @buf_size:  size of the output buffer. 0 to query the size
66162306a36Sopenharmony_ci *
66262306a36Sopenharmony_ci * fsverity does a two pass setup for reading the descriptor, in the first pass
66362306a36Sopenharmony_ci * it calls with buf_size = 0 to query the size of the descriptor, and then in
66462306a36Sopenharmony_ci * the second pass it actually reads the descriptor off disk.
66562306a36Sopenharmony_ci *
66662306a36Sopenharmony_ci * Returns the size on success or a negative error code on failure.
66762306a36Sopenharmony_ci */
66862306a36Sopenharmony_ciint btrfs_get_verity_descriptor(struct inode *inode, void *buf, size_t buf_size)
66962306a36Sopenharmony_ci{
67062306a36Sopenharmony_ci	u64 true_size;
67162306a36Sopenharmony_ci	int ret = 0;
67262306a36Sopenharmony_ci	struct btrfs_verity_descriptor_item item;
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	memset(&item, 0, sizeof(item));
67562306a36Sopenharmony_ci	ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_DESC_ITEM_KEY, 0,
67662306a36Sopenharmony_ci			     (char *)&item, sizeof(item), NULL);
67762306a36Sopenharmony_ci	if (ret < 0)
67862306a36Sopenharmony_ci		return ret;
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	if (item.reserved[0] != 0 || item.reserved[1] != 0)
68162306a36Sopenharmony_ci		return -EUCLEAN;
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	true_size = btrfs_stack_verity_descriptor_size(&item);
68462306a36Sopenharmony_ci	if (true_size > INT_MAX)
68562306a36Sopenharmony_ci		return -EUCLEAN;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	if (buf_size == 0)
68862306a36Sopenharmony_ci		return true_size;
68962306a36Sopenharmony_ci	if (buf_size < true_size)
69062306a36Sopenharmony_ci		return -ERANGE;
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_DESC_ITEM_KEY, 1,
69362306a36Sopenharmony_ci			     buf, buf_size, NULL);
69462306a36Sopenharmony_ci	if (ret < 0)
69562306a36Sopenharmony_ci		return ret;
69662306a36Sopenharmony_ci	if (ret != true_size)
69762306a36Sopenharmony_ci		return -EIO;
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	return true_size;
70062306a36Sopenharmony_ci}
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci/*
70362306a36Sopenharmony_ci * fsverity op that reads and caches a merkle tree page.
70462306a36Sopenharmony_ci *
70562306a36Sopenharmony_ci * @inode:         inode to read a merkle tree page for
70662306a36Sopenharmony_ci * @index:         page index relative to the start of the merkle tree
70762306a36Sopenharmony_ci * @num_ra_pages:  number of pages to readahead. Optional, we ignore it
70862306a36Sopenharmony_ci *
70962306a36Sopenharmony_ci * The Merkle tree is stored in the filesystem btree, but its pages are cached
71062306a36Sopenharmony_ci * with a logical position past EOF in the inode's mapping.
71162306a36Sopenharmony_ci *
71262306a36Sopenharmony_ci * Returns the page we read, or an ERR_PTR on error.
71362306a36Sopenharmony_ci */
71462306a36Sopenharmony_cistatic struct page *btrfs_read_merkle_tree_page(struct inode *inode,
71562306a36Sopenharmony_ci						pgoff_t index,
71662306a36Sopenharmony_ci						unsigned long num_ra_pages)
71762306a36Sopenharmony_ci{
71862306a36Sopenharmony_ci	struct folio *folio;
71962306a36Sopenharmony_ci	u64 off = (u64)index << PAGE_SHIFT;
72062306a36Sopenharmony_ci	loff_t merkle_pos = merkle_file_pos(inode);
72162306a36Sopenharmony_ci	int ret;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	if (merkle_pos < 0)
72462306a36Sopenharmony_ci		return ERR_PTR(merkle_pos);
72562306a36Sopenharmony_ci	if (merkle_pos > inode->i_sb->s_maxbytes - off - PAGE_SIZE)
72662306a36Sopenharmony_ci		return ERR_PTR(-EFBIG);
72762306a36Sopenharmony_ci	index += merkle_pos >> PAGE_SHIFT;
72862306a36Sopenharmony_ciagain:
72962306a36Sopenharmony_ci	folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0);
73062306a36Sopenharmony_ci	if (!IS_ERR(folio)) {
73162306a36Sopenharmony_ci		if (folio_test_uptodate(folio))
73262306a36Sopenharmony_ci			goto out;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci		folio_lock(folio);
73562306a36Sopenharmony_ci		/* If it's not uptodate after we have the lock, we got a read error. */
73662306a36Sopenharmony_ci		if (!folio_test_uptodate(folio)) {
73762306a36Sopenharmony_ci			folio_unlock(folio);
73862306a36Sopenharmony_ci			folio_put(folio);
73962306a36Sopenharmony_ci			return ERR_PTR(-EIO);
74062306a36Sopenharmony_ci		}
74162306a36Sopenharmony_ci		folio_unlock(folio);
74262306a36Sopenharmony_ci		goto out;
74362306a36Sopenharmony_ci	}
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	folio = filemap_alloc_folio(mapping_gfp_constraint(inode->i_mapping, ~__GFP_FS),
74662306a36Sopenharmony_ci				    0);
74762306a36Sopenharmony_ci	if (!folio)
74862306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	ret = filemap_add_folio(inode->i_mapping, folio, index, GFP_NOFS);
75162306a36Sopenharmony_ci	if (ret) {
75262306a36Sopenharmony_ci		folio_put(folio);
75362306a36Sopenharmony_ci		/* Did someone else insert a folio here? */
75462306a36Sopenharmony_ci		if (ret == -EEXIST)
75562306a36Sopenharmony_ci			goto again;
75662306a36Sopenharmony_ci		return ERR_PTR(ret);
75762306a36Sopenharmony_ci	}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	/*
76062306a36Sopenharmony_ci	 * Merkle item keys are indexed from byte 0 in the merkle tree.
76162306a36Sopenharmony_ci	 * They have the form:
76262306a36Sopenharmony_ci	 *
76362306a36Sopenharmony_ci	 * [ inode objectid, BTRFS_MERKLE_ITEM_KEY, offset in bytes ]
76462306a36Sopenharmony_ci	 */
76562306a36Sopenharmony_ci	ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY, off,
76662306a36Sopenharmony_ci			     folio_address(folio), PAGE_SIZE, &folio->page);
76762306a36Sopenharmony_ci	if (ret < 0) {
76862306a36Sopenharmony_ci		folio_put(folio);
76962306a36Sopenharmony_ci		return ERR_PTR(ret);
77062306a36Sopenharmony_ci	}
77162306a36Sopenharmony_ci	if (ret < PAGE_SIZE)
77262306a36Sopenharmony_ci		folio_zero_segment(folio, ret, PAGE_SIZE);
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci	folio_mark_uptodate(folio);
77562306a36Sopenharmony_ci	folio_unlock(folio);
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ciout:
77862306a36Sopenharmony_ci	return folio_file_page(folio, index);
77962306a36Sopenharmony_ci}
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci/*
78262306a36Sopenharmony_ci * fsverity op that writes a Merkle tree block into the btree.
78362306a36Sopenharmony_ci *
78462306a36Sopenharmony_ci * @inode:	inode to write a Merkle tree block for
78562306a36Sopenharmony_ci * @buf:	Merkle tree block to write
78662306a36Sopenharmony_ci * @pos:	the position of the block in the Merkle tree (in bytes)
78762306a36Sopenharmony_ci * @size:	the Merkle tree block size (in bytes)
78862306a36Sopenharmony_ci *
78962306a36Sopenharmony_ci * Returns 0 on success or negative error code on failure
79062306a36Sopenharmony_ci */
79162306a36Sopenharmony_cistatic int btrfs_write_merkle_tree_block(struct inode *inode, const void *buf,
79262306a36Sopenharmony_ci					 u64 pos, unsigned int size)
79362306a36Sopenharmony_ci{
79462306a36Sopenharmony_ci	loff_t merkle_pos = merkle_file_pos(inode);
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	if (merkle_pos < 0)
79762306a36Sopenharmony_ci		return merkle_pos;
79862306a36Sopenharmony_ci	if (merkle_pos > inode->i_sb->s_maxbytes - pos - size)
79962306a36Sopenharmony_ci		return -EFBIG;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	return write_key_bytes(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY,
80262306a36Sopenharmony_ci			       pos, buf, size);
80362306a36Sopenharmony_ci}
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ciconst struct fsverity_operations btrfs_verityops = {
80662306a36Sopenharmony_ci	.begin_enable_verity     = btrfs_begin_enable_verity,
80762306a36Sopenharmony_ci	.end_enable_verity       = btrfs_end_enable_verity,
80862306a36Sopenharmony_ci	.get_verity_descriptor   = btrfs_get_verity_descriptor,
80962306a36Sopenharmony_ci	.read_merkle_tree_page   = btrfs_read_merkle_tree_page,
81062306a36Sopenharmony_ci	.write_merkle_tree_block = btrfs_write_merkle_tree_block,
81162306a36Sopenharmony_ci};
812