// SPDX-License-Identifier: GPL-2.0-or-later
/* Network filesystem high-level buffered read support.
 *
 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/export.h>
#include <linux/task_io_accounting_ops.h>
#include "internal.h"

static void netfs_cache_expand_readahead(struct netfs_io_request *rreq,
					 unsigned long long *_start,
					 unsigned long long *_len,
					 unsigned long long i_size)
{
	struct netfs_cache_resources *cres = &rreq->cache_resources;

	if (cres->ops && cres->ops->expand_readahead)
		cres->ops->expand_readahead(cres, _start, _len, i_size);
}

static void netfs_rreq_expand(struct netfs_io_request *rreq,
			      struct readahead_control *ractl)
{
	/* Give the cache a chance to change the request parameters.  The
	 * resultant request must contain the original region.
	 */
	netfs_cache_expand_readahead(rreq, &rreq->start, &rreq->len, rreq->i_size);

	/* Give the netfs a chance to change the request parameters.  The
	 * resultant request must contain the original region.
	 */
	if (rreq->netfs_ops->expand_readahead)
		rreq->netfs_ops->expand_readahead(rreq);

	/* Expand the request if the cache wants it to start earlier.  Note
	 * that the expansion may get further extended if the VM wishes to
	 * insert THPs and the preferred start and/or end wind up in the middle
	 * of THPs.
	 *
	 * If this is the case, however, the THP size should be an integer
	 * multiple of the cache granule size, so we get a whole number of
	 * granules to deal with.
	 */
	if (rreq->start  != readahead_pos(ractl) ||
	    rreq->len != readahead_length(ractl)) {
		readahead_expand(ractl, rreq->start, rreq->len);
		rreq->start  = readahead_pos(ractl);
		rreq->len = readahead_length(ractl);

		trace_netfs_read(rreq, readahead_pos(ractl), readahead_length(ractl),
				 netfs_read_trace_expanded);
	}
}

/*
 * Drop the folio refs acquired from the readahead API.
 */
static void netfs_bulk_drop_ra_refs(struct netfs_io_request *rreq)
{
	struct folio_batch fbatch;
	struct folio *folio;
	pgoff_t nr_pages = DIV_ROUND_UP(rreq->len, PAGE_SIZE);
	pgoff_t first = rreq->start / PAGE_SIZE;
	XA_STATE(xas, &rreq->mapping->i_pages, first);

	folio_batch_init(&fbatch);

	rcu_read_lock();

	xas_for_each(&xas, folio,  first + nr_pages - 1) {
		if (xas_retry(&xas, folio))
			continue;

		if (!folio_batch_add(&fbatch, folio))
			folio_batch_release(&fbatch);
	}

	rcu_read_unlock();
	folio_batch_release(&fbatch);
	trace_netfs_rreq(rreq, netfs_rreq_trace_ra_put_ref);
	clear_bit_unlock(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags);
	wake_up(&rreq->waitq);
}

static void netfs_maybe_bulk_drop_ra_refs(struct netfs_io_request *rreq)
{
	if (test_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags))
		netfs_bulk_drop_ra_refs(rreq);
}

/*
 * Begin an operation, and fetch the stored zero point value from the cookie if
 * available.
 */
static int netfs_begin_cache_read(struct netfs_io_request *rreq, struct netfs_inode *ctx)
{
	return fscache_begin_read_operation(&rreq->cache_resources, netfs_i_cookie(ctx));
}

/*
 * netfs_prepare_read_iterator - Prepare the subreq iterator for I/O
 * @subreq: The subrequest to be set up
 *
 * Prepare the I/O iterator representing the read buffer on a subrequest for
 * the filesystem to use for I/O (it can be passed directly to a socket).  This
 * is intended to be called from the ->issue_read() method once the filesystem
 * has trimmed the request to the size it wants.
 *
 * Returns the limited size if successful and -ENOMEM if insufficient memory
 * available.
 */
