// SPDX-License-Identifier: GPL-2.0

#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/rwsem.h>
#include <linux/xattr.h>
#include <linux/security.h>
#include <linux/posix_acl_xattr.h>
#include <linux/iversion.h>
#include <linux/fsverity.h>
#include <linux/sched/mm.h>
#include "messages.h"
#include "ctree.h"
#include "btrfs_inode.h"
#include "transaction.h"
#include "locking.h"
#include "fs.h"
#include "accessors.h"
#include "ioctl.h"
#include "verity.h"
#include "orphan.h"

/*
 * Implementation of the interface defined in struct fsverity_operations.
 *
 * The main question is how and where to store the verity descriptor and the
 * Merkle tree. We store both in dedicated btree items in the filesystem tree,
 * together with the rest of the inode metadata. This means we'll need to do
 * extra work to encrypt them once encryption is supported in btrfs, but btrfs
 * has a lot of careful code around i_size and it seems better to make a new key
 * type than try and adjust all of our expectations for i_size.
 *
 * Note that this differs from the implementation in ext4 and f2fs, where
 * this data is stored as if it were in the file, but past EOF. However, btrfs
 * does not have a widespread mechanism for caching opaque metadata pages, so we
 * do pretend that the Merkle tree pages themselves are past EOF for the
 * purposes of caching them (as opposed to creating a virtual inode).
 *
 * fs verity items are stored under two different key types on disk.
 * The descriptor items:
 * [ inode objectid, BTRFS_VERITY_DESC_ITEM_KEY, offset ]
 *
 * At offset 0, we store a btrfs_verity_descriptor_item which tracks the
 * size of the descriptor item and some extra data for encryption.
 * Starting at offset 1, these hold the generic fs verity descriptor.
 * The latter are opaque to btrfs, we just read and write them as a blob for
 * the higher level verity code.  The most common descriptor size is 256 bytes.
 *
 * The merkle tree items:
 * [ inode objectid, BTRFS_VERITY_MERKLE_ITEM_KEY, offset ]
 *
 * These also start at offset 0, and correspond to the merkle tree bytes.
 * So when fsverity asks for page 0 of the merkle tree, we pull up one page
 * starting at offset 0 for this key type.  These are also opaque to btrfs,
 * we're blindly storing whatever fsverity sends down.
 *
 * Another important consideration is the fact that the Merkle tree data scales
 * linearly with the size of the file (with 4K pages/blocks and SHA-256, it's
 * ~1/127th the size) so for large files, writing the tree can be a lengthy
 * operation. For that reason, we guard the whole enable verity operation
 * (between begin_enable_verity and end_enable_verity) with an orphan item.
 * Again, because the data can be pretty large, it's quite possible that we
 * could run out of space writing it, so we try our best to handle errors by
 * stopping and rolling back rather than aborting the victim transaction.
 */

#define MERKLE_START_ALIGN			65536

/*
 * Compute the logical file offset where we cache the Merkle tree.
 *
 * @inode:  inode of the verity file
 *
 * For the purposes of caching the Merkle tree pages, as required by
 * fs-verity, it is convenient to do size computations in terms of a file
 * offset, rather than in terms of page indices.
 *
 * Use 64K to be sure it's past the last page in the file, even with 64K pages.
 * That rounding operation itself can overflow loff_t, so we do it in u64 and
 * check.
 *
 * Returns the file offset on success, negative error code on failure.
 */
static loff_t merkle_file_pos(const struct inode *inode)
{
	u64 sz = inode->i_size;
	u64 rounded = round_up(sz, MERKLE_START_ALIGN);

	if (rounded > inode->i_sb->s_maxbytes)
		return -EFBIG;

	return rounded;
}

/*
 * Drop all the items for this inode with this key_type.
 *
 * @inode:     inode to drop items for
 * @key_type:  type of items to drop (BTRFS_VERITY_DESC_ITEM or
 *             BTRFS_VERITY_MERKLE_ITEM)
 *
 * Before doing a verity enable we cleanup any existing verity items.
 * This is also used to clean up if a verity enable failed half way through.
 *
 * Returns number of dropped items on success, negative error code on failure.
 */
