diff options
-rw-r--r-- | net/9p/client.c | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 6e07ef494ff2..251abb1699c4 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -443,6 +443,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) | |||
443 | { | 443 | { |
444 | int8_t type; | 444 | int8_t type; |
445 | int err; | 445 | int err; |
446 | int ecode; | ||
446 | 447 | ||
447 | err = p9_parse_header(req->rc, NULL, &type, NULL, 0); | 448 | err = p9_parse_header(req->rc, NULL, &type, NULL, 0); |
448 | if (err) { | 449 | if (err) { |
@@ -450,36 +451,53 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) | |||
450 | return err; | 451 | return err; |
451 | } | 452 | } |
452 | 453 | ||
453 | if (type == P9_RERROR || type == P9_RLERROR) { | 454 | if (type != P9_RERROR && type != P9_RLERROR) |
454 | int ecode; | 455 | return 0; |
455 | |||
456 | if (!p9_is_proto_dotl(c)) { | ||
457 | char *ename; | ||
458 | 456 | ||
459 | err = p9pdu_readf(req->rc, c->proto_version, "s?d", | 457 | if (!p9_is_proto_dotl(c)) { |
460 | &ename, &ecode); | 458 | char *ename; |
461 | if (err) | 459 | |
462 | goto out_err; | 460 | if (req->tc->pbuf_size) { |
461 | /* Handle user buffers */ | ||
462 | size_t len = req->rc->size - req->rc->offset; | ||
463 | if (req->tc->pubuf) { | ||
464 | /* User Buffer */ | ||
465 | err = copy_from_user( | ||
466 | &req->rc->sdata[req->rc->offset], | ||
467 | req->tc->pubuf, len); | ||
468 | if (err) { | ||
469 | err = -EFAULT; | ||
470 | goto out_err; | ||
471 | } | ||
472 | } else { | ||
473 | /* Kernel Buffer */ | ||
474 | memmove(&req->rc->sdata[req->rc->offset], | ||
475 | req->tc->pkbuf, len); | ||
476 | } | ||
477 | } | ||
478 | err = p9pdu_readf(req->rc, c->proto_version, "s?d", | ||
479 | &ename, &ecode); | ||
480 | if (err) | ||
481 | goto out_err; | ||
463 | 482 | ||
464 | if (p9_is_proto_dotu(c)) | 483 | if (p9_is_proto_dotu(c)) |
465 | err = -ecode; | 484 | err = -ecode; |
466 | 485 | ||
467 | if (!err || !IS_ERR_VALUE(err)) { | 486 | if (!err || !IS_ERR_VALUE(err)) { |
468 | err = p9_errstr2errno(ename, strlen(ename)); | 487 | err = p9_errstr2errno(ename, strlen(ename)); |
469 | 488 | ||
470 | P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename); | 489 | P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, |
490 | ename); | ||
471 | 491 | ||
472 | kfree(ename); | 492 | kfree(ename); |
473 | } | ||
474 | } else { | ||
475 | err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); | ||
476 | err = -ecode; | ||
477 | |||
478 | P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); | ||
479 | } | 493 | } |
494 | } else { | ||
495 | err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); | ||
496 | err = -ecode; | ||
497 | |||
498 | P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); | ||
499 | } | ||
480 | 500 | ||
481 | } else | ||
482 | err = 0; | ||
483 | 501 | ||
484 | return err; | 502 | return err; |
485 | 503 | ||