diff options
author | Venkateswararao Jujjuri (JV) <jvrao@linux.vnet.ibm.com> | 2011-01-28 20:05:59 -0500 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2011-03-15 10:57:35 -0400 |
commit | bb2f8a55153ec58e66a496224504ac9be919c8f1 (patch) | |
tree | 25a0d7b4d74b42ca6389fa8f4c41c9378ccd75de | |
parent | 6f69c395cefb26ebba2c9bb725296a3a4a9200ec (diff) |
[net/9p] Read side zerocopy changes for 9P2000.L protocol.
Modify p9_client_read() to check the transport preference and act accordingly.
If the preference is P9_TRANS_PREF_PAYLOAD_SEP, send the payload
separately instead of putting it directly on PDU.
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
-rw-r--r-- | net/9p/client.c | 26 | ||||
-rw-r--r-- | net/9p/protocol.c | 21 |
2 files changed, 39 insertions, 8 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index a848bca9fbff..82079f902f56 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1270,7 +1270,15 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | |||
1270 | if (count < rsize) | 1270 | if (count < rsize) |
1271 | rsize = count; | 1271 | rsize = count; |
1272 | 1272 | ||
1273 | req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize); | 1273 | /* Don't bother zerocopy form small IO (< 1024) */ |
1274 | if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == | ||
1275 | P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) { | ||
1276 | req = p9_client_rpc(clnt, P9_TREAD, "dqE", fid->fid, offset, | ||
1277 | rsize, data, udata); | ||
1278 | } else { | ||
1279 | req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, | ||
1280 | rsize); | ||
1281 | } | ||
1274 | if (IS_ERR(req)) { | 1282 | if (IS_ERR(req)) { |
1275 | err = PTR_ERR(req); | 1283 | err = PTR_ERR(req); |
1276 | goto error; | 1284 | goto error; |
@@ -1284,13 +1292,15 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | |||
1284 | 1292 | ||
1285 | P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); | 1293 | P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); |
1286 | 1294 | ||
1287 | if (data) { | 1295 | if (!req->tc->pbuf_size) { |
1288 | memmove(data, dataptr, count); | 1296 | if (data) { |
1289 | } else { | 1297 | memmove(data, dataptr, count); |
1290 | err = copy_to_user(udata, dataptr, count); | 1298 | } else { |
1291 | if (err) { | 1299 | err = copy_to_user(udata, dataptr, count); |
1292 | err = -EFAULT; | 1300 | if (err) { |
1293 | goto free_and_error; | 1301 | err = -EFAULT; |
1302 | goto free_and_error; | ||
1303 | } | ||
1294 | } | 1304 | } |
1295 | } | 1305 | } |
1296 | p9_free_req(clnt, req); | 1306 | p9_free_req(clnt, req); |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 5936c50d0c93..7bca2421bfc8 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -114,6 +114,17 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) | |||
114 | return size - len; | 114 | return size - len; |
115 | } | 115 | } |
116 | 116 | ||
117 | static size_t | ||
118 | pdu_write_urw(struct p9_fcall *pdu, const char *kdata, const char __user *udata, | ||
119 | size_t size) | ||
120 | { | ||
121 | BUG_ON(pdu->size > P9_IOHDRSZ); | ||
122 | pdu->pubuf = (char __user *)udata; | ||
123 | pdu->pkbuf = (char *)kdata; | ||
124 | pdu->pbuf_size = size; | ||
125 | return 0; | ||
126 | } | ||
127 | |||
117 | /* | 128 | /* |
118 | b - int8_t | 129 | b - int8_t |
119 | w - int16_t | 130 | w - int16_t |
@@ -445,6 +456,16 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
445 | errcode = -EFAULT; | 456 | errcode = -EFAULT; |
446 | } | 457 | } |
447 | break; | 458 | break; |
459 | case 'E':{ | ||
460 | int32_t cnt = va_arg(ap, int32_t); | ||
461 | const char *k = va_arg(ap, const void *); | ||
462 | const char *u = va_arg(ap, const void *); | ||
463 | errcode = p9pdu_writef(pdu, proto_version, "d", | ||
464 | cnt); | ||
465 | if (!errcode && pdu_write_urw(pdu, k, u, cnt)) | ||
466 | errcode = -EFAULT; | ||
467 | } | ||
468 | break; | ||
448 | case 'U':{ | 469 | case 'U':{ |
449 | int32_t count = va_arg(ap, int32_t); | 470 | int32_t count = va_arg(ap, int32_t); |
450 | const char __user *udata = | 471 | const char __user *udata = |