Skip to content

Commit

Permalink
[net/9p] Handle Zero Copy TREAD/RERROR case in !dotl case.
Browse files Browse the repository at this point in the history
This takes care of copying out error buffers from user buffer
payloads when we are using zero copy.  This happens because the
only payload buffer the server has to respond to the request is
the user buffer given for the zero copy read.

Because we only use zerocopy when the amount of data to transfer
is greater than a certain size (currently 4K) and error strings are
limited to ERRMAX (currently 128) we don't need to worry about there
being sufficient space for the error to fit in the payload.

Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
  • Loading branch information
Venkateswararao Jujjuri (JV) authored and Eric Van Hensbergen committed Mar 15, 2011
1 parent 2c66523 commit ca41bb3
Showing 1 changed file with 41 additions and 23 deletions.
64 changes: 41 additions & 23 deletions net/9p/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,43 +443,61 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
{
int8_t type;
int err;
int ecode;

err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
if (err) {
P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
return err;
}

if (type == P9_RERROR || type == P9_RLERROR) {
int ecode;

if (!p9_is_proto_dotl(c)) {
char *ename;
if (type != P9_RERROR && type != P9_RLERROR)
return 0;

err = p9pdu_readf(req->rc, c->proto_version, "s?d",
&ename, &ecode);
if (err)
goto out_err;
if (!p9_is_proto_dotl(c)) {
char *ename;

if (req->tc->pbuf_size) {
/* Handle user buffers */
size_t len = req->rc->size - req->rc->offset;
if (req->tc->pubuf) {
/* User Buffer */
err = copy_from_user(
&req->rc->sdata[req->rc->offset],
req->tc->pubuf, len);
if (err) {
err = -EFAULT;
goto out_err;
}
} else {
/* Kernel Buffer */
memmove(&req->rc->sdata[req->rc->offset],
req->tc->pkbuf, len);
}
}
err = p9pdu_readf(req->rc, c->proto_version, "s?d",
&ename, &ecode);
if (err)
goto out_err;

if (p9_is_proto_dotu(c))
err = -ecode;
if (p9_is_proto_dotu(c))
err = -ecode;

if (!err || !IS_ERR_VALUE(err)) {
err = p9_errstr2errno(ename, strlen(ename));
if (!err || !IS_ERR_VALUE(err)) {
err = p9_errstr2errno(ename, strlen(ename));

P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode,
ename);

kfree(ename);
}
} else {
err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
err = -ecode;

P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
kfree(ename);
}
} else {
err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
err = -ecode;

P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
}

} else
err = 0;

return err;

Expand Down

0 comments on commit ca41bb3

Please sign in to comment.