Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1200fe6 authored by Al Viro's avatar Al Viro
Browse files

9p: switch p9_client_read() to passing struct iov_iter *



... and make it loop

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 9565a544
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -68,8 +68,6 @@ int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
int v9fs_uflags2omode(int uflags, int extended);

ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64);
void v9fs_blank_wstat(struct p9_wstat *wstat);
int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
+9 −11
Original line number Diff line number Diff line
@@ -51,12 +51,11 @@
 */
static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
{
	int retval;
	loff_t offset;
	char *buffer;
	struct inode *inode;
	struct inode *inode = page->mapping->host;
	struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE};
	struct iov_iter to;
	int retval, err;

	inode = page->mapping->host;
	p9_debug(P9_DEBUG_VFS, "\n");

	BUG_ON(!PageLocked(page));
@@ -65,16 +64,16 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
	if (retval == 0)
		return retval;

	buffer = kmap(page);
	offset = page_offset(page);
	iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE);

	retval = v9fs_fid_readn(fid, buffer, NULL, PAGE_CACHE_SIZE, offset);
	if (retval < 0) {
	retval = p9_client_read(fid, page_offset(page), &to, &err);
	if (err) {
		v9fs_uncache_page(inode, page);
		retval = err;
		goto done;
	}

	memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
	zero_user(page, retval, PAGE_SIZE - retval);
	flush_dcache_page(page);
	SetPageUptodate(page);

@@ -82,7 +81,6 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
	retval = 0;

done:
	kunmap(page);
	unlock_page(page);
	return retval;
}
+11 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>

@@ -115,6 +116,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
	int buflen;
	int reclen = 0;
	struct p9_rdir *rdir;
	struct kvec kvec;

	p9_debug(P9_DEBUG_VFS, "name %pD\n", file);
	fid = file->private_data;
@@ -124,16 +126,21 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
	rdir = v9fs_alloc_rdir_buf(file, buflen);
	if (!rdir)
		return -ENOMEM;
	kvec.iov_base = rdir->buf;
	kvec.iov_len = buflen;

	while (1) {
		if (rdir->tail == rdir->head) {
			err = v9fs_file_readn(file, rdir->buf, NULL,
							buflen, ctx->pos);
			if (err <= 0)
			struct iov_iter to;
			int n;
			iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buflen);
			n = p9_client_read(file->private_data, ctx->pos, &to,
					   &err);
			if (err)
				return err;

			rdir->head = 0;
			rdir->tail = err;
			rdir->tail = n;
		}
		while (rdir->head < rdir->tail) {
			p9stat_init(&st);
+10 −69
Original line number Diff line number Diff line
@@ -364,63 +364,6 @@ static int v9fs_file_flock_dotl(struct file *filp, int cmd,
	return ret;
}

/**
 * v9fs_fid_readn - read from a fid
 * @fid: fid to read
 * @data: data buffer to read data into
 * @udata: user data buffer to read data into
 * @count: size of buffer
 * @offset: offset at which to read data
 *
 */
ssize_t
v9fs_fid_readn(struct p9_fid *fid, char *data, char __user *udata, u32 count,
	       u64 offset)
{
	int n, total, size;

	p9_debug(P9_DEBUG_VFS, "fid %d offset %llu count %d\n",
		 fid->fid, (long long unsigned)offset, count);
	n = 0;
	total = 0;
	size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
	do {
		n = p9_client_read(fid, data, udata, offset, count);
		if (n <= 0)
			break;

		if (data)
			data += n;
		if (udata)
			udata += n;

		offset += n;
		count -= n;
		total += n;
	} while (count > 0 && n == size);

	if (n < 0)
		total = n;

	return total;
}

/**
 * v9fs_file_readn - read from a file
 * @filp: file pointer to read
 * @data: data buffer to read data into
 * @udata: user data buffer to read data into
 * @count: size of buffer
 * @offset: offset at which to read data
 *
 */
ssize_t
v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
	       u64 offset)
{
	return v9fs_fid_readn(filp->private_data, data, udata, count, offset);
}

/**
 * v9fs_file_read - read from a file
 * @filp: file pointer to read
@@ -434,22 +377,20 @@ static ssize_t
v9fs_file_read(struct file *filp, char __user *udata, size_t count,
	       loff_t * offset)
{
	int ret;
	struct p9_fid *fid;
	size_t size;
	struct p9_fid *fid = filp->private_data;
	struct iovec iov = {.iov_base = udata, .iov_len = count};
	struct iov_iter to;
	int ret, err;

	iov_iter_init(&to, READ, &iov, 1, count);

	p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
	fid = filp->private_data;

	size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
	if (count > size)
		ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
	else
		ret = p9_client_read(fid, NULL, udata, *offset, count);
	ret = p9_client_read(fid, *offset, &to, &err);
	if (!ret)
		return err;

	if (ret > 0)
	*offset += ret;

	return ret;
}

+16 −32
Original line number Diff line number Diff line
@@ -26,50 +26,34 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
			   void *buffer, size_t buffer_size)
{
	ssize_t retval;
	int msize, read_count;
	u64 offset = 0, attr_size;
	u64 attr_size;
	struct p9_fid *attr_fid;
	struct kvec kvec = {.iov_base = buffer, .iov_len = buffer_size};
	struct iov_iter to;
	int err;

	iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buffer_size);

	attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
	if (IS_ERR(attr_fid)) {
		retval = PTR_ERR(attr_fid);
		p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
			 retval);
		attr_fid = NULL;
		goto error;
	}
	if (!buffer_size) {
		/* request to get the attr_size */
		retval = attr_size;
		goto error;
		return retval;
	}
	if (attr_size > buffer_size) {
		retval = -ERANGE;
		goto error;
	}
	msize = attr_fid->clnt->msize;
	while (attr_size) {
		if (attr_size > (msize - P9_IOHDRSZ))
			read_count = msize - P9_IOHDRSZ;
		if (!buffer_size) /* request to get the attr_size */
			retval = attr_size;
		else
			read_count = attr_size;
		read_count = p9_client_read(attr_fid, ((char *)buffer)+offset,
					NULL, offset, read_count);
		if (read_count < 0) {
			/* error in xattr read */
			retval = read_count;
			goto error;
		}
		offset += read_count;
		attr_size -= read_count;
			retval = -ERANGE;
	} else {
		iov_iter_truncate(&to, attr_size);
		retval = p9_client_read(attr_fid, 0, &to, &err);
		if (err)
			retval = err;
	}
	/* Total read xattr bytes */
	retval = offset;
error:
	if (attr_fid)
	p9_client_clunk(attr_fid);
	return retval;

}


Loading