diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 150 |
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 | } |
1017 | EXPORT_SYMBOL(p9_client_remove); | 1017 | EXPORT_SYMBOL(p9_client_remove); |
1018 | 1018 | ||
1019 | int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count) | 1019 | int |
1020 | p9_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 | |||
1069 | error: | ||
1070 | kfree(tc); | ||
1071 | kfree(rc); | ||
1072 | return err; | ||
1073 | } | ||
1074 | EXPORT_SYMBOL(p9_client_read); | ||
1075 | |||
1076 | int 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 | |||
1122 | error: | ||
1123 | kfree(tc); | ||
1124 | kfree(rc); | ||
1125 | return err; | ||
1126 | } | ||
1127 | EXPORT_SYMBOL(p9_client_write); | ||
1128 | |||
1129 | int | ||
1130 | p9_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 | } |
1190 | EXPORT_SYMBOL(p9_client_uread); | 1088 | EXPORT_SYMBOL(p9_client_read); |
1191 | 1089 | ||
1192 | int | 1090 | int |
1193 | p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, | 1091 | p9_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 | } |
1245 | EXPORT_SYMBOL(p9_client_uwrite); | 1151 | EXPORT_SYMBOL(p9_client_write); |
1246 | 1152 | ||
1247 | int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count) | 1153 | int 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 | ||