static int drop_verity_items(struct btrfs_inode *inode, u8 key_type)
{
	struct btrfs_trans_handle *trans;
	struct btrfs_root *root = inode->root;
	struct btrfs_path *path;
	struct btrfs_key key;
	int count = 0;
	int ret;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	while (1) {
		/* 1 for the item being dropped */
		trans = btrfs_start_transaction(root, 1);
		if (IS_ERR(trans)) {
			ret = PTR_ERR(trans);
			goto out;
		}

		/*
		 * Walk backwards through all the items until we find one that
		 * isn't from our key type or objectid
		 */
		key.objectid = btrfs_ino(inode);
		key.type = key_type;
		key.offset = (u64)-1;

		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
		if (ret > 0) {
			ret = 0;
			/* No more keys of this type, we're done */
			if (path->slots[0] == 0)
				break;
			path->slots[0]--;
		} else if (ret < 0) {
			btrfs_end_transaction(trans);
			goto out;
		}

		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);

		/* No more keys of this type, we're done */
		if (key.objectid != btrfs_ino(inode) || key.type != key_type)
			break;

		/*
		 * This shouldn't be a performance sensitive function because
		 * it's not used as part of truncate.  If it ever becomes
		 * perf sensitive, change this to walk forward and bulk delete
		 * items
		 */
		ret = btrfs_del_items(trans, root, path, path->slots[0], 1);
		if (ret) {
			btrfs_end_transaction(trans);
			goto out;
		}
		count++;
		btrfs_release_path(path);
		btrfs_end_transaction(trans);
	}
	ret = count;
	btrfs_end_transaction(trans);
out:
	btrfs_free_path(path);
	return ret;
}

/*
 * Drop all verity items
 *
 * @inode:  inode to drop verity items for
 *
 * In most contexts where we are dropping verity items, we want to do it for all
 * the types of verity items, not a particular one.
 *
 * Returns: 0 on success, negative error code on failure.
 */
int btrfs_drop_verity_items(struct btrfs_inode *inode)
{
	int ret;

	ret = drop_verity_items(inode, BTRFS_VERITY_DESC_ITEM_KEY);
	if (ret < 0)
		return ret;
	ret = drop_verity_items(inode, BTRFS_VERITY_MERKLE_ITEM_KEY);
	if (ret < 0)
		return ret;

	return 0;
}

/*
 * Insert and write inode items with a given key type and offset.
 *
 * @inode:     inode to insert for
 * @key_type:  key type to insert
 * @offset:    item offset to insert at
 * @src:       source data to write
 * @len:       length of source data to write
 *
 * Write len bytes from src into items of up to 2K length.
 * The inserted items will have key (ino, key_type, offset + off) where off is
 * consecutively increasing from 0 up to the last item ending at offset + len.
 *
 * Returns 0 on success and a negative error code on failure.
 */
static int write_key_bytes(struct btrfs_inode *inode, u8 key_type, u64 offset,
			   const char *src, u64 len)
{
	struct btrfs_trans_handle *trans;
	struct btrfs_path *path;
	struct btrfs_root *root = inode->root;
	struct extent_buffer *leaf;
	struct btrfs_key key;
	unsigned long copy_bytes;
	unsigned long src_offset = 0;
	void *data;
	int ret = 0;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	while (len > 0) {
		/* 1 for the new item being inserted */
		trans = btrfs_start_transaction(root, 1);
		if (IS_ERR(trans)) {
			ret = PTR_ERR(trans);
			break;
		}

		key.objectid = btrfs_ino(inode);
		key.type = key_type;
		key.offset = offset;

		/*
		 * Insert 2K at a time mostly to be friendly for smaller leaf
		 * size filesystems
		 */
		copy_bytes = min_t(u64, len, 2048);

		ret = btrfs_insert_empty_item(trans, root, path, &key, copy_bytes);
		if (ret) {
			btrfs_end_transaction(trans);
			break;
		}

		leaf = path->nodes[0];

		data = btrfs_item_ptr(leaf, path->slots[0], void);
		write_extent_buffer(leaf, src + src_offset,
				    (unsigned long)data, copy_bytes);
		offset += copy_bytes;
		src_offset += copy_bytes;
		len -= copy_bytes;

		btrfs_release_path(path);
		btrfs_end_transaction(trans);
	}

	btrfs_free_path(path);
	return ret;
}

