// SPDX-License-Identifier: GPL-2.0
/*
 * io_misc.c - fallocate, fpunch, truncate:
 */

#include "bcachefs.h"
#include "alloc_foreground.h"
#include "bkey_buf.h"
#include "btree_update.h"
#include "buckets.h"
#include "clock.h"
#include "error.h"
#include "extents.h"
#include "extent_update.h"
#include "inode.h"
#include "io_misc.h"
#include "io_write.h"
#include "logged_ops.h"
#include "rebalance.h"
#include "subvolume.h"

/* Overwrites whatever was present with zeroes: */
int bch2_extent_fallocate(struct btree_trans *trans,
			  subvol_inum inum,
			  struct btree_iter *iter,
			  u64 sectors,
			  struct bch_io_opts opts,
			  s64 *i_sectors_delta,
			  struct write_point_specifier write_point)
{
	struct bch_fs *c = trans->c;
	struct disk_reservation disk_res = { 0 };
	struct closure cl;
	struct open_buckets open_buckets = { 0 };
	struct bkey_s_c k;
	struct bkey_buf old, new;
	unsigned sectors_allocated = 0, new_replicas;
	bool unwritten = opts.nocow &&
	    c->sb.version >= bcachefs_metadata_version_unwritten_extents;
	int ret;

	bch2_bkey_buf_init(&old);
	bch2_bkey_buf_init(&new);
	closure_init_stack(&cl);

	k = bch2_btree_iter_peek_slot(trans, iter);
	ret = bkey_err(k);
	if (ret)
		return ret;

	sectors = min_t(u64, sectors, k.k->p.offset - iter->pos.offset);
	new_replicas = max(0, (int) opts.data_replicas -
			   (int) bch2_bkey_nr_ptrs_fully_allocated(k));

	/*
	 * Get a disk reservation before (in the nocow case) calling
	 * into the allocator:
	 */
	ret = bch2_disk_reservation_get(c, &disk_res, sectors, new_replicas, 0);
	if (unlikely(ret))
		goto err_noprint;

	bch2_bkey_buf_reassemble(&old, c, k);

	if (!unwritten) {
		struct bkey_i_reservation *reservation;

		bch2_bkey_buf_realloc(&new, c, sizeof(*reservation) / sizeof(u64));
		reservation = bkey_reservation_init(new.k);
		reservation->k.p = iter->pos;
		bch2_key_resize(&reservation->k, sectors);
		reservation->v.nr_replicas = opts.data_replicas;
	} else {
		struct bkey_i_extent *e;
		struct bch_devs_list devs_have;
		struct write_point *wp;

		devs_have.nr = 0;

		bch2_bkey_buf_realloc(&new, c, BKEY_EXTENT_U64s_MAX);

		e = bkey_extent_init(new.k);
		e->k.p = iter->pos;

		ret = bch2_alloc_sectors_start_trans(trans,
				opts.foreground_target,
				false,
				write_point,
				&devs_have,
				opts.data_replicas,
				opts.data_replicas,
				BCH_WATERMARK_normal, 0, &cl, &wp);
		if (bch2_err_matches(ret, BCH_ERR_operation_blocked))
			ret = bch_err_throw(c, transaction_restart_nested);
		if (ret)
			goto err;

		sectors = min_t(u64, sectors, wp->sectors_free);
		sectors_allocated = sectors;

		bch2_key_resize(&e->k, sectors);

		bch2_open_bucket_get(c, wp, &open_buckets);
		bch2_alloc_sectors_append_ptrs(c, wp, &e->k_i, sectors, false);
		bch2_alloc_sectors_done(c, wp);

		extent_for_each_ptr(extent_i_to_s(e), ptr)
			ptr->unwritten = true;
	}

