diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-01 19:57:53 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:28:25 -0400 |
commit | 4f3b35c157e43107cc7e1f1aa06694e8b22e10bb (patch) | |
tree | 2e871c8698529878f93c225b818f4aa4b871f3c6 /net/9p/protocol.c | |
parent | 6e242a1ceeb1bcf55ffefa84d3079f711fe8a667 (diff) |
net/9p: switch the guts of p9_client_{read,write}() to iov_iter
... and have get_user_pages_fast() mapping fewer pages than requested
to generate a short read/write.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/9p/protocol.c')
-rw-r--r-- | net/9p/protocol.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index ab9127ec5b7a..e9d0f0c1a048 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/stddef.h> | 34 | #include <linux/stddef.h> |
35 | #include <linux/types.h> | 35 | #include <linux/types.h> |
36 | #include <linux/uio.h> | ||
36 | #include <net/9p/9p.h> | 37 | #include <net/9p/9p.h> |
37 | #include <net/9p/client.h> | 38 | #include <net/9p/client.h> |
38 | #include "protocol.h" | 39 | #include "protocol.h" |
@@ -69,10 +70,11 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size) | |||
69 | } | 70 | } |
70 | 71 | ||
71 | static size_t | 72 | static size_t |
72 | pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) | 73 | pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size) |
73 | { | 74 | { |
74 | size_t len = min(pdu->capacity - pdu->size, size); | 75 | size_t len = min(pdu->capacity - pdu->size, size); |
75 | if (copy_from_user(&pdu->sdata[pdu->size], udata, len)) | 76 | struct iov_iter i = *from; |
77 | if (copy_from_iter(&pdu->sdata[pdu->size], len, &i) != len) | ||
76 | len = 0; | 78 | len = 0; |
77 | 79 | ||
78 | pdu->size += len; | 80 | pdu->size += len; |
@@ -437,23 +439,13 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
437 | stbuf->extension, stbuf->n_uid, | 439 | stbuf->extension, stbuf->n_uid, |
438 | stbuf->n_gid, stbuf->n_muid); | 440 | stbuf->n_gid, stbuf->n_muid); |
439 | } break; | 441 | } break; |
440 | case 'D':{ | 442 | case 'V':{ |
441 | uint32_t count = va_arg(ap, uint32_t); | ||
442 | const void *data = va_arg(ap, const void *); | ||
443 | |||
444 | errcode = p9pdu_writef(pdu, proto_version, "d", | ||
445 | count); | ||
446 | if (!errcode && pdu_write(pdu, data, count)) | ||
447 | errcode = -EFAULT; | ||
448 | } | ||
449 | break; | ||
450 | case 'U':{ | ||
451 | int32_t count = va_arg(ap, int32_t); | 443 | int32_t count = va_arg(ap, int32_t); |
452 | const char __user *udata = | 444 | struct iov_iter *from = |
453 | va_arg(ap, const void __user *); | 445 | va_arg(ap, struct iov_iter *); |
454 | errcode = p9pdu_writef(pdu, proto_version, "d", | 446 | errcode = p9pdu_writef(pdu, proto_version, "d", |
455 | count); | 447 | count); |
456 | if (!errcode && pdu_write_u(pdu, udata, count)) | 448 | if (!errcode && pdu_write_u(pdu, from, count)) |
457 | errcode = -EFAULT; | 449 | errcode = -EFAULT; |
458 | } | 450 | } |
459 | break; | 451 | break; |