static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
{
	struct netfs_io_request *rreq = subreq->rreq;
	size_t rsize = subreq->len;

	if (subreq->source == NETFS_DOWNLOAD_FROM_SERVER)
		rsize = umin(rsize, rreq->io_streams[0].sreq_max_len);

	subreq->len = rsize;
	if (unlikely(rreq->io_streams[0].sreq_max_segs)) {
		size_t limit = netfs_limit_iter(&rreq->buffer.iter, 0, rsize,
						rreq->io_streams[0].sreq_max_segs);

		if (limit < rsize) {
			subreq->len = limit;
			trace_netfs_sreq(subreq, netfs_sreq_trace_limited);
		}
	}

	subreq->io_iter	= rreq->buffer.iter;

	iov_iter_truncate(&subreq->io_iter, subreq->len);
	rolling_buffer_advance(&rreq->buffer, subreq->len);
	return subreq->len;
}

static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_request *rreq,
						     struct netfs_io_subrequest *subreq,
						     loff_t i_size)
{
	struct netfs_cache_resources *cres = &rreq->cache_resources;
	enum netfs_io_source source;

	if (!cres->ops)
		return NETFS_DOWNLOAD_FROM_SERVER;
	source = cres->ops->prepare_read(subreq, i_size);
	trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
	return source;

}

/*
 * Issue a read against the cache.
 * - Eats the caller's ref on subreq.
 */
static void netfs_read_cache_to_pagecache(struct netfs_io_request *rreq,
					  struct netfs_io_subrequest *subreq)
{
	struct netfs_cache_resources *cres = &rreq->cache_resources;

	netfs_stat(&netfs_n_rh_read);
	cres->ops->read(cres, subreq->start, &subreq->io_iter, NETFS_READ_HOLE_IGNORE,
			netfs_cache_read_terminated, subreq);
}

void netfs_queue_read(struct netfs_io_request *rreq,
		      struct netfs_io_subrequest *subreq)
{
	struct netfs_io_stream *stream = &rreq->io_streams[0];

	__set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);

	/* We add to the end of the list whilst the collector may be walking
	 * the list.  The collector only goes nextwards and uses the lock to
	 * remove entries off of the front.
	 */
	spin_lock(&rreq->lock);
	/* Write IN_PROGRESS before pointer to new subreq */
	list_add_tail_release(&subreq->rreq_link, &stream->subrequests);
	if (list_is_first(&subreq->rreq_link, &stream->subrequests)) {
		if (!stream->active) {
			stream->collected_to = subreq->start;
			/* Store list pointers before active flag */
			smp_store_release(&stream->active, true);
		}
	}

	spin_unlock(&rreq->lock);
}

static void netfs_issue_read(struct netfs_io_request *rreq,
			     struct netfs_io_subrequest *subreq)
{
	switch (subreq->source) {
	case NETFS_DOWNLOAD_FROM_SERVER:
		rreq->netfs_ops->issue_read(subreq);
		break;
	case NETFS_READ_FROM_CACHE:
		netfs_read_cache_to_pagecache(rreq, subreq);
		break;
	default:
		__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
		subreq->error = 0;
		iov_iter_zero(subreq->len, &subreq->io_iter);
		subreq->transferred = subreq->len;
		netfs_read_subreq_terminated(subreq);
		break;
	}
}

/*
 * Mark folios that we want to copy to the cache.  For filesystems that use
 * netfslib fully, we set folio->private to NETFS_FOLIO_COPY_TO_CACHE;
 * otherwise we set the deprecated PG_private_2.
 */
static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,
				     struct folio_queue **fq,
				     unsigned int *offset,
				     int *slot,
				     size_t len,
				     bool copy)
{
	while (len > 0) {
		struct folio *folio;
		size_t fsize, overlap;

		if (!*fq)
			break;
		if (*slot >= folioq_count(*fq)) {
			*fq = (*fq)->next;
			*slot = 0;
			*offset = 0;
			continue;
		}

		/* Determine how much the subreq overlaps the folio, if at all. */
		fsize = folioq_folio_size(*fq, *slot);
		overlap = min(len, fsize - *offset);

		if (overlap > 0 && copy) {
			folio = folioq_folio(*fq, *slot);
			if (unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags))) {
				if (!folio_test_private_2(folio))
					folio_start_private_2(folio);
			} else {
				if (!folio_get_private(folio))
					folio_attach_private(folio, NETFS_FOLIO_COPY_TO_CACHE);
			}
			trace_netfs_folio(folio, netfs_folio_trace_mark_copy);
		}

		len -= overlap;
		*offset += overlap;
		if (*offset >= fsize) {
			*slot += 1;
			*offset = 0;
		}
	}
}