	ret = bch2_extent_update(trans, inum, iter, new.k, &disk_res,
				 0, i_sectors_delta, true);
err:
	if (!ret && sectors_allocated)
		bch2_increment_clock(c, sectors_allocated, WRITE);
	if (should_print_err(ret)) {
		struct printbuf buf = PRINTBUF;
		lockrestart_do(trans,
			bch2_inum_offset_err_msg_trans(trans, &buf, inum, iter->pos.offset << 9));
		prt_printf(&buf, "fallocate error: %s", bch2_err_str(ret));
		bch_err_ratelimited(c, "%s", buf.buf);
		printbuf_exit(&buf);
	}
err_noprint:
	bch2_open_buckets_put(c, &open_buckets);
	bch2_disk_reservation_put(c, &disk_res);
	bch2_bkey_buf_exit(&new, c);
	bch2_bkey_buf_exit(&old, c);

	if (closure_nr_remaining(&cl) != 1) {
		bch2_trans_unlock_long(trans);
		bch2_wait_on_allocator(c, &cl);
	}

	return ret;
}

/* For fsck */
int bch2_fpunch_snapshot(struct btree_trans *trans, struct bpos start, struct bpos end)
{
	u32 restart_count = trans->restart_count;
	struct bch_fs *c = trans->c;
	struct disk_reservation disk_res = bch2_disk_reservation_init(c, 0);
	unsigned max_sectors	= KEY_SIZE_MAX & (~0 << c->block_bits);
	struct bkey_i delete;

	int ret = for_each_btree_key_max_commit(trans, iter, BTREE_ID_extents,
			start, end, 0, k,
			&disk_res, NULL, BCH_TRANS_COMMIT_no_enospc, ({
		bkey_init(&delete.k);
		delete.k.p = iter.pos;

		/* create the biggest key we can */
		bch2_key_resize(&delete.k, max_sectors);
		bch2_cut_back(end, &delete);

		bch2_extent_trim_atomic(trans, &iter, &delete) ?:
		bch2_trans_update(trans, &iter, &delete, 0);
	}));

	bch2_disk_reservation_put(c, &disk_res);
	return ret ?: trans_was_restarted(trans, restart_count);
}

/*
 * Returns -BCH_ERR_transacton_restart if we had to drop locks:
 */
int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
		   subvol_inum inum, u64 end,
		   s64 *i_sectors_delta)
{
	struct bch_fs *c	= trans->c;
	unsigned max_sectors	= KEY_SIZE_MAX & (~0 << c->block_bits);
	struct bpos end_pos = POS(inum.inum, end);
	struct bkey_s_c k;
	int ret = 0, ret2 = 0;
	u32 snapshot;

	while (!ret ||
	       bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
		struct disk_reservation disk_res =
			bch2_disk_reservation_init(c, 0);
		struct bkey_i delete;

		if (ret)
			ret2 = ret;

		bch2_trans_begin(trans);

		ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
		if (ret)
			continue;

		bch2_btree_iter_set_snapshot(trans, iter, snapshot);

		/*
		 * peek_max() doesn't have ideal semantics for extents:
		 */
		k = bch2_btree_iter_peek_max(trans, iter, end_pos);
		if (!k.k)
			break;

		ret = bkey_err(k);
		if (ret)
			continue;

		bkey_init(&delete.k);
		delete.k.p = iter->pos;

		/* create the biggest key we can */
		bch2_key_resize(&delete.k, max_sectors);
		bch2_cut_back(end_pos, &delete);

		ret = bch2_extent_update(trans, inum, iter, &delete,
				&disk_res, 0, i_sectors_delta, false);
		bch2_disk_reservation_put(c, &disk_res);
	}

	return ret ?: ret2;
}

int bch2_fpunch(struct bch_fs *c, subvol_inum inum, u64 start, u64 end,
		s64 *i_sectors_delta)
{
	struct btree_trans *trans = bch2_trans_get(c);
	struct btree_iter iter;
	int ret;

	bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
			     POS(inum.inum, start),
			     BTREE_ITER_intent);

	ret = bch2_fpunch_at(trans, &iter, inum, end, i_sectors_delta);

	bch2_trans_iter_exit(trans, &iter);
	bch2_trans_put(trans);

	if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
		ret = 0;

	return ret;
}

