fs/netfs/direct_read.c

Source file repositories/reference/linux-study-clean/fs/netfs/direct_read.c

File Facts

System
Linux kernel
Corpus path
fs/netfs/direct_read.c
Extension
.c
Size
6736 bytes
Lines
256
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

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

	trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);

	subreq->io_iter	= rreq->buffer.iter;
	iov_iter_truncate(&subreq->io_iter, subreq->len);
	iov_iter_advance(&rreq->buffer.iter, subreq->len);
}

/*
 * Perform a read to a buffer from the server, slicing up the region to be read
 * according to the network rsize.
 */
static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
{
	unsigned long long start = rreq->start;
	ssize_t size = rreq->len;
	int ret;

	do {
		struct netfs_io_subrequest *subreq;
		ssize_t slice;

		subreq = netfs_alloc_subrequest(rreq);
		if (!subreq) {
			/* Stash the error in the request if there's not
			 * already an error set.
			 */
			cmpxchg(&rreq->error, 0, -ENOMEM);
			break;
		}

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

		netfs_queue_read(rreq, subreq);

		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;
			}
		}

		netfs_prepare_dio_read_iterator(subreq);
		slice = subreq->len;
		size -= slice;
		start += slice;
		rreq->submitted += slice;
		if (size <= 0) {
			smp_wmb(); /* Write lists before ALL_QUEUED. */
			set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
		}

		rreq->netfs_ops->issue_read(subreq);

		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);
	}
}

/*
 * Perform a read to an application buffer, bypassing the pagecache and the
 * local disk cache.
 */
static ssize_t netfs_unbuffered_read(struct netfs_io_request *rreq, bool sync)
{
	ssize_t ret;

	_enter("R=%x %llx-%llx",
	       rreq->debug_id, rreq->start, rreq->start + rreq->len - 1);

	if (rreq->len == 0) {
		pr_err("Zero-sized read [R=%x]\n", rreq->debug_id);

Annotation

Implementation Notes