/*
 * Read inode items of the given key type and offset from the btree.
 *
 * @inode:      inode to read items of
 * @key_type:   key type to read
 * @offset:     item offset to read from
 * @dest:       Buffer to read into. This parameter has slightly tricky
 *              semantics.  If it is NULL, the function will not do any copying
 *              and will just return the size of all the items up to len bytes.
 *              If dest_page is passed, then the function will kmap_local the
 *              page and ignore dest, but it must still be non-NULL to avoid the
 *              counting-only behavior.
 * @len:        length in bytes to read
 * @dest_folio: copy into this folio instead of the dest buffer
 *
 * Helper function to read items from the btree.  This returns the number of
 * bytes read or < 0 for errors.  We can return short reads if the items don't
 * exist on disk or aren't big enough to fill the desired length.  Supports
 * reading into a provided buffer (dest) or into the page cache
 *
 * Returns number of bytes read or a negative error code on failure.
 */
static int read_key_bytes(struct btrfs_inode *inode, u8 key_type, u64 offset,
			  char *dest, u64 len, struct folio *dest_folio)
{
	struct btrfs_path *path;
	struct btrfs_root *root = inode->root;
	struct extent_buffer *leaf;
	struct btrfs_key key;
	u64 item_end;
	u64 copy_end;
	int copied = 0;
	u32 copy_offset;
	unsigned long copy_bytes;
	unsigned long dest_offset = 0;
	void *data;
	char *kaddr = dest;
	int ret;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	if (dest_folio)
		path->reada = READA_FORWARD;

	key.objectid = btrfs_ino(inode);
	key.type = key_type;
	key.offset = offset;

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0) {
		goto out;
	} else if (ret > 0) {
		ret = 0;
		if (path->slots[0] == 0)
			goto out;
		path->slots[0]--;
	}

	while (len > 0) {
		leaf = path->nodes[0];
		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);

		if (key.objectid != btrfs_ino(inode) || key.type != key_type)
			break;

		item_end = btrfs_item_size(leaf, path->slots[0]) + key.offset;

		if (copied > 0) {
			/*
			 * Once we've copied something, we want all of the items
			 * to be sequential
			 */
			if (key.offset != offset)
				break;
		} else {
			/*
			 * Our initial offset might be in the middle of an
			 * item.  Make sure it all makes sense.
			 */
			if (key.offset > offset)
				break;
			if (item_end <= offset)
				break;
		}

		/* desc = NULL to just sum all the item lengths */
		if (!dest)
			copy_end = item_end;
		else
			copy_end = min(offset + len, item_end);

		/* Number of bytes in this item we want to copy */
		copy_bytes = copy_end - offset;

		/* Offset from the start of item for copying */
		copy_offset = offset - key.offset;

		if (dest) {
			if (dest_folio)
				kaddr = kmap_local_folio(dest_folio, 0);

			data = btrfs_item_ptr(leaf, path->slots[0], void);
			read_extent_buffer(leaf, kaddr + dest_offset,
					   (unsigned long)data + copy_offset,
					   copy_bytes);

			if (dest_folio)
				kunmap_local(kaddr);
		}

		offset += copy_bytes;
		dest_offset += copy_bytes;
		len -= copy_bytes;
		copied += copy_bytes;

		path->slots[0]++;
		if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
			/*
			 * We've reached the last slot in this leaf and we need
			 * to go to the next leaf.
			 */
			ret = btrfs_next_leaf(root, path);
			if (ret < 0) {
				break;
			} else if (ret > 0) {
				ret = 0;
				break;
			}
		}
	}
out:
	btrfs_free_path(path);
	if (!ret)
		ret = copied;
	return ret;
}

