fs/erofs/fscache.c

Source file repositories/reference/linux-study-clean/fs/erofs/fscache.c

File Facts

System
Linux kernel
Corpus path
fs/erofs/fscache.c
Extension
.c
Size
16593 bytes
Lines
665
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source 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

struct erofs_fscache_io {
	struct netfs_cache_resources cres;
	struct iov_iter		iter;
	netfs_io_terminated_t	end_io;
	void			*private;
	refcount_t		ref;
};

struct erofs_fscache_rq {
	struct address_space	*mapping;	/* The mapping being accessed */
	loff_t			start;		/* Start position */
	size_t			len;		/* Length of the request */
	size_t			submitted;	/* Length of submitted */
	short			error;		/* 0 or error that occurred */
	refcount_t		ref;
};

static bool erofs_fscache_io_put(struct erofs_fscache_io *io)
{
	if (!refcount_dec_and_test(&io->ref))
		return false;
	if (io->cres.ops)
		io->cres.ops->end_operation(&io->cres);
	kfree(io);
	return true;
}

static void erofs_fscache_req_complete(struct erofs_fscache_rq *req)
{
	struct folio *folio;
	bool failed = req->error;
	pgoff_t start_page = req->start / PAGE_SIZE;
	pgoff_t last_page = ((req->start + req->len) / PAGE_SIZE) - 1;

	XA_STATE(xas, &req->mapping->i_pages, start_page);

	rcu_read_lock();
	xas_for_each(&xas, folio, last_page) {
		if (xas_retry(&xas, folio))
			continue;
		if (!failed)
			folio_mark_uptodate(folio);
		folio_unlock(folio);
	}
	rcu_read_unlock();
}

static void erofs_fscache_req_put(struct erofs_fscache_rq *req)
{
	if (!refcount_dec_and_test(&req->ref))
		return;
	erofs_fscache_req_complete(req);
	kfree(req);
}

static struct erofs_fscache_rq *erofs_fscache_req_alloc(struct address_space *mapping,
						loff_t start, size_t len)
{
	struct erofs_fscache_rq *req = kzalloc_obj(*req);

	if (!req)
		return NULL;
	req->mapping = mapping;
	req->start = start;
	req->len = len;
	refcount_set(&req->ref, 1);
	return req;
}

static void erofs_fscache_req_io_put(struct erofs_fscache_io *io)
{
	struct erofs_fscache_rq *req = io->private;

	if (erofs_fscache_io_put(io))
		erofs_fscache_req_put(req);
}

static void erofs_fscache_req_end_io(void *priv, ssize_t transferred_or_error)
{
	struct erofs_fscache_io *io = priv;
	struct erofs_fscache_rq *req = io->private;

	if (IS_ERR_VALUE(transferred_or_error))
		req->error = transferred_or_error;
	erofs_fscache_req_io_put(io);
}

static struct erofs_fscache_io *erofs_fscache_req_io_alloc(struct erofs_fscache_rq *req)
{
	struct erofs_fscache_io *io = kzalloc_obj(*io);

Annotation

Implementation Notes