/*
 * Perform a read to the pagecache from a series of sources of different types,
 * slicing up the region to be read according to available cache blocks and
 * network rsize.
 */
static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
{
	struct folio_queue *fq = rreq->buffer.tail;
	unsigned long long start = rreq->start;
	unsigned int offset = 0;
	ssize_t size = rreq->len;
	int ret = 0, slot = 0;

	do {
		struct netfs_io_subrequest *subreq;
		enum netfs_io_source source = NETFS_SOURCE_UNKNOWN;
		ssize_t slice;

		subreq = netfs_alloc_subrequest(rreq);
		if (!subreq) {
			ret = -ENOMEM;
			break;
		}

		subreq->start	= start;
		subreq->len	= size;

		netfs_queue_read(rreq, subreq);

		source = netfs_cache_prepare_read(rreq, subreq, rreq->i_size);
		subreq->source = source;
		if (source == NETFS_DOWNLOAD_FROM_SERVER) {
			unsigned long long zero_point = netfs_read_zero_point(rreq->inode);
			unsigned long long zp = umin(zero_point, rreq->i_size);
			size_t len = subreq->len;

			if (unlikely(rreq->origin == NETFS_READ_SINGLE))
				zp = rreq->i_size;
			if (subreq->start >= zp) {
				subreq->source = source = NETFS_FILL_WITH_ZEROES;
				goto fill_with_zeroes;
			}

			if (len > zp - subreq->start)
				len = zp - subreq->start;
			if (len == 0) {
				pr_err("ZERO-LEN READ: R=%08x[%x] l=%zx/%zx s=%llx z=%llx i=%llx",
				       rreq->debug_id, subreq->debug_index,
				       subreq->len, size,
				       subreq->start, zero_point, rreq->i_size);
				netfs_cancel_read(subreq, ret);
				break;
			}
			subreq->len = len;

			netfs_stat(&netfs_n_rh_download);
			if (rreq->netfs_ops->prepare_read) {
				ret = rreq->netfs_ops->prepare_read(subreq);
				if (ret < 0) {
					netfs_cancel_read(subreq, ret);
					break;
				}
				trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
			}
			goto issue;
		}

	fill_with_zeroes:
		if (source == NETFS_FILL_WITH_ZEROES) {
			subreq->source = NETFS_FILL_WITH_ZEROES;
			trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
			netfs_stat(&netfs_n_rh_zero);
			goto issue;
		}

		if (source == NETFS_READ_FROM_CACHE) {
			trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
			goto issue;
		}

		pr_err("Unexpected read source %u\n", source);
		WARN_ON_ONCE(1);
		netfs_cancel_read(subreq, ret);
		break;

	issue:
		slice = netfs_prepare_read_iterator(subreq);
		if (slice < 0) {
			ret = slice;
			netfs_cancel_read(subreq, ret);
			break;
		}
		start += slice;
		size -= slice;
		if (size <= 0) {
			smp_wmb(); /* Write lists before ALL_QUEUED. */
			set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
		}

		if (fq) {
			/* See if the cache indicated this should be cached. */
			bool copy = test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);

			netfs_mark_copy_to_cache(rreq, &fq, &slot, &offset, slice, copy);
		}

		netfs_issue_read(rreq, subreq);
		netfs_maybe_bulk_drop_ra_refs(rreq);

		if (test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
			netfs_wait_for_paused_read(rreq);
		if (test_bit(NETFS_RREQ_FAILED, &rreq->flags))
			break;
		cond_resched();
	} while (size > 0);

	if (unlikely(size > 0)) {
		smp_wmb(); /* Write lists before ALL_QUEUED. */
		set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
		netfs_wake_collector(rreq);
	}

	/* Defer error return as we may need to wait for outstanding I/O. */
	cmpxchg(&rreq->error, 0, ret);
}

/**
 * netfs_readahead - Helper to manage a read request
 * @ractl: The description of the readahead request
 *
 * Fulfil a readahead request by drawing data from the cache if possible, or
 * the netfs if not.  Space beyond the EOF is zero-filled.  Multiple I/O
 * requests from different sources will get munged together.  If necessary, the
 * readahead window can be expanded in either direction to a more convenient
 * alighment for RPC efficiency or to make storage in the cache feasible.
 *
 * The calling netfs must initialise a netfs context contiguous to the vfs
 * inode before calling this.
 *
 * This is usable whether or not caching is enabled.
 */
