// SPDX-License-Identifier: GPL-2.0-only

#include "dev.h"
#include "sysctl.h"
#include "fuse_dev_i.h"
#include "dev_uring_i.h"

/* Frequency (in seconds) of request timeout checks, if opted into */
#define FUSE_TIMEOUT_TIMER_FREQ 15

/* Frequency (in jiffies) of request timeout checks, if opted into */
static const unsigned long fuse_timeout_timer_freq =
	secs_to_jiffies(FUSE_TIMEOUT_TIMER_FREQ);

/*
 * Default timeout (in seconds) for the server to reply to a request
 * before the connection is aborted, if no timeout was specified on mount.
 *
 * Exported via sysctl
 */
unsigned int fuse_default_req_timeout;

/*
 * Max timeout (in seconds) for the server to reply to a request before
 * the connection is aborted.
 *
 * Exported via sysctl
 */
unsigned int fuse_max_req_timeout;

bool fuse_request_expired(struct fuse_chan *fch, struct list_head *list)
{
	struct fuse_req *req;

	req = list_first_entry_or_null(list, struct fuse_req, list);
	if (!req)
		return false;
	return time_is_before_jiffies(req->create_time + fch->timeout.req_timeout);
}

static bool fuse_fpq_processing_expired(struct fuse_chan *fch, struct list_head *processing)
{
	int i;

	for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
		if (fuse_request_expired(fch, &processing[i]))
			return true;

	return false;
}

/*
 * Check if any requests aren't being completed by the time the request timeout
 * elapses. To do so, we:
 * - check the fiq pending list
 * - check the bg queue
 * - check the fpq io and processing lists
 *
 * To make this fast, we only check against the head request on each list since
 * these are generally queued in order of creation time (eg newer requests get
 * queued to the tail). We might miss a few edge cases (eg requests transitioning
 * between lists, re-sent requests at the head of the pending list having a
 * later creation time than other requests on that list, etc.) but that is fine
 * since if the request never gets fulfilled, it will eventually be caught.
 */
static void fuse_check_timeout(struct work_struct *work)
{
	struct delayed_work *dwork = to_delayed_work(work);
	struct fuse_chan *fch = container_of(dwork, struct fuse_chan, timeout.work);
	struct fuse_iqueue *fiq = &fch->iq;
	struct fuse_dev *fud;
	struct fuse_pqueue *fpq;
	bool expired = false;

	if (!atomic_read(&fch->num_waiting))
		goto out;

	spin_lock(&fiq->lock);
	expired = fuse_request_expired(fch, &fiq->pending);
	spin_unlock(&fiq->lock);
	if (expired)
		goto chan_abort;

	spin_lock(&fch->bg_lock);
	expired = fuse_request_expired(fch, &fch->bg_queue);
	spin_unlock(&fch->bg_lock);
	if (expired)
		goto chan_abort;

	spin_lock(&fch->lock);
	if (!fch->connected) {
		spin_unlock(&fch->lock);
		return;
	}
	list_for_each_entry(fud, &fch->devices, entry) {
		fpq = &fud->pq;
		spin_lock(&fpq->lock);
		if (fuse_request_expired(fch, &fpq->io) ||
		    fuse_fpq_processing_expired(fch, fpq->processing)) {
			spin_unlock(&fpq->lock);
			spin_unlock(&fch->lock);
			goto chan_abort;
		}

		spin_unlock(&fpq->lock);
	}
	spin_unlock(&fch->lock);

	if (fuse_uring_request_expired(fch))
		goto chan_abort;

out:
	queue_delayed_work(system_percpu_wq, &fch->timeout.work,
			   fuse_timeout_timer_freq);
	return;

chan_abort:
	fuse_chan_abort(fch, false);
}

static void set_request_timeout(struct fuse_chan *fch, unsigned int timeout)
{
	fch->timeout.req_timeout = secs_to_jiffies(timeout);
	INIT_DELAYED_WORK(&fch->timeout.work, fuse_check_timeout);
	queue_delayed_work(system_percpu_wq, &fch->timeout.work,
			   fuse_timeout_timer_freq);
}

void fuse_init_server_timeout(struct fuse_chan *fch, unsigned int timeout)
{
	if (!timeout)
		timeout = fuse_default_req_timeout;

	timeout = min_not_zero(timeout, fuse_max_req_timeout);
	if (!timeout)
		return;

	timeout = max(FUSE_TIMEOUT_TIMER_FREQ, timeout);

	set_request_timeout(fch, timeout);
}

