// SPDX-License-Identifier: GPL-2.0

#include "messages.h"
#include "ctree.h"
#include "delalloc-space.h"
#include "block-rsv.h"
#include "btrfs_inode.h"
#include "space-info.h"
#include "transaction.h"
#include "qgroup.h"
#include "block-group.h"
#include "fs.h"

/*
 * HOW DOES THIS WORK
 *
 * There are two stages to data reservations, one for data and one for metadata
 * to handle the new extents and checksums generated by writing data.
 *
 *
 * DATA RESERVATION
 *   The general flow of the data reservation is as follows
 *
 *   -> Reserve
 *     We call into btrfs_reserve_data_bytes() for the user request bytes that
 *     they wish to write.  We make this reservation and add it to
 *     space_info->bytes_may_use.  We set EXTENT_DELALLOC on the inode io_tree
 *     for the range and carry on if this is buffered, or follow up trying to
 *     make a real allocation if we are pre-allocating or doing O_DIRECT.
 *
 *   -> Use
 *     At writepages()/prealloc/O_DIRECT time we will call into
 *     btrfs_reserve_extent() for some part or all of this range of bytes.  We
 *     will make the allocation and subtract space_info->bytes_may_use by the
 *     original requested length and increase the space_info->bytes_reserved by
 *     the allocated length.  This distinction is important because compression
 *     may allocate a smaller on disk extent than we previously reserved.
 *
 *   -> Allocation
 *     finish_ordered_io() will insert the new file extent item for this range,
 *     and then add a delayed ref update for the extent tree.  Once that delayed
 *     ref is written the extent size is subtracted from
 *     space_info->bytes_reserved and added to space_info->bytes_used.
 *
 *   Error handling
 *
 *   -> By the reservation maker
 *     This is the simplest case, we haven't completed our operation and we know
 *     how much we reserved, we can simply call
 *     btrfs_free_reserved_data_space*() and it will be removed from
 *     space_info->bytes_may_use.
 *
 *   -> After the reservation has been made, but before cow_file_range()
 *     This is specifically for the delalloc case.  You must clear
 *     EXTENT_DELALLOC with the EXTENT_CLEAR_DATA_RESV bit, and the range will
 *     be subtracted from space_info->bytes_may_use.
 *
 * METADATA RESERVATION
 *   The general metadata reservation lifetimes are discussed elsewhere, this
 *   will just focus on how it is used for delalloc space.
 *
 *   We keep track of two things on a per inode bases
 *
 *   ->outstanding_extents
 *     This is the number of file extent items we'll need to handle all of the
 *     outstanding DELALLOC space we have in this inode.  We limit the maximum
 *     size of an extent, so a large contiguous dirty area may require more than
 *     one outstanding_extent, which is why count_max_extents() is used to
 *     determine how many outstanding_extents get added.
 *
 *   ->csum_bytes
 *     This is essentially how many dirty bytes we have for this inode, so we
 *     can calculate the number of checksum items we would have to add in order
 *     to checksum our outstanding data.
 *
 *   We keep a per-inode block_rsv in order to make it easier to keep track of
 *   our reservation.  We use btrfs_calculate_inode_block_rsv_size() to
 *   calculate the current theoretical maximum reservation we would need for the
 *   metadata for this inode.  We call this and then adjust our reservation as
 *   necessary, either by attempting to reserve more space, or freeing up excess
 *   space.
 *
 * OUTSTANDING_EXTENTS HANDLING
 *
 *  ->outstanding_extents is used for keeping track of how many extents we will
 *  need to use for this inode, and it will fluctuate depending on where you are
 *  in the life cycle of the dirty data.  Consider the following normal case for
 *  a completely clean inode, with a num_bytes < our maximum allowed extent size
 *
 *  -> reserve
 *    ->outstanding_extents += 1 (current value is 1)
 *
 *  -> set_delalloc
 *    ->outstanding_extents += 1 (current value is 2)
 *
 *  -> btrfs_delalloc_release_extents()
 *    ->outstanding_extents -= 1 (current value is 1)
 *
 *    We must call this once we are done, as we hold our reservation for the
 *    duration of our operation, and then assume set_delalloc will update the
 *    counter appropriately.
 *
 *  -> add ordered extent
 *    ->outstanding_extents += 1 (current value is 2)
 *
 *  -> btrfs_clear_delalloc_extent
 *    ->outstanding_extents -= 1 (current value is 1)
 *
 *  -> finish_ordered_io/btrfs_remove_ordered_extent
 *    ->outstanding_extents -= 1 (current value is 0)
 *
 *  Each stage is responsible for their own accounting of the extent, thus
 *  making error handling and cleanup easier.
 */

