diff options
Diffstat (limited to 'net/9p/protocol.c')
-rw-r--r-- | net/9p/protocol.c | 75 |
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 | ||
54 | static int | 55 | static int |
55 | p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...); | 56 | p9pdu_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 |
58 | void | 59 | void |
@@ -144,7 +145,8 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) | |||
144 | */ | 145 | */ |
145 | 146 | ||
146 | static int | 147 | static int |
147 | p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | 148 | p9pdu_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 | ||
354 | int | 359 | int |
355 | p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | 360 | p9pdu_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 | ||
497 | int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...) | 506 | int 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 | ||
509 | static int | 518 | static int |
510 | p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...) | 519 | p9pdu_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 | ||
522 | int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu) | 531 | int 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); |