aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/vfs_file.c4
-rw-r--r--include/net/9p/client.h10
-rw-r--r--net/9p/client.c150
3 files changed, 34 insertions, 130 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 52944d2249a4..3819a195de8f 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -136,7 +136,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count,
136 136
137 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 137 P9_DPRINTK(P9_DEBUG_VFS, "\n");
138 fid = filp->private_data; 138 fid = filp->private_data;
139 ret = p9_client_uread(fid, data, *offset, count); 139 ret = p9_client_read(fid, NULL, data, *offset, count);
140 if (ret > 0) 140 if (ret > 0)
141 *offset += ret; 141 *offset += ret;
142 142
@@ -164,7 +164,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
164 (int)count, (int)*offset); 164 (int)count, (int)*offset);
165 165
166 fid = filp->private_data; 166 fid = filp->private_data;
167 ret = p9_client_uwrite(fid, data, *offset, count); 167 ret = p9_client_write(fid, NULL, data, *offset, count);
168 if (ret > 0) { 168 if (ret > 0) {
169 invalidate_inode_pages2_range(inode->i_mapping, *offset, 169 invalidate_inode_pages2_range(inode->i_mapping, *offset,
170 *offset+ret); 170 *offset+ret);
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 6a71d9067818..c70a0f0b448d 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -201,13 +201,11 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
201 char *extension); 201 char *extension);
202int p9_client_clunk(struct p9_fid *fid); 202int 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, u64 offset, u32 count); 204int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
205 u64 offset, u32 count);
205int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count); 206int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count);
206int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count); 207int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
207int p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, 208 u64 offset, u32 count);
208 u32 count);
209int p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
210 u32 count);
211struct p9_stat *p9_client_stat(struct p9_fid *fid); 209struct p9_stat *p9_client_stat(struct p9_fid *fid);
212int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); 210int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
213struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset); 211struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset);
diff --git a/net/9p/client.c b/net/9p/client.c
index 29934febecdb..5fc3aa1eb39b 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1016,7 +1016,9 @@ done:
1016} 1016}
1017EXPORT_SYMBOL(p9_client_remove); 1017EXPORT_SYMBOL(p9_client_remove);
1018 1018
1019int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count) 1019int
1020p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1021 u32 count)
1020{ 1022{
1021 int err, n, rsize, total; 1023 int err, n, rsize, total;
1022 struct p9_fcall *tc, *rc; 1024 struct p9_fcall *tc, *rc;
@@ -1053,125 +1055,21 @@ int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count)
1053 if (n > count) 1055 if (n > count)
1054 n = count; 1056 n = count;
1055 1057
1056 memmove(data, rc->params.rread.data, n); 1058 if (data) {
1057 count -= n; 1059 memmove(data, rc->params.rread.data, n);
1058 data += n; 1060 data += n;
1059 offset += n;
1060 total += n;
1061 kfree(tc);
1062 tc = NULL;
1063 kfree(rc);
1064 rc = NULL;
1065 } while (count > 0 && n == rsize);
1066
1067 return total;
1068
1069error:
1070 kfree(tc);
1071 kfree(rc);
1072 return err;
1073}
1074EXPORT_SYMBOL(p9_client_read);
1075
1076int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count)
1077{
1078 int err, n, rsize, total;
1079 struct p9_fcall *tc, *rc;
1080 struct p9_client *clnt;
1081
1082 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
1083 (long long unsigned) offset, count);
1084 err = 0;
1085 tc = NULL;
1086 rc = NULL;
1087 clnt = fid->clnt;
1088 total = 0;
1089
1090 rsize = fid->iounit;
1091 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1092 rsize = clnt->msize - P9_IOHDRSZ;
1093
1094 do {
1095 if (count < rsize)
1096 rsize = count;
1097
1098 tc = p9_create_twrite(fid->fid, offset, rsize, data);
1099 if (IS_ERR(tc)) {
1100 err = PTR_ERR(tc);
1101 tc = NULL;
1102 goto error;
1103 } 1061 }
1104 1062
1105 err = p9_client_rpc(clnt, tc, &rc); 1063 if (udata) {
1106 if (err) 1064 err = copy_to_user(udata, rc->params.rread.data, n);
1107 goto error; 1065 if (err) {
1108 1066 err = -EFAULT;
1109 n = rc->params.rread.count; 1067 goto error;
1110 count -= n; 1068 }
1111 data += n; 1069 udata += n;
1112 offset += n;
1113 total += n;
1114 kfree(tc);
1115 tc = NULL;
1116 kfree(rc);
1117 rc = NULL;
1118 } while (count > 0);
1119
1120 return total;
1121
1122error:
1123 kfree(tc);
1124 kfree(rc);
1125 return err;
1126}
1127EXPORT_SYMBOL(p9_client_write);
1128
1129int
1130p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count)
1131{
1132 int err, n, rsize, total;
1133 struct p9_fcall *tc, *rc;
1134 struct p9_client *clnt;
1135
1136 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
1137 (long long unsigned) offset, count);
1138 err = 0;
1139 tc = NULL;
1140 rc = NULL;
1141 clnt = fid->clnt;
1142 total = 0;
1143
1144 rsize = fid->iounit;
1145 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1146 rsize = clnt->msize - P9_IOHDRSZ;
1147
1148 do {
1149 if (count < rsize)
1150 rsize = count;
1151
1152 tc = p9_create_tread(fid->fid, offset, rsize);
1153 if (IS_ERR(tc)) {
1154 err = PTR_ERR(tc);
1155 tc = NULL;
1156 goto error;
1157 }
1158
1159 err = p9_client_rpc(clnt, tc, &rc);
1160 if (err)
1161 goto error;
1162
1163 n = rc->params.rread.count;
1164 if (n > count)
1165 n = count;
1166
1167 err = copy_to_user(data, rc->params.rread.data, n);
1168 if (err) {
1169 err = -EFAULT;
1170 goto error;
1171 } 1070 }
1172 1071
1173 count -= n; 1072 count -= n;
1174 data += n;
1175 offset += n; 1073 offset += n;
1176 total += n; 1074 total += n;
1177 kfree(tc); 1075 kfree(tc);
@@ -1187,11 +1085,11 @@ error:
1187 kfree(rc); 1085 kfree(rc);
1188 return err; 1086 return err;
1189} 1087}
1190EXPORT_SYMBOL(p9_client_uread); 1088EXPORT_SYMBOL(p9_client_read);
1191 1089
1192int 1090int
1193p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, 1091p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1194 u32 count) 1092 u64 offset, u32 count)
1195{ 1093{
1196 int err, n, rsize, total; 1094 int err, n, rsize, total;
1197 struct p9_fcall *tc, *rc; 1095 struct p9_fcall *tc, *rc;
@@ -1213,7 +1111,10 @@ p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
1213 if (count < rsize) 1111 if (count < rsize)
1214 rsize = count; 1112 rsize = count;
1215 1113
1216 tc = p9_create_twrite_u(fid->fid, offset, rsize, data); 1114 if (data)
1115 tc = p9_create_twrite(fid->fid, offset, rsize, data);
1116 else
1117 tc = p9_create_twrite_u(fid->fid, offset, rsize, udata);
1217 if (IS_ERR(tc)) { 1118 if (IS_ERR(tc)) {
1218 err = PTR_ERR(tc); 1119 err = PTR_ERR(tc);
1219 tc = NULL; 1120 tc = NULL;
@@ -1226,7 +1127,12 @@ p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
1226 1127
1227 n = rc->params.rread.count; 1128 n = rc->params.rread.count;
1228 count -= n; 1129 count -= n;
1229 data += n; 1130
1131 if (data)
1132 data += n;
1133 else
1134 udata += n;
1135
1230 offset += n; 1136 offset += n;
1231 total += n; 1137 total += n;
1232 kfree(tc); 1138 kfree(tc);
@@ -1242,7 +1148,7 @@ error:
1242 kfree(rc); 1148 kfree(rc);
1243 return err; 1149 return err;
1244} 1150}
1245EXPORT_SYMBOL(p9_client_uwrite); 1151EXPORT_SYMBOL(p9_client_write);
1246 1152
1247int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count) 1153int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
1248{ 1154{
@@ -1253,7 +1159,7 @@ int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
1253 n = 0; 1159 n = 0;
1254 total = 0; 1160 total = 0;
1255 while (count) { 1161 while (count) {
1256 n = p9_client_read(fid, data, offset, count); 1162 n = p9_client_read(fid, data, NULL, offset, count);
1257 if (n <= 0) 1163 if (n <= 0)
1258 break; 1164 break;
1259 1165