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

Commit 45e4a24f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: (26 commits)
  9p: add more conservative locking
  9p: fix oops in protocol stat parsing error path.
  9p: fix device file handling
  9p: Improve debug support
  9p: eliminate depricated conv functions
  9p: rework client code to use new protocol support functions
  9p: remove unnecessary tag field from p9_req_t structure
  9p: remove 9p fcall debug prints
  9p: add new protocol support code
  9p: encapsulate version function
  9p: move dirread to fs layer
  9p: adjust 9p vfs write operation
  9p: move readn meta-function from client to fs layer
  9p: consolidate read/write functions
  9p: drop broken unused error path from p9_conn_create()
  9p: make rpc code common and rework flush code
  9p: use the rcall structure passed in the request in trans_fd read_work
  9p: apply common request code to trans_fd
  9p: apply common tagpool handling to trans_fd
  9p: move request management to client code
  ...
parents 52c6738b 7eb923b8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -30,8 +30,8 @@
#include <linux/parser.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
#include <net/9p/transport.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include "v9fs.h"
#include "v9fs_vfs.h"

@@ -234,7 +234,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
	if (!v9ses->clnt->dotu)
		v9ses->flags &= ~V9FS_EXTENDED;

	v9ses->maxdata = v9ses->clnt->msize;
	v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;

	/* for legacy mode, fall back to V9FS_ACCESS_ANY */
	if (!v9fs_extended(v9ses) &&
+4 −2
Original line number Diff line number Diff line
@@ -46,9 +46,11 @@ extern struct dentry_operations v9fs_cached_dentry_operations;

struct inode *v9fs_get_inode(struct super_block *sb, int mode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
int v9fs_dir_release(struct inode *inode, struct file *filp);
int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat);
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
void v9fs_dentry_release(struct dentry *);
int v9fs_uflags2omode(int uflags, int extended);

ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
+1 −4
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@

#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"

/**
 * v9fs_vfs_readpage - read an entire page in from 9P
@@ -53,14 +52,12 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page)
	int retval;
	loff_t offset;
	char *buffer;
	struct p9_fid *fid;

	P9_DPRINTK(P9_DEBUG_VFS, "\n");
	fid = filp->private_data;
	buffer = kmap(page);
	offset = page_offset(page);

	retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE);
	retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE);
	if (retval < 0)
		goto done;

+43 −17
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@
 *
 */

static inline int dt_type(struct p9_stat *mistat)
static inline int dt_type(struct p9_wstat *mistat)
{
	unsigned long perm = mistat->mode;
	int rettype = DT_REG;
@@ -69,32 +69,58 @@ static inline int dt_type(struct p9_stat *mistat)
static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
	int over;
	struct p9_wstat st;
	int err;
	struct p9_fid *fid;
	struct v9fs_session_info *v9ses;
	struct inode *inode;
	struct p9_stat *st;
	int buflen;
	char *statbuf;
	int n, i = 0;

	P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
	inode = filp->f_path.dentry->d_inode;
	v9ses = v9fs_inode2v9ses(inode);
	fid = filp->private_data;
	while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) {
		if (IS_ERR(st))
			return PTR_ERR(st);

		over = filldir(dirent, st->name.str, st->name.len, filp->f_pos,
			v9fs_qid2ino(&st->qid), dt_type(st));
	buflen = fid->clnt->msize - P9_IOHDRSZ;
	statbuf = kmalloc(buflen, GFP_KERNEL);
	if (!statbuf)
		return -ENOMEM;

		if (over)
	while (1) {
		err = v9fs_file_readn(filp, statbuf, NULL, buflen,
								fid->rdir_fpos);
		if (err <= 0)
			break;

		filp->f_pos += st->size;
		kfree(st);
		st = NULL;
		n = err;
		while (i < n) {
			err = p9stat_read(statbuf + i, buflen-i, &st,
							fid->clnt->dotu);
			if (err) {
				P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
				err = -EIO;
				p9stat_free(&st);
				goto free_and_exit;
			}

	kfree(st);
	return 0;
			i += st.size+2;
			fid->rdir_fpos += st.size+2;

			over = filldir(dirent, st.name, strlen(st.name),
			    filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));

			filp->f_pos += st.size+2;

			p9stat_free(&st);

			if (over) {
				err = 0;
				goto free_and_exit;
			}
		}
	}

free_and_exit:
	kfree(statbuf);
	return err;
}


+82 −11
Original line number Diff line number Diff line
@@ -120,23 +120,72 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
}

/**
 * v9fs_file_read - read from a file
 * 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)
{
	int n, total;
	struct p9_fid *fid = filp->private_data;

	P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid,
					(long long unsigned) offset, count);

	n = 0;
	total = 0;
	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 == (fid->clnt->msize - P9_IOHDRSZ));

	if (n < 0)
		total = n;

	return total;
}

/**
 * v9fs_file_read - read from a file
 * @filp: file pointer to read
 * @udata: user data buffer to read data into
 * @count: size of buffer
 * @offset: offset at which to read data
 *
 */

static ssize_t
v9fs_file_read(struct file *filp, char __user * data, size_t count,
v9fs_file_read(struct file *filp, char __user *udata, size_t count,
	       loff_t * offset)
{
	int ret;
	struct p9_fid *fid;

	P9_DPRINTK(P9_DEBUG_VFS, "\n");
	P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset);
	fid = filp->private_data;
	ret = p9_client_uread(fid, data, *offset, count);

	if (count > (fid->clnt->msize - P9_IOHDRSZ))
		ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
	else
		ret = p9_client_read(fid, NULL, udata, *offset, count);

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

@@ -156,19 +205,38 @@ static ssize_t
v9fs_file_write(struct file *filp, const char __user * data,
		size_t count, loff_t * offset)
{
	int ret;
	int n, rsize, total = 0;
	struct p9_fid *fid;
	struct p9_client *clnt;
	struct inode *inode = filp->f_path.dentry->d_inode;
	int origin = *offset;

	P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
		(int)count, (int)*offset);

	fid = filp->private_data;
	ret = p9_client_uwrite(fid, data, *offset, count);
	if (ret > 0) {
		invalidate_inode_pages2_range(inode->i_mapping, *offset,
								*offset+ret);
		*offset += ret;
	clnt = fid->clnt;

	rsize = fid->iounit;
	if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
		rsize = clnt->msize - P9_IOHDRSZ;

	do {
		if (count < rsize)
			rsize = count;

		n = p9_client_write(fid, NULL, data+total, *offset+total,
									rsize);
		if (n <= 0)
			break;
		count -= n;
		total += n;
	} while (count > 0);

	if (total > 0) {
		invalidate_inode_pages2_range(inode->i_mapping, origin,
								origin+total);
		*offset += total;
	}

	if (*offset > inode->i_size) {
@@ -176,7 +244,10 @@ v9fs_file_write(struct file *filp, const char __user * data,
		inode->i_blocks = (inode->i_size + 512 - 1) >> 9;
	}

	return ret;
	if (n < 0)
		return n;

	return total;
}

static const struct file_operations v9fs_cached_file_operations = {
Loading