int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes)
{
	struct btrfs_root *root = inode->root;
	struct btrfs_fs_info *fs_info = root->fs_info;
	enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_DATA;

	/* Make sure bytes are sectorsize aligned */
	bytes = ALIGN(bytes, fs_info->sectorsize);

	if (btrfs_is_free_space_inode(inode))
		flush = BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE;

	return btrfs_reserve_data_bytes(fs_info, bytes, flush);
}

int btrfs_check_data_free_space(struct btrfs_inode *inode,
				struct extent_changeset **reserved, u64 start,
				u64 len, bool noflush)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_DATA;
	int ret;

	/* align the range */
	len = round_up(start + len, fs_info->sectorsize) -
	      round_down(start, fs_info->sectorsize);
	start = round_down(start, fs_info->sectorsize);

	if (noflush)
		flush = BTRFS_RESERVE_NO_FLUSH;
	else if (btrfs_is_free_space_inode(inode))
		flush = BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE;

	ret = btrfs_reserve_data_bytes(fs_info, len, flush);
	if (ret < 0)
		return ret;

	/* Use new btrfs_qgroup_reserve_data to reserve precious data space. */
	ret = btrfs_qgroup_reserve_data(inode, reserved, start, len);
	if (ret < 0) {
		btrfs_free_reserved_data_space_noquota(fs_info, len);
		extent_changeset_free(*reserved);
		*reserved = NULL;
	} else {
		ret = 0;
	}
	return ret;
}

/*
 * Called if we need to clear a data reservation for this inode
 * Normally in a error case.
 *
 * This one will *NOT* use accurate qgroup reserved space API, just for case
 * which we can't sleep and is sure it won't affect qgroup reserved space.
 * Like clear_bit_hook().
 */
void btrfs_free_reserved_data_space_noquota(struct btrfs_fs_info *fs_info,
					    u64 len)
{
	struct btrfs_space_info *data_sinfo;

	ASSERT(IS_ALIGNED(len, fs_info->sectorsize));

	data_sinfo = fs_info->data_sinfo;
	btrfs_space_info_free_bytes_may_use(fs_info, data_sinfo, len);
}

/*
 * Called if we need to clear a data reservation for this inode
 * Normally in a error case.
 *
 * This one will handle the per-inode data rsv map for accurate reserved
 * space framework.
 */
void btrfs_free_reserved_data_space(struct btrfs_inode *inode,
			struct extent_changeset *reserved, u64 start, u64 len)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;

	/* Make sure the range is aligned to sectorsize */
	len = round_up(start + len, fs_info->sectorsize) -
	      round_down(start, fs_info->sectorsize);
	start = round_down(start, fs_info->sectorsize);

	btrfs_free_reserved_data_space_noquota(fs_info, len);
	btrfs_qgroup_free_data(inode, reserved, start, len, NULL);
}

/*
 * Release any excessive reservations for an inode.
 *
 * @inode:       the inode we need to release from
 * @qgroup_free: free or convert qgroup meta. Unlike normal operation, qgroup
 *               meta reservation needs to know if we are freeing qgroup
 *               reservation or just converting it into per-trans.  Normally
 *               @qgroup_free is true for error handling, and false for normal
 *               release.
 *
 * This is the same as btrfs_block_rsv_release, except that it handles the
 * tracepoint for the reservation.
 */
static void btrfs_inode_rsv_release(struct btrfs_inode *inode, bool qgroup_free)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
	u64 released = 0;
	u64 qgroup_to_release = 0;

	/*
	 * Since we statically set the block_rsv->size we just want to say we
	 * are releasing 0 bytes, and then we'll just get the reservation over
	 * the size free'd.
	 */
	released = btrfs_block_rsv_release(fs_info, block_rsv, 0,
					   &qgroup_to_release);
	if (released > 0)
		trace_btrfs_space_reservation(fs_info, "delalloc",
					      btrfs_ino(inode), released, 0);
	if (qgroup_free)
		btrfs_qgroup_free_meta_prealloc(inode->root, qgroup_to_release);
	else
		btrfs_qgroup_convert_reserved_meta(inode->root,
						   qgroup_to_release);
}

static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
						 struct btrfs_inode *inode)
{
	struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
	u64 reserve_size = 0;
	u64 qgroup_rsv_size = 0;
	unsigned outstanding_extents;

