From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Venkateswararao Jujjuri (JV)" Subject: [PATCH 7/7] [net/9p] Handle TREAD/RERROR case in !dotl case. Date: Sun, 06 Feb 2011 22:58:12 -0800 Message-ID: <4D4F9804.1050904@linux.vnet.ibm.com> References: <1297063283-2180-1-git-send-email-jvrao@linux.vnet.ibm.com> <1297063283-2180-8-git-send-email-jvrao@linux.vnet.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org To: "Venkateswararao Jujjuri (JV)" Return-path: Received: from e33.co.us.ibm.com ([32.97.110.151]:32960 "EHLO e33.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752239Ab1BGG6S (ORCPT ); Mon, 7 Feb 2011 01:58:18 -0500 Received: from d03relay03.boulder.ibm.com (d03relay03.boulder.ibm.com [9.17.195.228]) by e33.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p176q1ie031544 for ; Sun, 6 Feb 2011 23:52:01 -0700 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay03.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p176wGHL091906 for ; Sun, 6 Feb 2011 23:58:16 -0700 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p176wGKd029497 for ; Sun, 6 Feb 2011 23:58:16 -0700 In-Reply-To: <1297063283-2180-8-git-send-email-jvrao@linux.vnet.ibm.com> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: 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 > > 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 {