aboutsummaryrefslogtreecommitdiffstats
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)
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 @@
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
71static size_t 72static size_t
72pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) 73pdu_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;