aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/protocol.c')
-rw-r--r--net/9p/protocol.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index fc70147c771e..e7541d5b0118 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -28,6 +28,7 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/slab.h>
31#include <linux/sched.h> 32#include <linux/sched.h>
32#include <linux/types.h> 33#include <linux/types.h>
33#include <net/9p/9p.h> 34#include <net/9p/9p.h>
@@ -52,7 +53,7 @@
52#endif 53#endif
53 54
54static int 55static int
55p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...); 56p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
56 57
57#ifdef CONFIG_NET_9P_DEBUG 58#ifdef CONFIG_NET_9P_DEBUG
58void 59void
@@ -144,7 +145,8 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
144*/ 145*/
145 146
146static int 147static int
147p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) 148p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
149 va_list ap)
148{ 150{
149 const char *ptr; 151 const char *ptr;
150 int errcode = 0; 152 int errcode = 0;
@@ -194,7 +196,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
194 int16_t len; 196 int16_t len;
195 int size; 197 int size;
196 198
197 errcode = p9pdu_readf(pdu, optional, "w", &len); 199 errcode = p9pdu_readf(pdu, proto_version,
200 "w", &len);
198 if (errcode) 201 if (errcode)
199 break; 202 break;
200 203
@@ -217,7 +220,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
217 struct p9_qid *qid = 220 struct p9_qid *qid =
218 va_arg(ap, struct p9_qid *); 221 va_arg(ap, struct p9_qid *);
219 222
220 errcode = p9pdu_readf(pdu, optional, "bdq", 223 errcode = p9pdu_readf(pdu, proto_version, "bdq",
221 &qid->type, &qid->version, 224 &qid->type, &qid->version,
222 &qid->path); 225 &qid->path);
223 } 226 }
@@ -230,7 +233,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
230 stbuf->n_uid = stbuf->n_gid = stbuf->n_muid = 233 stbuf->n_uid = stbuf->n_gid = stbuf->n_muid =
231 -1; 234 -1;
232 errcode = 235 errcode =
233 p9pdu_readf(pdu, optional, 236 p9pdu_readf(pdu, proto_version,
234 "wwdQdddqssss?sddd", 237 "wwdQdddqssss?sddd",
235 &stbuf->size, &stbuf->type, 238 &stbuf->size, &stbuf->type,
236 &stbuf->dev, &stbuf->qid, 239 &stbuf->dev, &stbuf->qid,
@@ -250,7 +253,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
250 void **data = va_arg(ap, void **); 253 void **data = va_arg(ap, void **);
251 254
252 errcode = 255 errcode =
253 p9pdu_readf(pdu, optional, "d", count); 256 p9pdu_readf(pdu, proto_version, "d", count);
254 if (!errcode) { 257 if (!errcode) {
255 *count = 258 *count =
256 MIN(*count, 259 MIN(*count,
@@ -263,8 +266,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
263 int16_t *nwname = va_arg(ap, int16_t *); 266 int16_t *nwname = va_arg(ap, int16_t *);
264 char ***wnames = va_arg(ap, char ***); 267 char ***wnames = va_arg(ap, char ***);
265 268
266 errcode = 269 errcode = p9pdu_readf(pdu, proto_version,
267 p9pdu_readf(pdu, optional, "w", nwname); 270 "w", nwname);
268 if (!errcode) { 271 if (!errcode) {
269 *wnames = 272 *wnames =
270 kmalloc(sizeof(char *) * *nwname, 273 kmalloc(sizeof(char *) * *nwname,
@@ -278,7 +281,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
278 281
279 for (i = 0; i < *nwname; i++) { 282 for (i = 0; i < *nwname; i++) {
280 errcode = 283 errcode =
281 p9pdu_readf(pdu, optional, 284 p9pdu_readf(pdu,
285 proto_version,
282 "s", 286 "s",
283 &(*wnames)[i]); 287 &(*wnames)[i]);
284 if (errcode) 288 if (errcode)
@@ -306,7 +310,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
306 *wqids = NULL; 310 *wqids = NULL;
307 311
308 errcode = 312 errcode =
309 p9pdu_readf(pdu, optional, "w", nwqid); 313 p9pdu_readf(pdu, proto_version, "w", nwqid);
310 if (!errcode) { 314 if (!errcode) {
311 *wqids = 315 *wqids =
312 kmalloc(*nwqid * 316 kmalloc(*nwqid *
@@ -321,7 +325,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
321 325
322 for (i = 0; i < *nwqid; i++) { 326 for (i = 0; i < *nwqid; i++) {
323 errcode = 327 errcode =
324 p9pdu_readf(pdu, optional, 328 p9pdu_readf(pdu,
329 proto_version,
325 "Q", 330 "Q",
326 &(*wqids)[i]); 331 &(*wqids)[i]);
327 if (errcode) 332 if (errcode)
@@ -336,7 +341,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
336 } 341 }
337 break; 342 break;
338 case '?': 343 case '?':
339 if (!optional) 344 if (proto_version != p9_proto_2000u)
340 return 0; 345 return 0;
341 break; 346 break;
342 default: 347 default:
@@ -352,7 +357,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
352} 357}
353 358
354int 359int
355p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) 360p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
361 va_list ap)
356{ 362{
357 const char *ptr; 363 const char *ptr;
358 int errcode = 0; 364 int errcode = 0;
@@ -389,7 +395,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
389 if (sptr) 395 if (sptr)
390 len = MIN(strlen(sptr), USHORT_MAX); 396 len = MIN(strlen(sptr), USHORT_MAX);
391 397
392 errcode = p9pdu_writef(pdu, optional, "w", len); 398 errcode = p9pdu_writef(pdu, proto_version,
399 "w", len);
393 if (!errcode && pdu_write(pdu, sptr, len)) 400 if (!errcode && pdu_write(pdu, sptr, len))
394 errcode = -EFAULT; 401 errcode = -EFAULT;
395 } 402 }
@@ -398,7 +405,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
398 const struct p9_qid *qid = 405 const struct p9_qid *qid =
399 va_arg(ap, const struct p9_qid *); 406 va_arg(ap, const struct p9_qid *);
400 errcode = 407 errcode =
401 p9pdu_writef(pdu, optional, "bdq", 408 p9pdu_writef(pdu, proto_version, "bdq",
402 qid->type, qid->version, 409 qid->type, qid->version,
403 qid->path); 410 qid->path);
404 } break; 411 } break;
@@ -406,7 +413,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
406 const struct p9_wstat *stbuf = 413 const struct p9_wstat *stbuf =
407 va_arg(ap, const struct p9_wstat *); 414 va_arg(ap, const struct p9_wstat *);
408 errcode = 415 errcode =
409 p9pdu_writef(pdu, optional, 416 p9pdu_writef(pdu, proto_version,
410 "wwdQdddqssss?sddd", 417 "wwdQdddqssss?sddd",
411 stbuf->size, stbuf->type, 418 stbuf->size, stbuf->type,
412 stbuf->dev, &stbuf->qid, 419 stbuf->dev, &stbuf->qid,
@@ -421,8 +428,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
421 int32_t count = va_arg(ap, int32_t); 428 int32_t count = va_arg(ap, int32_t);
422 const void *data = va_arg(ap, const void *); 429 const void *data = va_arg(ap, const void *);
423 430
424 errcode = 431 errcode = p9pdu_writef(pdu, proto_version, "d",
425 p9pdu_writef(pdu, optional, "d", count); 432 count);
426 if (!errcode && pdu_write(pdu, data, count)) 433 if (!errcode && pdu_write(pdu, data, count))
427 errcode = -EFAULT; 434 errcode = -EFAULT;
428 } 435 }
@@ -431,8 +438,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
431 int32_t count = va_arg(ap, int32_t); 438 int32_t count = va_arg(ap, int32_t);
432 const char __user *udata = 439 const char __user *udata =
433 va_arg(ap, const void __user *); 440 va_arg(ap, const void __user *);
434 errcode = 441 errcode = p9pdu_writef(pdu, proto_version, "d",
435 p9pdu_writef(pdu, optional, "d", count); 442 count);
436 if (!errcode && pdu_write_u(pdu, udata, count)) 443 if (!errcode && pdu_write_u(pdu, udata, count))
437 errcode = -EFAULT; 444 errcode = -EFAULT;
438 } 445 }
@@ -441,14 +448,15 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
441 int16_t nwname = va_arg(ap, int); 448 int16_t nwname = va_arg(ap, int);
442 const char **wnames = va_arg(ap, const char **); 449 const char **wnames = va_arg(ap, const char **);
443 450
444 errcode = 451 errcode = p9pdu_writef(pdu, proto_version, "w",
445 p9pdu_writef(pdu, optional, "w", nwname); 452 nwname);
446 if (!errcode) { 453 if (!errcode) {
447 int i; 454 int i;
448 455
449 for (i = 0; i < nwname; i++) { 456 for (i = 0; i < nwname; i++) {
450 errcode = 457 errcode =
451 p9pdu_writef(pdu, optional, 458 p9pdu_writef(pdu,
459 proto_version,
452 "s", 460 "s",
453 wnames[i]); 461 wnames[i]);
454 if (errcode) 462 if (errcode)
@@ -462,14 +470,15 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
462 struct p9_qid *wqids = 470 struct p9_qid *wqids =
463 va_arg(ap, struct p9_qid *); 471 va_arg(ap, struct p9_qid *);
464 472
465 errcode = 473 errcode = p9pdu_writef(pdu, proto_version, "w",
466 p9pdu_writef(pdu, optional, "w", nwqid); 474 nwqid);
467 if (!errcode) { 475 if (!errcode) {
468 int i; 476 int i;
469 477
470 for (i = 0; i < nwqid; i++) { 478 for (i = 0; i < nwqid; i++) {
471 errcode = 479 errcode =
472 p9pdu_writef(pdu, optional, 480 p9pdu_writef(pdu,
481 proto_version,
473 "Q", 482 "Q",
474 &wqids[i]); 483 &wqids[i]);
475 if (errcode) 484 if (errcode)
@@ -479,7 +488,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
479 } 488 }
480 break; 489 break;
481 case '?': 490 case '?':
482 if (!optional) 491 if (proto_version != p9_proto_2000u)
483 return 0; 492 return 0;
484 break; 493 break;
485 default: 494 default:
@@ -494,32 +503,32 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
494 return errcode; 503 return errcode;
495} 504}
496 505
497int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...) 506int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
498{ 507{
499 va_list ap; 508 va_list ap;
500 int ret; 509 int ret;
501 510
502 va_start(ap, fmt); 511 va_start(ap, fmt);
503 ret = p9pdu_vreadf(pdu, optional, fmt, ap); 512 ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
504 va_end(ap); 513 va_end(ap);
505 514
506 return ret; 515 return ret;
507} 516}
508 517
509static int 518static int
510p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...) 519p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
511{ 520{
512 va_list ap; 521 va_list ap;
513 int ret; 522 int ret;
514 523
515 va_start(ap, fmt); 524 va_start(ap, fmt);
516 ret = p9pdu_vwritef(pdu, optional, fmt, ap); 525 ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
517 va_end(ap); 526 va_end(ap);
518 527
519 return ret; 528 return ret;
520} 529}
521 530
522int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu) 531int p9stat_read(char *buf, int len, struct p9_wstat *st, int proto_version)
523{ 532{
524 struct p9_fcall fake_pdu; 533 struct p9_fcall fake_pdu;
525 int ret; 534 int ret;
@@ -529,7 +538,7 @@ int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu)
529 fake_pdu.sdata = buf; 538 fake_pdu.sdata = buf;
530 fake_pdu.offset = 0; 539 fake_pdu.offset = 0;
531 540
532 ret = p9pdu_readf(&fake_pdu, dotu, "S", st); 541 ret = p9pdu_readf(&fake_pdu, proto_version, "S", st);
533 if (ret) { 542 if (ret) {
534 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); 543 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
535 p9pdu_dump(1, &fake_pdu); 544 p9pdu_dump(1, &fake_pdu);