void netfs_readahead(struct readahead_control *ractl)
{
	struct netfs_io_request *rreq;
	struct netfs_inode *ictx = netfs_inode(ractl->mapping->host);
	ssize_t added;
	uoff_t start = readahead_pos(ractl);
	size_t size = readahead_length(ractl);
	int ret;

	rreq = netfs_alloc_request(ractl->mapping, ractl->file, start, size,
				   NETFS_READAHEAD);
	if (IS_ERR(rreq))
		return;

	__set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags);

	ret = netfs_begin_cache_read(rreq, ictx);
	if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
		goto cleanup_free;

	netfs_stat(&netfs_n_rh_readahead);
	trace_netfs_read(rreq, readahead_pos(ractl), readahead_length(ractl),
			 netfs_read_trace_readahead);

	netfs_rreq_expand(rreq, ractl);

	/* Load the folios to be read into a bvecq chain.  Note that this
	 * acquires a ref on each folio that we will need to release later -
	 * but we don't want to do that until after we've started the I/O.
	 */
	added = rolling_buffer_bulk_load_from_ra(&rreq->buffer, ractl,
						 rreq->debug_id, rreq->gfp);
	if (added < 0) {
		ret = added;
		goto cleanup_free;
	}
	__set_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags);

	rreq->submitted = rreq->start + added;
	rreq->cleaned_to = rreq->start;
	netfs_read_set_unlock_at(rreq);

	netfs_read_to_pagecache(rreq);
	netfs_maybe_bulk_drop_ra_refs(rreq);
	return netfs_put_request(rreq, netfs_rreq_trace_put_return);

cleanup_free:
	return netfs_put_failed_request(rreq);
}
EXPORT_SYMBOL(netfs_readahead);

/*
 * Create a rolling buffer with a single occupying folio.
 */
static int netfs_create_singular_buffer(struct netfs_io_request *rreq, struct folio *folio,
					unsigned int rollbuf_flags)
{
	ssize_t added;

	if (rolling_buffer_init(&rreq->buffer, rreq->debug_id, ITER_DEST, rreq->gfp) < 0)
		return -ENOMEM;

	added = rolling_buffer_append(&rreq->buffer, folio, rollbuf_flags, rreq->gfp);
	if (added < 0)
		return added;
	rreq->submitted = rreq->start + added;
	rreq->progress_at = added;
	return 0;
}

/*
 * Read into gaps in a folio partially filled by a streaming write.
 */
static int netfs_read_gaps(struct file *file, struct folio *folio)
{
	struct netfs_io_request *rreq;
	struct address_space *mapping = folio->mapping;
	struct netfs_group *group = netfs_folio_group(folio);
	struct netfs_folio *finfo = netfs_folio_info(folio);
	struct netfs_inode *ctx = netfs_inode(mapping->host);
	struct folio *sink = NULL;
	struct bio_vec *bvec;
	unsigned int from = finfo->dirty_offset;
	unsigned int to = from + finfo->dirty_len;
	unsigned int off = 0, i = 0;
	size_t flen = folio_size(folio);
	size_t nr_bvec = flen / PAGE_SIZE + 2;
	size_t part;
	int ret;

	_enter("%lx", folio->index);

	rreq = netfs_alloc_request(mapping, file, folio_pos(folio), flen, NETFS_READ_GAPS);
	if (IS_ERR(rreq)) {
		ret = PTR_ERR(rreq);
		goto alloc_error;
	}

	ret = netfs_begin_cache_read(rreq, ctx);
	if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
		goto discard;

	netfs_stat(&netfs_n_rh_read_folio);
	trace_netfs_read(rreq, rreq->start, rreq->len, netfs_read_trace_read_gaps);

	/* Fiddle the buffer so that a gap at the beginning and/or a gap at the
	 * end get copied to, but the middle is discarded.
	 */
	ret = -ENOMEM;
	bvec = kmalloc_objs(*bvec, nr_bvec);
	if (!bvec)
		goto discard;

	sink = folio_alloc(GFP_KERNEL, 0);
	if (!sink) {
		kfree(bvec);
		goto discard;
	}

	trace_netfs_folio(folio, netfs_folio_trace_read_gaps);

	rreq->direct_bv = bvec;
	rreq->direct_bv_count = nr_bvec;
	if (from > 0) {
		bvec_set_folio(&bvec[i++], folio, from, 0);
		off = from;
	}
	while (off < to) {
		part = min_t(size_t, to - off, PAGE_SIZE);
		bvec_set_folio(&bvec[i++], sink, part, 0);
		off += part;
	}
	if (to < flen)
		bvec_set_folio(&bvec[i++], folio, flen - to, to);
	iov_iter_bvec(&rreq->buffer.iter, ITER_DEST, bvec, i, rreq->len);
	rreq->submitted = rreq->start + flen;

	netfs_read_to_pagecache(rreq);

	ret = netfs_wait_for_read(rreq);
	if (ret >= 0) {
		if (group)
			folio_change_private(folio, group);
		else
			folio_detach_private(folio);
		kfree(finfo);
		trace_netfs_folio(folio, netfs_folio_trace_filled_gaps);
		flush_dcache_folio(folio);
		folio_mark_uptodate(folio);
	}

	if (sink)
		folio_put(sink);
	folio_unlock(folio);
	netfs_put_request(rreq, netfs_rreq_trace_put_return);
	return ret < 0 ? ret : 0;

discard:
	netfs_put_failed_request(rreq);
alloc_error:
	folio_unlock(folio);
	return ret;
}

