fs/netfs/read_collect.c

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

File Facts

System
Linux kernel
Corpus path
fs/netfs/read_collect.c
Extension
.c
Size
18662 bytes
Lines
609
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 (finfo) {
			trace_netfs_folio(folio, netfs_folio_trace_filled_gaps);
			if (finfo->netfs_group)
				folio_change_private(folio, finfo->netfs_group);
			else
				folio_detach_private(folio);
			kfree(finfo);
		}

		if (test_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags)) {
			if (!WARN_ON_ONCE(folio_get_private(folio) != NULL)) {
				trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
				folio_attach_private(folio, NETFS_FOLIO_COPY_TO_CACHE);
				folio_mark_dirty(folio);
			}
		} else {
			trace_netfs_folio(folio, netfs_folio_trace_read_done);
		}

		folioq_clear(folioq, slot);
	} else {
		// TODO: Use of PG_private_2 is deprecated.
		if (test_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags))
			netfs_pgpriv2_copy_to_cache(rreq, folio);
	}

just_unlock:
	if (folio == rreq->no_unlock_folio &&
	    test_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags)) {
		_debug("no unlock");
	} else {
		trace_netfs_folio(folio, netfs_folio_trace_read_unlock);
		folio_unlock(folio);
	}

	folioq_clear(folioq, slot);
}

/*
 * Unlock any folios we've finished with.
 */
static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
				     unsigned int *notes)
{
	struct folio_queue *folioq = rreq->buffer.tail;
	unsigned long long collected_to = rreq->collected_to;
	unsigned int slot = rreq->buffer.first_tail_slot;

	if (rreq->cleaned_to >= rreq->collected_to)
		return;

	// TODO: Begin decryption

	if (slot >= folioq_nr_slots(folioq)) {
		folioq = rolling_buffer_delete_spent(&rreq->buffer);
		if (!folioq) {
			rreq->front_folio_order = 0;
			return;
		}
		slot = 0;
	}

	for (;;) {
		struct folio *folio;
		unsigned long long fpos, fend;
		unsigned int order;
		size_t fsize;

		if (*notes & COPY_TO_CACHE)
			set_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);

		folio = folioq_folio(folioq, slot);
		if (WARN_ONCE(!folio_test_locked(folio),
			      "R=%08x: folio %lx is not locked\n",
			      rreq->debug_id, folio->index))
			trace_netfs_folio(folio, netfs_folio_trace_not_locked);

		order = folioq_folio_order(folioq, slot);
		rreq->front_folio_order = order;
		fsize = PAGE_SIZE << order;
		fpos = folio_pos(folio);
		fend = fpos + fsize;

		trace_netfs_collect_folio(rreq, folio, fend, collected_to);

		/* Unlock any folio we've transferred all of. */
		if (collected_to < fend)
			break;

		netfs_unlock_read_folio(rreq, folioq, slot);

Annotation

Implementation Notes