/* truncate: */

void bch2_logged_op_truncate_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
{
	struct bkey_s_c_logged_op_truncate op = bkey_s_c_to_logged_op_truncate(k);

	prt_printf(out, "subvol=%u", le32_to_cpu(op.v->subvol));
	prt_printf(out, " inum=%llu", le64_to_cpu(op.v->inum));
	prt_printf(out, " new_i_size=%llu", le64_to_cpu(op.v->new_i_size));
}

static int truncate_set_isize(struct btree_trans *trans,
			      subvol_inum inum,
			      u64 new_i_size,
			      bool warn)
{
	struct btree_iter iter = {};
	struct bch_inode_unpacked inode_u;
	int ret;

	ret   = __bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent, warn) ?:
		(inode_u.bi_size = new_i_size, 0) ?:
		bch2_inode_write(trans, &iter, &inode_u);

	bch2_trans_iter_exit(trans, &iter);
	return ret;
}

static int __bch2_resume_logged_op_truncate(struct btree_trans *trans,
					    struct bkey_i *op_k,
					    u64 *i_sectors_delta)
{
	struct bch_fs *c = trans->c;
	struct btree_iter fpunch_iter;
	struct bkey_i_logged_op_truncate *op = bkey_i_to_logged_op_truncate(op_k);
	subvol_inum inum = { le32_to_cpu(op->v.subvol), le64_to_cpu(op->v.inum) };
	u64 new_i_size = le64_to_cpu(op->v.new_i_size);
	bool warn_errors = i_sectors_delta != NULL;
	int ret;

	ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
			truncate_set_isize(trans, inum, new_i_size, i_sectors_delta != NULL));
	if (ret)
		goto err;

	bch2_trans_iter_init(trans, &fpunch_iter, BTREE_ID_extents,
			     POS(inum.inum, round_up(new_i_size, block_bytes(c)) >> 9),
			     BTREE_ITER_intent);
	ret = bch2_fpunch_at(trans, &fpunch_iter, inum, U64_MAX, i_sectors_delta);
	bch2_trans_iter_exit(trans, &fpunch_iter);

	if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
		ret = 0;
err:
	if (warn_errors)
		bch_err_fn(c, ret);
	return ret;
}

int bch2_resume_logged_op_truncate(struct btree_trans *trans, struct bkey_i *op_k)
{
	return __bch2_resume_logged_op_truncate(trans, op_k, NULL);
}

int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sectors_delta)
{
	struct bkey_i_logged_op_truncate op;

	bkey_logged_op_truncate_init(&op.k_i);
	op.v.subvol	= cpu_to_le32(inum.subvol);
	op.v.inum	= cpu_to_le64(inum.inum);
	op.v.new_i_size	= cpu_to_le64(new_i_size);

	/*
	 * Logged ops aren't atomic w.r.t. snapshot creation: creating a
	 * snapshot while they're in progress, then crashing, will result in the
	 * resume only proceeding in one of the snapshots
	 */
	down_read(&c->snapshot_create_lock);
	struct btree_trans *trans = bch2_trans_get(c);
	int ret = bch2_logged_op_start(trans, &op.k_i);
	if (ret)
		goto out;
	ret = __bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta);
	ret = bch2_logged_op_finish(trans, &op.k_i) ?: ret;
out:
	bch2_trans_put(trans);
	up_read(&c->snapshot_create_lock);

	return ret;
}

/* finsert/fcollapse: */

void bch2_logged_op_finsert_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
{
	struct bkey_s_c_logged_op_finsert op = bkey_s_c_to_logged_op_finsert(k);

	prt_printf(out, "subvol=%u",		le32_to_cpu(op.v->subvol));
	prt_printf(out, " inum=%llu",		le64_to_cpu(op.v->inum));
	prt_printf(out, " dst_offset=%lli",	le64_to_cpu(op.v->dst_offset));
	prt_printf(out, " src_offset=%llu",	le64_to_cpu(op.v->src_offset));
}