/**
 * netfs_read_folio - Helper to manage a read_folio request
 * @file: The file to read from
 * @folio: The folio to read
 *
 * Fulfil a read_folio request by drawing data from the cache if
 * possible, or the netfs if not.  Space beyond the EOF is zero-filled.
 * Multiple I/O requests from different sources will get munged together.
 *
 * The calling netfs must initialise a netfs context contiguous to the vfs
 * inode before calling this.
 *
 * This is usable whether or not caching is enabled.
 */
int netfs_read_folio(struct file *file, struct folio *folio)
{
	struct address_space *mapping = folio->mapping;
	struct netfs_io_request *rreq;
	struct netfs_inode *ctx = netfs_inode(mapping->host);
	int ret;

	folio_wait_writeback(folio);

	if (folio_test_dirty(folio))
		return netfs_read_gaps(file, folio);

	_enter("%lx", folio->index);

	rreq = netfs_alloc_request(mapping, file,
				   folio_pos(folio), folio_size(folio),
				   NETFS_READPAGE);
	if (IS_ERR(rreq)) {
		ret = PTR_ERR(rreq);
		goto alloc_error;
	}

	ret = netfs_begin_cache_read(rreq, ctx);
	if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
		goto discard;

	netfs_stat(&netfs_n_rh_read_folio);
	trace_netfs_read(rreq, rreq->start, rreq->len, netfs_read_trace_readpage);

	/* Set up the output buffer */
	ret = netfs_create_singular_buffer(rreq, folio, 0);
	if (ret < 0)
		goto discard;

	netfs_read_to_pagecache(rreq);
	ret = netfs_wait_for_read(rreq);
	netfs_put_request(rreq, netfs_rreq_trace_put_return);
	return ret < 0 ? ret : 0;

discard:
	netfs_put_failed_request(rreq);
alloc_error:
	folio_unlock(folio);
	return ret;
}
EXPORT_SYMBOL(netfs_read_folio);

/*
 * Prepare a folio for writing without reading first
 * @folio: The folio being prepared
 * @pos: starting position for the write
 * @len: length of write
 * @always_fill: T if the folio should always be completely filled/cleared
 *
 * In some cases, write_begin doesn't need to read at all:
 * - full folio write
 * - write that lies in a folio that is completely beyond EOF
 * - write that covers the folio from start to EOF or beyond it
 *
 * If any of these criteria are met, then zero out the unwritten parts
 * of the folio and return true. Otherwise, return false.
 */
static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
				 bool always_fill)
{
	struct inode *inode = folio_inode(folio);
	loff_t i_size = i_size_read(inode);
	size_t offset = offset_in_folio(folio, pos);
	size_t plen = folio_size(folio);

	if (unlikely(always_fill)) {
		if (pos - offset + len <= i_size)
			return false; /* Page entirely before EOF */
		folio_zero_segment(folio, 0, plen);
		folio_mark_uptodate(folio);
		return true;
	}

	/* Full folio write */
	if (offset == 0 && len >= plen)
		return true;

	/* Page entirely beyond the end of the file */
	if (pos - offset >= i_size)
		goto zero_out;

	/* Write that covers from the start of the folio to EOF or beyond */
	if (offset == 0 && (pos + len) >= i_size)
		goto zero_out;

	return false;
zero_out:
	folio_zero_segments(folio, 0, offset, offset + len, plen);
	return true;
}

