fs/9p/vfs_addr.c

Source file repositories/reference/linux-study-clean/fs/9p/vfs_addr.c

File Facts

System
Linux kernel
Corpus path
fs/9p/vfs_addr.c
Extension
.c
Size
5414 bytes
Lines
202
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

if (WARN_ON_ONCE(pos)) {
			/* reading a link at a non null offset should
			 * not happen
			 */
			err = -EIO;
			goto fill_subreq;
		}
		err = p9_client_readlink(fid, &target);
		if (err != 0)
			goto fill_subreq;
		len = strlen(target);
		n = copy_to_iter(target, len, &subreq->io_iter);
		kfree(target);
		total = n;
	} else {
		total = p9_client_read(fid, pos, &subreq->io_iter, &err);
	}

fill_subreq:
	/* if we just extended the file size, any portion not in
	 * cache won't be on server and is zeroes */
	if (subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
	    subreq->rreq->origin != NETFS_DIO_READ)
		__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
	if (pos + total >= i_size_read(rreq->inode))
		__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
	if (!err && total) {
		subreq->transferred += total;
		__set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
	}

	subreq->error = err;
	netfs_read_subreq_terminated(subreq);
}

/**
 * v9fs_init_request - Initialise a request
 * @rreq: The read request
 * @file: The file being read from
 */
static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
{
	struct p9_fid *fid;
	struct dentry *dentry;
	bool writing = (rreq->origin == NETFS_READ_FOR_WRITE ||
			rreq->origin == NETFS_WRITETHROUGH ||
			rreq->origin == NETFS_UNBUFFERED_WRITE ||
			rreq->origin == NETFS_DIO_WRITE);

	if (rreq->origin == NETFS_WRITEBACK)
		return 0; /* We don't get the write handle until we find we
			   * have actually dirty data and not just
			   * copy-to-cache data.
			   */

	if (file) {
		fid = file->private_data;
		if (!fid)
			goto no_fid;
		p9_fid_get(fid);
	} else if (S_ISLNK(rreq->inode->i_mode)) {
		dentry = d_find_any_alias(rreq->inode);
		if (!dentry)
			goto no_fid;
		fid = v9fs_fid_lookup(dentry);
		dput(dentry);
		if (IS_ERR(fid))
			goto no_fid;
	} else {
		fid = v9fs_fid_find_inode(rreq->inode, writing, INVALID_UID, true);
		if (!fid)
			goto no_fid;
	}

	rreq->wsize = fid->clnt->msize - P9_IOHDRSZ;
	if (fid->iounit)
		rreq->wsize = min(rreq->wsize, fid->iounit);

	/* we might need to read from a fid that was opened write-only
	 * for read-modify-write of page cache, use the writeback fid
	 * for that */
	WARN_ON(rreq->origin == NETFS_READ_FOR_WRITE && !(fid->mode & P9_ORDWR));
	rreq->netfs_priv = fid;
	return 0;

no_fid:
	WARN_ONCE(1, "folio expected an open fid inode->i_ino=%llx\n",
		  rreq->inode->i_ino);
	return -EINVAL;
}

Annotation

Implementation Notes