On 2/6/2011 11:21 PM, Venkateswararao Jujjuri (JV) wrote: > In addition, this patch also avoids zero copy for short reads in !dotl case. > > Signed-off-by: Venkateswararao Jujjuri <jvrao@xxxxxxxxxxxxxxxxxx> > > Conflicts: > > net/9p/protocol.c > --- > include/net/9p/9p.h | 2 + > net/9p/client.c | 74 +++++++++++++++++++++++++++++++++----------------- > 2 files changed, 51 insertions(+), 25 deletions(-) > > diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h > index 9c939c2..7313801 100644 > --- a/include/net/9p/9p.h > +++ b/include/net/9p/9p.h > @@ -320,6 +320,8 @@ enum p9_qid_t { > /* Room for readdir header */ > #define P9_READDIRHDRSZ 24 > > +#define P9_ERRMAX 256 /* FIXME: Check what is the correct value */ > + > /** > * struct p9_str - length prefixed string type > * @len: length of the string > diff --git a/net/9p/client.c b/net/9p/client.c > index f939edf..7f34c42 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) > { > int8_t type; > int err; > + int ecode; > > err = p9_parse_header(req->rc, NULL, &type, NULL, 0); > if (err) { > @@ -450,36 +451,53 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) > 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->pbuf && > + !segment_eq(get_fs(), KERNEL_DS)) { > + /* User Buffer */ > + err = copy_from_user( > + &req->rc->sdata[req->rc->offset], > + req->tc->pbuf, len); > + if (err) { > + err = -EFAULT; > + return err; > + } > + } else { > + /* Kernel Buffer */ > + memmove(&req->rc->sdata[req->rc->offset], > + req->tc->pbuf, 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; > > @@ -1270,8 +1288,14 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, > if (count < rsize) > rsize = count; > > - if ((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == > - P9_TRANS_PREF_PAYLOAD_SEP) { > + /* for !p9_proto_2000L, we need to have enough space on PDU > + * to handle TREAD/RERROR. Hence don't attempt payload > + * seperaion for small reads even if the transport prefers > + * P9_TRANS_PREF_PAYLOAD_SEP */ > + if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == > + P9_TRANS_PREF_PAYLOAD_SEP) && > + ((clnt->proto_version == p9_proto_2000L) || > + rsize > 2 * P9_ERRMAX) ) { > req = p9_client_rpc(clnt, P9_TREAD, "dqE", fid->fid, offset, > rsize, data ? data : udata); > } else { -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html