/**
 * netfs_write_begin - Helper to prepare for writing [DEPRECATED]
 * @ctx: The netfs context
 * @file: The file to read from
 * @mapping: The mapping to read from
 * @pos: File position at which the write will begin
 * @len: The length of the write (may extend beyond the end of the folio chosen)
 * @_folio: Where to put the resultant folio
 * @_fsdata: Place for the netfs to store a cookie
 *
 * Pre-read data for a write-begin request by drawing data from the cache if
 * possible, or the netfs if not.  Space beyond the EOF is zero-filled.
 * Multiple I/O requests from different sources will get munged together.
 *
 * The calling netfs must provide a table of operations, only one of which,
 * issue_read, is mandatory.
 *
 * The check_write_begin() operation can be provided to check for and flush
 * conflicting writes once the folio is grabbed and locked.  It is passed a
 * pointer to the fsdata cookie that gets returned to the VM to be passed to
 * write_end.  It is permitted to sleep.  It should return 0 if the request
 * should go ahead or it may return an error.  It may also unlock and put the
 * folio, provided it sets ``*foliop`` to NULL, in which case a return of 0
 * will cause the folio to be re-got and the process to be retried.
 *
 * The calling netfs must initialise a netfs context contiguous to the vfs
 * inode before calling this.
 *
 * This is usable whether or not caching is enabled.
 *
 * Note that this should be considered deprecated and netfs_perform_write()
 * used instead.
 */
int netfs_write_begin(struct netfs_inode *ctx,
		      struct file *file, struct address_space *mapping,
		      loff_t pos, unsigned int len, struct folio **_folio,
		      void **_fsdata)
{
	struct netfs_io_request *rreq;
	struct folio *folio;
	pgoff_t index = pos >> PAGE_SHIFT;
	int ret;

retry:
	folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
				    mapping_gfp_mask(mapping));
	if (IS_ERR(folio))
		return PTR_ERR(folio);

	if (ctx->ops->check_write_begin) {
		/* Allow the netfs (eg. ceph) to flush conflicts. */
		ret = ctx->ops->check_write_begin(file, pos, len, &folio, _fsdata);
		if (ret < 0) {
			trace_netfs_failure(NULL, NULL, ret, netfs_fail_check_write_begin);
			goto error;
		}
		if (!folio)
			goto retry;
	}

	if (folio_test_uptodate(folio))
		goto have_folio;

	/* If the folio is beyond the EOF, we want to clear it - unless it's
	 * within the cache granule containing the EOF, in which case we need
	 * to preload the granule.
	 */
	if (!netfs_is_cache_maybe_enabled(ctx) &&
	    netfs_skip_folio_read(folio, pos, len, false)) {
		netfs_stat(&netfs_n_rh_write_zskip);
		goto have_folio_no_wait;
	}

	rreq = netfs_alloc_request(mapping, file,
				   folio_pos(folio), folio_size(folio),
				   NETFS_READ_FOR_WRITE);
	if (IS_ERR(rreq)) {
		ret = PTR_ERR(rreq);
		goto error;
	}
	rreq->no_unlock_folio	= folio;
	__set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags);

	ret = netfs_begin_cache_read(rreq, ctx);
	if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
		goto error_put;

	netfs_stat(&netfs_n_rh_write_begin);
	trace_netfs_read(rreq, pos, len, netfs_read_trace_write_begin);

	/* Set up the output buffer */
	ret = netfs_create_singular_buffer(rreq, folio, 0);
	if (ret < 0)
		goto error_put;

	netfs_read_to_pagecache(rreq);
	ret = netfs_wait_for_read(rreq);
	netfs_put_request(rreq, netfs_rreq_trace_put_return);
	if (ret < 0)
		goto error;

have_folio:
	ret = folio_wait_private_2_killable(folio);
	if (ret < 0)
		goto error;
have_folio_no_wait:
	*_folio = folio;
	_leave(" = 0");
	return 0;

