// SPDX-License-Identifier: GPL-2.0-only /* Network filesystem read subrequest result collection, assessment and * retrying. * * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. * Written by David Howells ([email protected]) */ #include <linux/export.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/task_io_accounting_ops.h> #include "internal.h" /* * Clear the unread part of an I/O request. */ static void netfs_clear_unread(struct netfs_io_subrequest *subreq) { … } /* * Flush, mark and unlock a folio that's now completely read. If we want to * cache the folio, we set the group to NETFS_FOLIO_COPY_TO_CACHE, mark it * dirty and let writeback handle it. */ static void netfs_unlock_read_folio(struct netfs_io_subrequest *subreq, struct netfs_io_request *rreq, struct folio_queue *folioq, int slot) { … } /* * Unlock any folios that are now completely read. Returns true if the * subrequest is removed from the list. */ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq, bool was_async) { … } /* * Do page flushing and suchlike after DIO. */ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq) { … } /* * Assess the state of a read request and decide what to do next. * * Note that we're in normal kernel thread context at this point, possibly * running on a workqueue. */ static void netfs_rreq_assess(struct netfs_io_request *rreq) { … } void netfs_read_termination_worker(struct work_struct *work) { … } /* * Handle the completion of all outstanding I/O operations on a read request. * We inherit a ref from the caller. */ void netfs_rreq_terminated(struct netfs_io_request *rreq, bool was_async) { … } /** * netfs_read_subreq_progress - Note progress of a read operation. * @subreq: The read request that has terminated. * @was_async: True if we're in an asynchronous context. * * This tells the read side of netfs lib that a contributory I/O operation has * made some progress and that it may be possible to unlock some folios. * * Before calling, the filesystem should update subreq->transferred to track * the amount of data copied into the output buffer. * * If @was_async is true, the caller might be running in softirq or interrupt * context and we can't sleep. */ void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq, bool was_async) { … } EXPORT_SYMBOL(…); /** * netfs_read_subreq_terminated - Note the termination of an I/O operation. * @subreq: The I/O request that has terminated. * @error: Error code indicating type of completion. * @was_async: The termination was asynchronous * * This tells the read helper that a contributory I/O operation has terminated, * one way or another, and that it should integrate the results. * * The caller indicates the outcome of the operation through @error, supplying * 0 to indicate a successful or retryable transfer (if NETFS_SREQ_NEED_RETRY * is set) or a negative error code. The helper will look after reissuing I/O * operations as appropriate and writing downloaded data to the cache. * * Before calling, the filesystem should update subreq->transferred to track * the amount of data copied into the output buffer. * * If @was_async is true, the caller might be running in softirq or interrupt * context and we can't sleep. */ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq, int error, bool was_async) { … } EXPORT_SYMBOL(…);