static int adjust_i_size(struct btree_trans *trans, subvol_inum inum,
			 u64 offset, s64 len, bool warn)
{
	struct btree_iter iter;
	struct bch_inode_unpacked inode_u;
	int ret;

	offset	<<= 9;
	len	<<= 9;

	ret = __bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent, warn);
	if (ret)
		return ret;

	if (len > 0) {
		if (MAX_LFS_FILESIZE - inode_u.bi_size < len) {
			ret = -EFBIG;
			goto err;
		}

		if (offset >= inode_u.bi_size) {
			ret = -EINVAL;
			goto err;
		}
	}

	inode_u.bi_size += len;
	inode_u.bi_mtime = inode_u.bi_ctime = bch2_current_time(trans->c);

	ret = bch2_inode_write(trans, &iter, &inode_u);
err:
	bch2_trans_iter_exit(trans, &iter);
	return ret;
}

static int __bch2_resume_logged_op_finsert(struct btree_trans *trans,
					   struct bkey_i *op_k,
					   u64 *i_sectors_delta)
{
	struct bch_fs *c = trans->c;
	struct btree_iter iter;
	struct bkey_i_logged_op_finsert *op = bkey_i_to_logged_op_finsert(op_k);
	subvol_inum inum = { le32_to_cpu(op->v.subvol), le64_to_cpu(op->v.inum) };
	struct bch_io_opts opts;
	u64 dst_offset = le64_to_cpu(op->v.dst_offset);
	u64 src_offset = le64_to_cpu(op->v.src_offset);
	s64 shift = dst_offset - src_offset;
	u64 len = abs(shift);
	u64 pos = le64_to_cpu(op->v.pos);
	bool insert = shift > 0;
	u32 snapshot;
	bool warn_errors = i_sectors_delta != NULL;
	int ret = 0;

	ret = bch2_inum_opts_get(trans, inum, &opts);
	if (ret)
		return ret;

	/*
	 * check for missing subvolume before fpunch, as in resume we don't want
	 * it to be a fatal error
	 */
	ret = lockrestart_do(trans, __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot, warn_errors));
	if (ret)
		return ret;

	bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
			     POS(inum.inum, 0),
			     BTREE_ITER_intent);

	switch (op->v.state) {
case LOGGED_OP_FINSERT_start:
	op->v.state = LOGGED_OP_FINSERT_shift_extents;

	if (insert) {
		ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
				adjust_i_size(trans, inum, src_offset, len, warn_errors) ?:
				bch2_logged_op_update(trans, &op->k_i));
		if (ret)
			goto err;
	} else {
		bch2_btree_iter_set_pos(trans, &iter, POS(inum.inum, src_offset));

		ret = bch2_fpunch_at(trans, &iter, inum, src_offset + len, i_sectors_delta);
		if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart))
			goto err;

		ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
				bch2_logged_op_update(trans, &op->k_i));
	}

	fallthrough;