error_put:
	netfs_put_failed_request(rreq);
error:
	if (folio) {
		folio_unlock(folio);
		folio_put(folio);
	}
	_leave(" = %d", ret);
	return ret;
}
EXPORT_SYMBOL(netfs_write_begin);

/*
 * Preload the data into a folio we're proposing to write into.
 */
int netfs_prefetch_for_write(struct file *file, struct folio *folio,
			     size_t offset, size_t len)
{
	struct netfs_io_request *rreq;
	struct address_space *mapping = folio->mapping;
	struct netfs_inode *ctx = netfs_inode(mapping->host);
	unsigned long long start = folio_pos(folio);
	size_t flen = folio_size(folio);
	int ret;

	_enter("%zx @%llx", flen, start);

	ret = -ENOMEM;

	rreq = netfs_alloc_request(mapping, file, start, flen,
				   NETFS_READ_FOR_WRITE);
	if (IS_ERR(rreq)) {
		ret = PTR_ERR(rreq);
		goto error;
	}

	rreq->no_unlock_folio = folio;
	__set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags);
	ret = netfs_begin_cache_read(rreq, ctx);
	if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
		goto error_put;

	netfs_stat(&netfs_n_rh_write_begin);
	trace_netfs_read(rreq, start, flen, netfs_read_trace_prefetch_for_write);

	/* Set up the output buffer */
	ret = netfs_create_singular_buffer(rreq, folio, NETFS_ROLLBUF_PAGECACHE_MARK);
	if (ret < 0)
		goto error_put;

	netfs_read_to_pagecache(rreq);
	ret = netfs_wait_for_read(rreq);
	netfs_put_request(rreq, netfs_rreq_trace_put_return);
	return ret < 0 ? ret : 0;

error_put:
	netfs_put_failed_request(rreq);
error:
	_leave(" = %d", ret);
	return ret;
}

/**
 * netfs_buffered_read_iter - Filesystem buffered I/O read routine
 * @iocb: kernel I/O control block
 * @iter: destination for the data read
 *
 * This is the ->read_iter() routine for all filesystems that can use the page
 * cache directly.
 *
 * The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be
 * returned when no data can be read without waiting for I/O requests to
 * complete; it doesn't prevent readahead.
 *
 * The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests
 * shall be made for the read or for readahead.  When no data can be read,
 * -EAGAIN shall be returned.  When readahead would be triggered, a partial,
 * possibly empty read shall be returned.
 *
 * Return:
 * * number of bytes copied, even for partial reads
 * * negative error code (or 0 if IOCB_NOIO) if nothing was read
 */
ssize_t netfs_buffered_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
	struct inode *inode = file_inode(iocb->ki_filp);
	struct netfs_inode *ictx = netfs_inode(inode);
	ssize_t ret;

	if (WARN_ON_ONCE((iocb->ki_flags & IOCB_DIRECT) ||
			 test_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags)))
		return -EINVAL;

	ret = netfs_start_io_read(inode);
	if (ret == 0) {
		ret = filemap_read(iocb, iter, 0);
		netfs_end_io_read(inode);
	}
	return ret;
}
EXPORT_SYMBOL(netfs_buffered_read_iter);

/**
 * netfs_file_read_iter - Generic filesystem read routine
 * @iocb: kernel I/O control block
 * @iter: destination for the data read
 *
 * This is the ->read_iter() routine for all filesystems that can use the page
 * cache directly.
 *
 * The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be
 * returned when no data can be read without waiting for I/O requests to
 * complete; it doesn't prevent readahead.
 *
 * The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests
 * shall be made for the read or for readahead.  When no data can be read,
 * -EAGAIN shall be returned.  When readahead would be triggered, a partial,
 * possibly empty read shall be returned.
 *
 * Return:
 * * number of bytes copied, even for partial reads
 * * negative error code (or 0 if IOCB_NOIO) if nothing was read
 */
ssize_t netfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
	struct netfs_inode *ictx = netfs_inode(iocb->ki_filp->f_mapping->host);

	if ((iocb->ki_flags & IOCB_DIRECT) ||
	    test_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags))
		return netfs_unbuffered_read_iter(iocb, iter);

	return netfs_buffered_read_iter(iocb, iter);
}
EXPORT_SYMBOL(netfs_file_read_iter);
