aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,
234 if (!v9ses->clnt->dotu) 234 if (!v9ses->clnt->dotu)
235 v9ses->flags &= ~V9FS_EXTENDED; 235 v9ses->flags &= ~V9FS_EXTENDED;
236 236
237 v9ses->maxdata = v9ses->clnt->msize; 237 v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
238 238
239 /* for legacy mode, fall back to V9FS_ACCESS_ANY */ 239 /* for legacy mode, fall back to V9FS_ACCESS_ANY */
240 if (!v9fs_extended(v9ses) && 240 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);
52void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat); 52void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat);
53void v9fs_dentry_release(struct dentry *); 53void v9fs_dentry_release(struct dentry *);
54int v9fs_uflags2omode(int uflags, int extended); 54int v9fs_uflags2omode(int uflags, int extended);
55
56ssize_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 @@
38 38
39#include "v9fs.h" 39#include "v9fs.h"
40#include "v9fs_vfs.h" 40#include "v9fs_vfs.h"
41#include "fid.h"
42 41
43/** 42/**
44 * v9fs_vfs_readpage - read an entire page in from 9P 43 * 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)
53 int retval; 52 int retval;
54 loff_t offset; 53 loff_t offset;
55 char *buffer; 54 char *buffer;
56 struct p9_fid *fid;
57 55
58 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 56 P9_DPRINTK(P9_DEBUG_VFS, "\n");
59 fid = filp->private_data;
60 buffer = kmap(page); 57 buffer = kmap(page);
61 offset = page_offset(page); 58 offset = page_offset(page);
62 59
63 retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE); 60 retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE);
64 if (retval < 0) 61 if (retval < 0)
65 goto done; 62 goto done;
66 63
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)
120} 120}
121 121
122/** 122/**
123 * v9fs_file_read - read from a file 123 * v9fs_file_readn - read from a file
124 * @filp: file pointer to read 124 * @filp: file pointer to read
125 * @data: data buffer to read data into 125 * @data: data buffer to read data into
126 * @udata: user data buffer to read data into
126 * @count: size of buffer 127 * @count: size of buffer
127 * @offset: offset at which to read data 128 * @offset: offset at which to read data
128 * 129 *
129 */ 130 */
131
132ssize_t
133v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
134 u64 offset)
135{
136 int n, total;
137 struct p9_fid *fid = filp->private_data;
138
139 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
140 (long long unsigned) offset, count);
141
142 n = 0;
143 total = 0;
144 do {
145 n = p9_client_read(fid, data, udata, offset, count);
146 if (n <= 0)
147 break;
148
149 if (data)
150 data += n;
151 if (udata)
152 udata += n;
153
154 offset += n;
155 count -= n;
156 total += n;
157 } while (count > 0 && n == (fid->clnt->msize - P9_IOHDRSZ));
158
159 if (n < 0)
160 total = n;
161
162 return total;
163}
164
165/**
166 * v9fs_file_read - read from a file
167 * @filp: file pointer to read
168 * @udata: user data buffer to read data into
169 * @count: size of buffer
170 * @offset: offset at which to read data
171 *
172 */
173
130static ssize_t 174static ssize_t
131v9fs_file_read(struct file *filp, char __user * data, size_t count, 175v9fs_file_read(struct file *filp, char __user *udata, size_t count,
132 loff_t * offset) 176 loff_t * offset)
133{ 177{
134 int ret; 178 int ret;
135 struct p9_fid *fid; 179 struct p9_fid *fid;
136 180
137 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 181 P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset);
138 fid = filp->private_data; 182 fid = filp->private_data;
139 ret = p9_client_read(fid, NULL, data, *offset, count); 183
184 if (count > (fid->clnt->msize - P9_IOHDRSZ))
185 ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
186 else
187 ret = p9_client_read(fid, NULL, udata, *offset, count);
188
140 if (ret > 0) 189 if (ret > 0)
141 *offset += ret; 190 *offset += ret;
142 191
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);
203int p9_client_remove(struct p9_fid *fid); 203int p9_client_remove(struct p9_fid *fid);
204int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, 204int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
205 u64 offset, u32 count); 205 u64 offset, u32 count);
206int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count);
207int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, 206int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
208 u64 offset, u32 count); 207 u64 offset, u32 count);
209struct p9_stat *p9_client_stat(struct p9_fid *fid); 208struct 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:
1150} 1150}
1151EXPORT_SYMBOL(p9_client_write); 1151EXPORT_SYMBOL(p9_client_write);
1152 1152
1153int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
1154{
1155 int n, total;
1156
1157 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
1158 (long long unsigned) offset, count);
1159 n = 0;
1160 total = 0;
1161 while (count) {
1162 n = p9_client_read(fid, data, NULL, offset, count);
1163 if (n <= 0)
1164 break;
1165
1166 data += n;
1167 offset += n;
1168 count -= n;
1169 total += n;
1170 }
1171
1172 if (n < 0)
1173 total = n;
1174
1175 return total;
1176}
1177EXPORT_SYMBOL(p9_client_readn);
1178
1179static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu) 1153static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu)
1180{ 1154{
1181 int n; 1155 int n;