/*
 * Delete an fsverity orphan
 *
 * @trans:  transaction to do the delete in
 * @inode:  inode to orphan
 *
 * Capture verity orphan specific logic that is repeated in the couple places
 * we delete verity orphans. Specifically, handling ENOENT and ignoring inodes
 * with 0 links.
 *
 * Returns zero on success or a negative error code on failure.
 */
static int del_orphan(struct btrfs_trans_handle *trans, struct btrfs_inode *inode)
{
	struct btrfs_root *root = inode->root;
	int ret;

	/*
	 * If the inode has no links, it is either already unlinked, or was
	 * created with O_TMPFILE. In either case, it should have an orphan from
	 * that other operation. Rather than reference count the orphans, we
	 * simply ignore them here, because we only invoke the verity path in
	 * the orphan logic when i_nlink is 1.
	 */
	if (!inode->vfs_inode.i_nlink)
		return 0;

	ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode));
	if (ret == -ENOENT)
		ret = 0;
	return ret;
}

/*
 * Rollback in-progress verity if we encounter an error.
 *
 * @inode:  inode verity had an error for
 *
 * We try to handle recoverable errors while enabling verity by rolling it back
 * and just failing the operation, rather than having an fs level error no
 * matter what. However, any error in rollback is unrecoverable.
 *
 * Returns 0 on success, negative error code on failure.
 */
static int rollback_verity(struct btrfs_inode *inode)
{
	struct btrfs_trans_handle *trans = NULL;
	struct btrfs_root *root = inode->root;
	int ret;

	btrfs_assert_inode_locked(inode);
	truncate_inode_pages(inode->vfs_inode.i_mapping, inode->vfs_inode.i_size);
	clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
	ret = btrfs_drop_verity_items(inode);
	if (ret) {
		btrfs_handle_fs_error(root->fs_info, ret,
				"failed to drop verity items in rollback %llu",
				(u64)inode->vfs_inode.i_ino);
		goto out;
	}

	/*
	 * 1 for updating the inode flag
	 * 1 for deleting the orphan
	 */
	trans = btrfs_start_transaction(root, 2);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		trans = NULL;
		btrfs_handle_fs_error(root->fs_info, ret,
			"failed to start transaction in verity rollback %llu",
			(u64)inode->vfs_inode.i_ino);
		goto out;
	}
	inode->ro_flags &= ~BTRFS_INODE_RO_VERITY;
	btrfs_sync_inode_flags_to_i_flags(inode);
	ret = btrfs_update_inode(trans, inode);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto out;
	}
	ret = del_orphan(trans, inode);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto out;
	}
out:
	if (trans)
		btrfs_end_transaction(trans);
	return ret;
}

/*
 * Finalize making the file a valid verity file
 *
 * @inode:      inode to be marked as verity
 * @desc:       contents of the verity descriptor to write (not NULL)
 * @desc_size:  size of the verity descriptor
 *
 * Do the actual work of finalizing verity after successfully writing the Merkle
 * tree:
 *
 * - write out the descriptor items
 * - mark the inode with the verity flag
 * - delete the orphan item
 * - mark the ro compat bit
 * - clear the in progress bit
 *
 * Returns 0 on success, negative error code on failure.
 */
static int finish_verity(struct btrfs_inode *inode, const void *desc,
			 size_t desc_size)
{
	struct btrfs_trans_handle *trans = NULL;
	struct btrfs_root *root = inode->root;
	struct btrfs_verity_descriptor_item item;
	int ret;

	/* Write out the descriptor item */
	memset(&item, 0, sizeof(item));
	btrfs_set_stack_verity_descriptor_size(&item, desc_size);
	ret = write_key_bytes(inode, BTRFS_VERITY_DESC_ITEM_KEY, 0,
			      (const char *)&item, sizeof(item));
	if (ret)
		goto out;

	/* Write out the descriptor itself */
	ret = write_key_bytes(inode, BTRFS_VERITY_DESC_ITEM_KEY, 1,
			      desc, desc_size);
	if (ret)
		goto out;

	/*
	 * 1 for updating the inode flag
	 * 1 for deleting the orphan
	 */
	trans = btrfs_start_transaction(root, 2);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		goto out;
	}
	inode->ro_flags |= BTRFS_INODE_RO_VERITY;
	btrfs_sync_inode_flags_to_i_flags(inode);
	ret = btrfs_update_inode(trans, inode);
	if (ret)
		goto end_trans;
	ret = del_orphan(trans, inode);
	if (ret)
		goto end_trans;
	clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
	btrfs_set_fs_compat_ro(root->fs_info, VERITY);
