summaryrefslogtreecommitdiff
path: root/net/9p/protocol.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-04-01 19:57:53 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-04-11 22:28:25 -0400
commit4f3b35c157e43107cc7e1f1aa06694e8b22e10bb (patch)
tree2e871c8698529878f93c225b818f4aa4b871f3c6 /net/9p/protocol.c
parent6e242a1ceeb1bcf55ffefa84d3079f711fe8a667 (diff)
downloadlwn-4f3b35c157e43107cc7e1f1aa06694e8b22e10bb.tar.gz
lwn-4f3b35c157e43107cc7e1f1aa06694e8b22e10bb.zip
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.c24
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 @@
#include <linux/sched.h>
#include <linux/stddef.h>
#include <linux/types.h>
+#include <linux/uio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "protocol.h"
@@ -69,10 +70,11 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
}
static size_t
-pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
+pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
{
size_t len = min(pdu->capacity - pdu->size, size);
- if (copy_from_user(&pdu->sdata[pdu->size], udata, len))
+ struct iov_iter i = *from;
+ if (copy_from_iter(&pdu->sdata[pdu->size], len, &i) != len)
len = 0;
pdu->size += len;
@@ -437,23 +439,13 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
stbuf->extension, stbuf->n_uid,
stbuf->n_gid, stbuf->n_muid);
} break;
- case 'D':{
- uint32_t count = va_arg(ap, uint32_t);
- const void *data = va_arg(ap, const void *);
-
- errcode = p9pdu_writef(pdu, proto_version, "d",
- count);
- if (!errcode && pdu_write(pdu, data, count))
- errcode = -EFAULT;
- }
- break;
- case 'U':{
+ case 'V':{
int32_t count = va_arg(ap, int32_t);
- const char __user *udata =
- va_arg(ap, const void __user *);
+ struct iov_iter *from =
+ va_arg(ap, struct iov_iter *);
errcode = p9pdu_writef(pdu, proto_version, "d",
count);
- if (!errcode && pdu_write_u(pdu, udata, count))
+ if (!errcode && pdu_write_u(pdu, from, count))
errcode = -EFAULT;
}
break;