case LOGGED_OP_FINSERT_shift_extents:
	while (1) {
		struct disk_reservation disk_res =
			bch2_disk_reservation_init(c, 0);
		struct bkey_i delete, *copy;
		struct bkey_s_c k;
		struct bpos src_pos = POS(inum.inum, src_offset);

		bch2_trans_begin(trans);

		ret = __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot,
						    warn_errors);
		if (ret)
			goto btree_err;

		bch2_btree_iter_set_snapshot(trans, &iter, snapshot);
		bch2_btree_iter_set_pos(trans, &iter, SPOS(inum.inum, pos, snapshot));

		k = insert
			? bch2_btree_iter_peek_prev_min(trans, &iter, POS(inum.inum, 0))
			: bch2_btree_iter_peek_max(trans, &iter, POS(inum.inum, U64_MAX));
		if ((ret = bkey_err(k)))
			goto btree_err;

		if (!k.k ||
		    k.k->p.inode != inum.inum ||
		    bkey_le(k.k->p, POS(inum.inum, src_offset)))
			break;

		copy = bch2_bkey_make_mut_noupdate(trans, k);
		if ((ret = PTR_ERR_OR_ZERO(copy)))
			goto btree_err;

		if (insert &&
		    bkey_lt(bkey_start_pos(k.k), src_pos)) {
			bch2_cut_front(src_pos, copy);

			/* Splitting compressed extent? */
			bch2_disk_reservation_add(c, &disk_res,
					copy->k.size *
					bch2_bkey_nr_ptrs_allocated(bkey_i_to_s_c(copy)),
					BCH_DISK_RESERVATION_NOFAIL);
		}

		bkey_init(&delete.k);
		delete.k.p = copy->k.p;
		delete.k.p.snapshot = snapshot;
		delete.k.size = copy->k.size;

		copy->k.p.offset += shift;
		copy->k.p.snapshot = snapshot;

		op->v.pos = cpu_to_le64(insert ? bkey_start_offset(&delete.k) : delete.k.p.offset);

		ret =   bch2_bkey_set_needs_rebalance(c, &opts, copy) ?:
			bch2_btree_insert_trans(trans, BTREE_ID_extents, &delete, 0) ?:
			bch2_btree_insert_trans(trans, BTREE_ID_extents, copy, 0) ?:
			bch2_logged_op_update(trans, &op->k_i) ?:
			bch2_trans_commit(trans, &disk_res, NULL, BCH_TRANS_COMMIT_no_enospc);
btree_err:
		bch2_disk_reservation_put(c, &disk_res);

		if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
			continue;
		if (ret)
			goto err;

		pos = le64_to_cpu(op->v.pos);
	}

	op->v.state = LOGGED_OP_FINSERT_finish;

	if (!insert) {
		ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
				adjust_i_size(trans, inum, src_offset, shift, warn_errors) ?:
				bch2_logged_op_update(trans, &op->k_i));
	} else {
		/* We need an inode update to update bi_journal_seq for fsync: */
		ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
				adjust_i_size(trans, inum, 0, 0, warn_errors) ?:
				bch2_logged_op_update(trans, &op->k_i));
	}

	break;
case LOGGED_OP_FINSERT_finish:
	break;
	}
err:
	bch2_trans_iter_exit(trans, &iter);
	if (warn_errors)
		bch_err_fn(c, ret);
	return ret;
}

int bch2_resume_logged_op_finsert(struct btree_trans *trans, struct bkey_i *op_k)
{
	return __bch2_resume_logged_op_finsert(trans, op_k, NULL);
}

int bch2_fcollapse_finsert(struct bch_fs *c, subvol_inum inum,
			   u64 offset, u64 len, bool insert,
			   s64 *i_sectors_delta)
{
	struct bkey_i_logged_op_finsert op;
	s64 shift = insert ? len : -len;

	bkey_logged_op_finsert_init(&op.k_i);
	op.v.subvol	= cpu_to_le32(inum.subvol);
	op.v.inum	= cpu_to_le64(inum.inum);
	op.v.dst_offset	= cpu_to_le64(offset + shift);
	op.v.src_offset	= cpu_to_le64(offset);
	op.v.pos	= cpu_to_le64(insert ? U64_MAX : offset);

	/*
	 * Logged ops aren't atomic w.r.t. snapshot creation: creating a
	 * snapshot while they're in progress, then crashing, will result in the
	 * resume only proceeding in one of the snapshots
	 */
	down_read(&c->snapshot_create_lock);
	struct btree_trans *trans = bch2_trans_get(c);
	int ret = bch2_logged_op_start(trans, &op.k_i);
	if (ret)
		goto out;
	ret = __bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta);
	ret = bch2_logged_op_finish(trans, &op.k_i) ?: ret;
out:
	bch2_trans_put(trans);
	up_read(&c->snapshot_create_lock);

	return ret;
}