	lockdep_assert_held(&inode->lock);
	outstanding_extents = inode->outstanding_extents;

	/*
	 * Insert size for the number of outstanding extents, 1 normal size for
	 * updating the inode.
	 */
	if (outstanding_extents) {
		reserve_size = btrfs_calc_insert_metadata_size(fs_info,
						outstanding_extents);
		reserve_size += btrfs_calc_metadata_size(fs_info, 1);
	}
	if (!(inode->flags & BTRFS_INODE_NODATASUM)) {
		u64 csum_leaves;

		csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, inode->csum_bytes);
		reserve_size += btrfs_calc_insert_metadata_size(fs_info, csum_leaves);
	}
	/*
	 * For qgroup rsv, the calculation is very simple:
	 * account one nodesize for each outstanding extent
	 *
	 * This is overestimating in most cases.
	 */
	qgroup_rsv_size = (u64)outstanding_extents * fs_info->nodesize;

	spin_lock(&block_rsv->lock);
	block_rsv->size = reserve_size;
	block_rsv->qgroup_rsv_size = qgroup_rsv_size;
	spin_unlock(&block_rsv->lock);
}

static void calc_inode_reservations(struct btrfs_inode *inode,
				    u64 num_bytes, u64 disk_num_bytes,
				    u64 *meta_reserve, u64 *qgroup_reserve)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	u64 nr_extents = count_max_extents(fs_info, num_bytes);
	u64 csum_leaves;
	u64 inode_update = btrfs_calc_metadata_size(fs_info, 1);

	if (inode->flags & BTRFS_INODE_NODATASUM)
		csum_leaves = 0;
	else
		csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes);

	*meta_reserve = btrfs_calc_insert_metadata_size(fs_info,
						nr_extents + csum_leaves);

	/*
	 * finish_ordered_io has to update the inode, so add the space required
	 * for an inode update.
	 */
	*meta_reserve += inode_update;
	*qgroup_reserve = nr_extents * fs_info->nodesize;
}

int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
				    u64 disk_num_bytes, bool noflush)
{
	struct btrfs_root *root = inode->root;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
	u64 meta_reserve, qgroup_reserve;
	unsigned nr_extents;
	enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL;
	int ret = 0;

	/*
	 * If we are a free space inode we need to not flush since we will be in
	 * the middle of a transaction commit.  We also don't need the delalloc
	 * mutex since we won't race with anybody.  We need this mostly to make
	 * lockdep shut its filthy mouth.
	 *
	 * If we have a transaction open (can happen if we call truncate_block
	 * from truncate), then we need FLUSH_LIMIT so we don't deadlock.
	 */
	if (noflush || btrfs_is_free_space_inode(inode)) {
		flush = BTRFS_RESERVE_NO_FLUSH;
	} else {
		if (current->journal_info)
			flush = BTRFS_RESERVE_FLUSH_LIMIT;
	}

	num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
	disk_num_bytes = ALIGN(disk_num_bytes, fs_info->sectorsize);

	/*
	 * We always want to do it this way, every other way is wrong and ends
	 * in tears.  Pre-reserving the amount we are going to add will always
	 * be the right way, because otherwise if we have enough parallelism we
	 * could end up with thousands of inodes all holding little bits of
	 * reservations they were able to make previously and the only way to
	 * reclaim that space is to ENOSPC out the operations and clear
	 * everything out and try again, which is bad.  This way we just
	 * over-reserve slightly, and clean up the mess when we are done.
	 */
	calc_inode_reservations(inode, num_bytes, disk_num_bytes,
				&meta_reserve, &qgroup_reserve);
	ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true,
						 noflush);
	if (ret)
		return ret;
	ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv->space_info,
					   meta_reserve, flush);
	if (ret) {
		btrfs_qgroup_free_meta_prealloc(root, qgroup_reserve);
		return ret;
	}

	/*
	 * Now we need to update our outstanding extents and csum bytes _first_
	 * and then add the reservation to the block_rsv.  This keeps us from
	 * racing with an ordered completion or some such that would think it
	 * needs to free the reservation we just made.
	 */
	nr_extents = count_max_extents(fs_info, num_bytes);
	spin_lock(&inode->lock);
	btrfs_mod_outstanding_extents(inode, nr_extents);
	if (!(inode->flags & BTRFS_INODE_NODATASUM))
		inode->csum_bytes += disk_num_bytes;
	btrfs_calculate_inode_block_rsv_size(fs_info, inode);
	spin_unlock(&inode->lock);

	/* Now we can safely add our space to our block rsv */
	btrfs_block_rsv_add_bytes(block_rsv, meta_reserve, false);
	trace_btrfs_space_reservation(root->fs_info, "delalloc",
				      btrfs_ino(inode), meta_reserve, 1);

	spin_lock(&block_rsv->lock);
	block_rsv->qgroup_rsv_reserved += qgroup_reserve;
	spin_unlock(&block_rsv->lock);

	return 0;
}