end_trans:
	btrfs_end_transaction(trans);
out:
	return ret;

}

/*
 * fsverity op that begins enabling verity.
 *
 * @filp:  file to enable verity on
 *
 * Begin enabling fsverity for the file. We drop any existing verity items, add
 * an orphan and set the in progress bit.
 *
 * Returns 0 on success, negative error code on failure.
 */
static int btrfs_begin_enable_verity(struct file *filp)
{
	struct btrfs_inode *inode = BTRFS_I(file_inode(filp));
	struct btrfs_root *root = inode->root;
	struct btrfs_trans_handle *trans;
	int ret;

	btrfs_assert_inode_locked(inode);

	if (test_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags))
		return -EBUSY;

	/*
	 * This should almost never do anything, but theoretically, it's
	 * possible that we failed to enable verity on a file, then were
	 * interrupted or failed while rolling back, failed to cleanup the
	 * orphan, and finally attempt to enable verity again.
	 */
	ret = btrfs_drop_verity_items(inode);
	if (ret)
		return ret;

	/* 1 for the orphan item */
	trans = btrfs_start_transaction(root, 1);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	ret = btrfs_orphan_add(trans, inode);
	if (!ret)
		set_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
	btrfs_end_transaction(trans);

	return 0;
}

/*
 * fsverity op that ends enabling verity.
 *
 * @filp:              file we are finishing enabling verity on
 * @desc:              verity descriptor to write out (NULL in error conditions)
 * @desc_size:         size of the verity descriptor (variable with signatures)
 * @merkle_tree_size:  size of the merkle tree in bytes
 *
 * If desc is null, then VFS is signaling an error occurred during verity
 * enable, and we should try to rollback. Otherwise, attempt to finish verity.
 *
 * Returns 0 on success, negative error code on error.
 */
static int btrfs_end_enable_verity(struct file *filp, const void *desc,
				   size_t desc_size, u64 merkle_tree_size)
{
	struct btrfs_inode *inode = BTRFS_I(file_inode(filp));
	int ret = 0;
	int rollback_ret;

	btrfs_assert_inode_locked(inode);

	if (desc == NULL)
		goto rollback;

	ret = finish_verity(inode, desc, desc_size);
	if (ret)
		goto rollback;
	return ret;

rollback:
	rollback_ret = rollback_verity(inode);
	if (rollback_ret)
		btrfs_err(inode->root->fs_info,
			  "failed to rollback verity items: %d", rollback_ret);
	return ret;
}

/*
 * fsverity op that gets the struct fsverity_descriptor.
 *
 * @inode:     inode to get the descriptor of
 * @buf:       output buffer for the descriptor contents
 * @buf_size:  size of the output buffer. 0 to query the size
 *
 * fsverity does a two pass setup for reading the descriptor, in the first pass
 * it calls with buf_size = 0 to query the size of the descriptor, and then in
 * the second pass it actually reads the descriptor off disk.
 *
 * Returns the size on success or a negative error code on failure.
 */
int btrfs_get_verity_descriptor(struct inode *inode, void *buf, size_t buf_size)
{
	u64 true_size;
	int ret = 0;
	struct btrfs_verity_descriptor_item item;

	memset(&item, 0, sizeof(item));
	ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_DESC_ITEM_KEY, 0,
			     (char *)&item, sizeof(item), NULL);
	if (ret < 0)
		return ret;

	if (unlikely(item.reserved[0] != 0 || item.reserved[1] != 0))
		return -EUCLEAN;

	true_size = btrfs_stack_verity_descriptor_size(&item);
	if (unlikely(true_size > INT_MAX))
		return -EUCLEAN;

	if (buf_size == 0)
		return true_size;
	if (buf_size < true_size)
		return -ERANGE;

	ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_DESC_ITEM_KEY, 1,
			     buf, buf_size, NULL);
	if (ret < 0)
		return ret;
	if (ret != true_size)
		return -EIO;

	return true_size;
}

