fs/netfs/write_collect.c

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

File Facts

System
Linux kernel
Corpus path
fs/netfs/write_collect.c
Extension
.c
Size
15666 bytes
Lines
516
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

list_for_each_entry(sreq, &s->subrequests, rreq_link) {
			pr_err("  sreq[%x:%x] sc=%u s=%llx t=%zx/%zx r=%d f=%lx\n",
			       sreq->stream_nr, sreq->debug_index, sreq->source,
			       sreq->start, sreq->transferred, sreq->len,
			       refcount_read(&sreq->ref), sreq->flags);
		}
	}
}

/*
 * Successful completion of write of a folio to the server and/or cache.  Note
 * that we are not allowed to lock the folio here on pain of deadlocking with
 * truncate.
 */
int netfs_folio_written_back(struct folio *folio)
{
	enum netfs_folio_trace why = netfs_folio_trace_clear;
	struct inode *inode = folio_inode(folio);
	struct netfs_inode *ictx = netfs_inode(inode);
	struct netfs_folio *finfo;
	struct netfs_group *group = NULL;
	int gcount = 0;

	if ((finfo = netfs_folio_info(folio))) {
		/* Streaming writes cannot be redirtied whilst under writeback,
		 * so discard the streaming record.
		 */
		unsigned long long fend;

		fend = folio_pos(folio) + finfo->dirty_offset + finfo->dirty_len;
		spin_lock(&ictx->inode.i_lock);
		if (fend > ictx->_zero_point)
			netfs_write_zero_point(inode, fend);
		spin_unlock(&ictx->inode.i_lock);

		folio_detach_private(folio);
		group = finfo->netfs_group;
		gcount++;
		kfree(finfo);
		why = netfs_folio_trace_clear_s;
		goto end_wb;
	}

	if ((group = netfs_folio_group(folio))) {
		if (group == NETFS_FOLIO_COPY_TO_CACHE) {
			why = netfs_folio_trace_clear_cc;
			folio_detach_private(folio);
			goto end_wb;
		}

		/* Need to detach the group pointer if the page didn't get
		 * redirtied.  If it has been redirtied, then it must be within
		 * the same group.
		 */
		why = netfs_folio_trace_redirtied;
		if (!folio_test_dirty(folio)) {
			folio_detach_private(folio);
			gcount++;
			why = netfs_folio_trace_clear_g;
		}
	}

end_wb:
	trace_netfs_folio(folio, why);
	folio_end_writeback(folio);
	return gcount;
}

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

	if (WARN_ON_ONCE(!folioq)) {
		pr_err("[!] Writeback unlock found empty rolling buffer!\n");
		netfs_dump_request(wreq);
		return;
	}

	if (wreq->origin == NETFS_PGPRIV2_COPY_TO_CACHE) {
		if (netfs_pgpriv2_unlock_copied_folios(wreq))
			*notes |= MADE_PROGRESS;
		return;
	}

Annotation

Implementation Notes