/*
 * Release a metadata reservation for an inode.
 *
 * @inode:        the inode to release the reservation for.
 * @num_bytes:    the number of bytes we are releasing.
 * @qgroup_free:  free qgroup reservation or convert it to per-trans reservation
 *
 * This will release the metadata reservation for an inode.  This can be called
 * once we complete IO for a given set of bytes to release their metadata
 * reservations, or on error for the same reason.
 */
void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes,
				     bool qgroup_free)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;

	num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
	spin_lock(&inode->lock);
	if (!(inode->flags & BTRFS_INODE_NODATASUM))
		inode->csum_bytes -= num_bytes;
	btrfs_calculate_inode_block_rsv_size(fs_info, inode);
	spin_unlock(&inode->lock);

	if (btrfs_is_testing(fs_info))
		return;

	btrfs_inode_rsv_release(inode, qgroup_free);
}

/*
 * Release our outstanding_extents for an inode.
 *
 * @inode:      the inode to balance the reservation for.
 * @num_bytes:  the number of bytes we originally reserved with
 *
 * When we reserve space we increase outstanding_extents for the extents we may
 * add.  Once we've set the range as delalloc or created our ordered extents we
 * have outstanding_extents to track the real usage, so we use this to free our
 * temporarily tracked outstanding_extents.  This _must_ be used in conjunction
 * with btrfs_delalloc_reserve_metadata.
 */
void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	unsigned num_extents;

	spin_lock(&inode->lock);
	num_extents = count_max_extents(fs_info, num_bytes);
	btrfs_mod_outstanding_extents(inode, -num_extents);
	btrfs_calculate_inode_block_rsv_size(fs_info, inode);
	spin_unlock(&inode->lock);

	if (btrfs_is_testing(fs_info))
		return;

	btrfs_inode_rsv_release(inode, true);
}

/*
 * Reserve data and metadata space for delalloc
 *
 * @inode:     inode we're writing to
 * @start:     start range we are writing to
 * @len:       how long the range we are writing to
 * @reserved:  mandatory parameter, record actually reserved qgroup ranges of
 * 	       current reservation.
 *
 * This will do the following things
 *
 * - reserve space in data space info for num bytes and reserve precious
 *   corresponding qgroup space
 *   (Done in check_data_free_space)
 *
 * - reserve space for metadata space, based on the number of outstanding
 *   extents and how much csums will be needed also reserve metadata space in a
 *   per root over-reserve method.
 * - add to the inodes->delalloc_bytes
 * - add it to the fs_info's delalloc inodes list.
 *   (Above 3 all done in delalloc_reserve_metadata)
 *
 * Return 0 for success
 * Return <0 for error(-ENOSPC or -EDQUOT)
 */
int btrfs_delalloc_reserve_space(struct btrfs_inode *inode,
			struct extent_changeset **reserved, u64 start, u64 len)
{
	int ret;

	ret = btrfs_check_data_free_space(inode, reserved, start, len, false);
	if (ret < 0)
		return ret;
	ret = btrfs_delalloc_reserve_metadata(inode, len, len, false);
	if (ret < 0) {
		btrfs_free_reserved_data_space(inode, *reserved, start, len);
		extent_changeset_free(*reserved);
		*reserved = NULL;
	}
	return ret;
}

/*
 * Release data and metadata space for delalloc
 *
 * @inode:       inode we're releasing space for
 * @reserved:    list of changed/reserved ranges
 * @start:       start position of the space already reserved
 * @len:         length of the space already reserved
 * @qgroup_free: should qgroup reserved-space also be freed
 *
 * Release the metadata space that was not used and will decrement
 * ->delalloc_bytes and remove it from the fs_info->delalloc_inodes list if
 * there are no delalloc bytes left.  Also it will handle the qgroup reserved
 * space.
 */
void btrfs_delalloc_release_space(struct btrfs_inode *inode,
				  struct extent_changeset *reserved,
				  u64 start, u64 len, bool qgroup_free)
{
	btrfs_delalloc_release_metadata(inode, len, qgroup_free);
	btrfs_free_reserved_data_space(inode, reserved, start, len);
}
