summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2008-10-13 20:36:16 -0500
committerEric Van Hensbergen <ericvh@gmail.com>2008-10-17 11:04:43 -0500
commitfbedadc16e5c888e4df9df3b1757de4993508d35 (patch)
treec477daf52f7a8aa2c2a0c9902b1711b6c2d32833
parent0fc9655ec67ec5d4dfd08e469e0e9f0a494bf5bc (diff)
downloadlinux-fbedadc16e5c888e4df9df3b1757de4993508d35.tar.gz
linux-fbedadc16e5c888e4df9df3b1757de4993508d35.tar.bz2
linux-fbedadc16e5c888e4df9df3b1757de4993508d35.zip
9p: move readn meta-function from client to fs layer
There are a couple of methods in the client code which aren't actually wire operations. To keep things organized cleaner, these operations are being moved to the fs layer. This patch moves the readn meta-function (which executes multiple wire reads until a buffer is full) to the fs layer. Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
-rw-r--r--fs/9p/v9fs.c2
-rw-r--r--fs/9p/v9fs_vfs.h2
-rw-r--r--fs/9p/vfs_addr.c5
-rw-r--r--fs/9p/vfs_file.c57
-rw-r--r--include/net/9p/client.h1
-rw-r--r--net/9p/client.c26
6 files changed, 57 insertions, 36 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index b6b85cf01e0d..24eb01087b6d 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -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) &&
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 57997fa14e69..046cff377f10 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -52,3 +52,5 @@ int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_stat *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);
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 97d3aed57983..6fcb1e7095cf 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -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;
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 3819a195de8f..4d6d7657fb75 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -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_9P, "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_read(fid, NULL, 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;
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index c70a0f0b448d..bb8b0ede132d 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -203,7 +203,6 @@ int p9_client_clunk(struct p9_fid *fid);
int p9_client_remove(struct p9_fid *fid);
int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
u64 offset, u32 count);
-int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count);
int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
u64 offset, u32 count);
struct p9_stat *p9_client_stat(struct p9_fid *fid);
diff --git a/net/9p/client.c b/net/9p/client.c
index 5fc3aa1eb39b..d5ea042eabb0 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1150,32 +1150,6 @@ error:
}
EXPORT_SYMBOL(p9_client_write);
-int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
-{
- int n, total;
-
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
- (long long unsigned) offset, count);
- n = 0;
- total = 0;
- while (count) {
- n = p9_client_read(fid, data, NULL, offset, count);
- if (n <= 0)
- break;
-
- data += n;
- offset += n;
- count -= n;
- total += n;
- }
-
- if (n < 0)
- total = n;
-
- return total;
-}
-EXPORT_SYMBOL(p9_client_readn);
-
static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu)
{
int n;