/*
 * fsverity op that reads and caches a merkle tree page.
 *
 * @inode:         inode to read a merkle tree page for
 * @index:         page index relative to the start of the merkle tree
 * @num_ra_pages:  number of pages to readahead. Optional, we ignore it
 *
 * The Merkle tree is stored in the filesystem btree, but its pages are cached
 * with a logical position past EOF in the inode's mapping.
 *
 * Returns the page we read, or an ERR_PTR on error.
 */
static struct page *btrfs_read_merkle_tree_page(struct inode *inode,
						pgoff_t index,
						unsigned long num_ra_pages)
{
	struct folio *folio;
	u64 off = (u64)index << PAGE_SHIFT;
	loff_t merkle_pos = merkle_file_pos(inode);
	int ret;

	if (merkle_pos < 0)
		return ERR_PTR(merkle_pos);
	if (merkle_pos > inode->i_sb->s_maxbytes - off - PAGE_SIZE)
		return ERR_PTR(-EFBIG);
	index += merkle_pos >> PAGE_SHIFT;
again:
	folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0);
	if (!IS_ERR(folio)) {
		if (folio_test_uptodate(folio))
			goto out;

		folio_lock(folio);
		/* If it's not uptodate after we have the lock, we got a read error. */
		if (!folio_test_uptodate(folio)) {
			folio_unlock(folio);
			folio_put(folio);
			return ERR_PTR(-EIO);
		}
		folio_unlock(folio);
		goto out;
	}

	folio = filemap_alloc_folio(mapping_gfp_constraint(inode->i_mapping, ~__GFP_FS),
				    0);
	if (!folio)
		return ERR_PTR(-ENOMEM);

	ret = filemap_add_folio(inode->i_mapping, folio, index, GFP_NOFS);
	if (ret) {
		folio_put(folio);
		/* Did someone else insert a folio here? */
		if (ret == -EEXIST)
			goto again;
		return ERR_PTR(ret);
	}

	/*
	 * Merkle item keys are indexed from byte 0 in the merkle tree.
	 * They have the form:
	 *
	 * [ inode objectid, BTRFS_MERKLE_ITEM_KEY, offset in bytes ]
	 */
	ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY, off,
			     folio_address(folio), PAGE_SIZE, folio);
	if (ret < 0) {
		folio_put(folio);
		return ERR_PTR(ret);
	}
	if (ret < PAGE_SIZE)
		folio_zero_segment(folio, ret, PAGE_SIZE);

	folio_mark_uptodate(folio);
	folio_unlock(folio);

out:
	return folio_file_page(folio, index);
}

/*
 * fsverity op that writes a Merkle tree block into the btree.
 *
 * @inode:	inode to write a Merkle tree block for
 * @buf:	Merkle tree block to write
 * @pos:	the position of the block in the Merkle tree (in bytes)
 * @size:	the Merkle tree block size (in bytes)
 *
 * Returns 0 on success or negative error code on failure
 */
static int btrfs_write_merkle_tree_block(struct inode *inode, const void *buf,
					 u64 pos, unsigned int size)
{
	loff_t merkle_pos = merkle_file_pos(inode);

	if (merkle_pos < 0)
		return merkle_pos;
	if (merkle_pos > inode->i_sb->s_maxbytes - pos - size)
		return -EFBIG;

	return write_key_bytes(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY,
			       pos, buf, size);
}

const struct fsverity_operations btrfs_verityops = {
	.inode_info_offs         = (int)offsetof(struct btrfs_inode, i_verity_info) -
				   (int)offsetof(struct btrfs_inode, vfs_inode),
	.begin_enable_verity     = btrfs_begin_enable_verity,
	.end_enable_verity       = btrfs_end_enable_verity,
	.get_verity_descriptor   = btrfs_get_verity_descriptor,
	.read_merkle_tree_page   = btrfs_read_merkle_tree_page,
	.write_merkle_tree_block = btrfs_write_merkle_tree_block,
};
