// SPDX-License-Identifier: GPL-2.0
/*
 * I/O and data path helper functionality.
 *
 * Borrowed from NFS Copyright (c) 2016 Trond Myklebust
 */

#include <linux/kernel.h>
#include <linux/netfs.h>
#include "internal.h"

/*
 * inode_dio_wait_interruptible - wait for outstanding DIO requests to finish
 * @inode: inode to wait for
 *
 * Waits for all pending direct I/O requests to finish so that we can
 * proceed with a truncate or equivalent operation.
 *
 * Must be called under a lock that serializes taking new references
 * to i_dio_count, usually by inode->i_mutex.
 */
static int netfs_inode_dio_wait_interruptible(struct inode *inode)
{
	if (inode_dio_finished(inode))
		return 0;

	inode_dio_wait_interruptible(inode);
	return !inode_dio_finished(inode) ? -ERESTARTSYS : 0;
}

/* Call with exclusively locked inode->i_rwsem */
static int netfs_block_o_direct(struct netfs_inode *ictx)
{
	if (!test_bit(NETFS_ICTX_ODIRECT, &ictx->flags))
		return 0;
	clear_bit(NETFS_ICTX_ODIRECT, &ictx->flags);
	return netfs_inode_dio_wait_interruptible(&ictx->inode);
}

/**
 * netfs_start_io_read - declare the file is being used for buffered reads
 * @inode: file inode
 *
 * Declare that a buffered read operation is about to start, and ensure
 * that we block all direct I/O.
 * On exit, the function ensures that the NETFS_ICTX_ODIRECT flag is unset,
 * and holds a shared lock on inode->i_rwsem to ensure that the flag
 * cannot be changed.
 * In practice, this means that buffered read operations are allowed to
 * execute in parallel, thanks to the shared lock, whereas direct I/O
 * operations need to wait to grab an exclusive lock in order to set
 * NETFS_ICTX_ODIRECT.
 * Note that buffered writes and truncates both take a write lock on
 * inode->i_rwsem, meaning that those are serialised w.r.t. the reads.
 */
int netfs_start_io_read(struct inode *inode)
	__acquires(inode->i_rwsem)
{
	struct netfs_inode *ictx = netfs_inode(inode);

	/* Be an optimist! */
	if (down_read_interruptible(&inode->i_rwsem) < 0)
		return -ERESTARTSYS;
	if (test_bit(NETFS_ICTX_ODIRECT, &ictx->flags) == 0)
		return 0;
	up_read(&inode->i_rwsem);

	/* Slow path.... */
	if (down_write_killable(&inode->i_rwsem) < 0)
		return -ERESTARTSYS;
	if (netfs_block_o_direct(ictx) < 0) {
		up_write(&inode->i_rwsem);
		return -ERESTARTSYS;
	}
	downgrade_write(&inode->i_rwsem);
	return 0;
}
EXPORT_SYMBOL(netfs_start_io_read);

/**
 * netfs_end_io_read - declare that the buffered read operation is done
 * @inode: file inode
 *
 * Declare that a buffered read operation is done, and release the shared
 * lock on inode->i_rwsem.
 */
void netfs_end_io_read(struct inode *inode)
	__releases(inode->i_rwsem)
{
	up_read(&inode->i_rwsem);
}
EXPORT_SYMBOL(netfs_end_io_read);

/**
 * netfs_start_io_write - declare the file is being used for buffered writes
 * @inode: file inode
 *
 * Declare that a buffered read operation is about to start, and ensure
 * that we block all direct I/O.
 */
int netfs_start_io_write(struct inode *inode)
	__acquires(inode->i_rwsem)
{
	struct netfs_inode *ictx = netfs_inode(inode);

	if (down_write_killable(&inode->i_rwsem) < 0)
		return -ERESTARTSYS;
	if (netfs_block_o_direct(ictx) < 0) {
		up_write(&inode->i_rwsem);
		return -ERESTARTSYS;
	}
	downgrade_write(&inode->i_rwsem);
	return 0;
}
EXPORT_SYMBOL(netfs_start_io_write);

/**
 * netfs_end_io_write - declare that the buffered write operation is done
 * @inode: file inode
 *
 * Declare that a buffered write operation is done, and release the
 * lock on inode->i_rwsem.
 */
void netfs_end_io_write(struct inode *inode)
	__releases(inode->i_rwsem)
{
	up_read(&inode->i_rwsem);
}
EXPORT_SYMBOL(netfs_end_io_write);

/* Call with exclusively locked inode->i_rwsem */
static int netfs_block_buffered(struct inode *inode)
{
	struct netfs_inode *ictx = netfs_inode(inode);
	int ret;

	if (!test_bit(NETFS_ICTX_ODIRECT, &ictx->flags)) {
		set_bit(NETFS_ICTX_ODIRECT, &ictx->flags);
		if (inode->i_mapping->nrpages != 0) {
			unmap_mapping_range(inode->i_mapping, 0, 0, 0);
			ret = filemap_fdatawait(inode->i_mapping);
			if (ret < 0) {
				clear_bit(NETFS_ICTX_ODIRECT, &ictx->flags);
				return ret;
			}
		}
	}
	return 0;
}

/**
 * netfs_start_io_direct - declare the file is being used for direct i/o
 * @inode: file inode
 *
 * Declare that a direct I/O operation is about to start, and ensure
 * that we block all buffered I/O.
 * On exit, the function ensures that the NETFS_ICTX_ODIRECT flag is set,
 * and holds a shared lock on inode->i_rwsem to ensure that the flag
 * cannot be changed.
 * In practice, this means that direct I/O operations are allowed to
 * execute in parallel, thanks to the shared lock, whereas buffered I/O
 * operations need to wait to grab an exclusive lock in order to clear
 * NETFS_ICTX_ODIRECT.
 * Note that buffered writes and truncates both take a write lock on
 * inode->i_rwsem, meaning that those are serialised w.r.t. O_DIRECT.
 */
int netfs_start_io_direct(struct inode *inode)
	__acquires(inode->i_rwsem)
{
	struct netfs_inode *ictx = netfs_inode(inode);
	int ret;

	/* Be an optimist! */
	if (down_read_interruptible(&inode->i_rwsem) < 0)
		return -ERESTARTSYS;
	if (test_bit(NETFS_ICTX_ODIRECT, &ictx->flags) != 0)
		return 0;
	up_read(&inode->i_rwsem);

	/* Slow path.... */
	if (down_write_killable(&inode->i_rwsem) < 0)
		return -ERESTARTSYS;
	ret = netfs_block_buffered(inode);
	if (ret < 0) {
		up_write(&inode->i_rwsem);
		return ret;
	}
	downgrade_write(&inode->i_rwsem);
	return 0;
}
EXPORT_SYMBOL(netfs_start_io_direct);

/**
 * netfs_end_io_direct - declare that the direct i/o operation is done
 * @inode: file inode
 *
 * Declare that a direct I/O operation is done, and release the shared
 * lock on inode->i_rwsem.
 */
void netfs_end_io_direct(struct inode *inode)
	__releases(inode->i_rwsem)
{
	up_read(&inode->i_rwsem);
}
EXPORT_SYMBOL(netfs_end_io_direct);
