aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p')
-rw-r--r--net/9p/client.c150
1 files changed, 28 insertions, 122 deletions
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