aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/protocol.c')
-rw-r--r--net/9p/protocol.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 1e308f210928..b58a501cf3d1 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -114,6 +114,26 @@ 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
117static size_t
118pdu_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
128static size_t
129pdu_write_readdir(struct p9_fcall *pdu, const char *kdata, size_t size)
130{
131 BUG_ON(pdu->size > P9_READDIRHDRSZ);
132 pdu->pkbuf = (char *)kdata;
133 pdu->pbuf_size = size;
134 return 0;
135}
136
117/* 137/*
118 b - int8_t 138 b - int8_t
119 w - int16_t 139 w - int16_t
@@ -185,7 +205,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
185 if (errcode) 205 if (errcode)
186 break; 206 break;
187 207
188 *sptr = kmalloc(len + 1, GFP_KERNEL); 208 *sptr = kmalloc(len + 1, GFP_NOFS);
189 if (*sptr == NULL) { 209 if (*sptr == NULL) {
190 errcode = -EFAULT; 210 errcode = -EFAULT;
191 break; 211 break;
@@ -245,7 +265,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
245 } 265 }
246 break; 266 break;
247 case 'T':{ 267 case 'T':{
248 int16_t *nwname = va_arg(ap, int16_t *); 268 uint16_t *nwname = va_arg(ap, uint16_t *);
249 char ***wnames = va_arg(ap, char ***); 269 char ***wnames = va_arg(ap, char ***);
250 270
251 errcode = p9pdu_readf(pdu, proto_version, 271 errcode = p9pdu_readf(pdu, proto_version,
@@ -253,7 +273,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
253 if (!errcode) { 273 if (!errcode) {
254 *wnames = 274 *wnames =
255 kmalloc(sizeof(char *) * *nwname, 275 kmalloc(sizeof(char *) * *nwname,
256 GFP_KERNEL); 276 GFP_NOFS);
257 if (!*wnames) 277 if (!*wnames)
258 errcode = -ENOMEM; 278 errcode = -ENOMEM;
259 } 279 }
@@ -297,7 +317,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
297 *wqids = 317 *wqids =
298 kmalloc(*nwqid * 318 kmalloc(*nwqid *
299 sizeof(struct p9_qid), 319 sizeof(struct p9_qid),
300 GFP_KERNEL); 320 GFP_NOFS);
301 if (*wqids == NULL) 321 if (*wqids == NULL)
302 errcode = -ENOMEM; 322 errcode = -ENOMEM;
303 } 323 }
@@ -445,6 +465,26 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
445 errcode = -EFAULT; 465 errcode = -EFAULT;
446 } 466 }
447 break; 467 break;
468 case 'E':{
469 int32_t cnt = va_arg(ap, int32_t);
470 const char *k = va_arg(ap, const void *);
471 const char __user *u = va_arg(ap,
472 const void __user *);
473 errcode = p9pdu_writef(pdu, proto_version, "d",
474 cnt);
475 if (!errcode && pdu_write_urw(pdu, k, u, cnt))
476 errcode = -EFAULT;
477 }
478 break;
479 case 'F':{
480 int32_t cnt = va_arg(ap, int32_t);
481 const char *k = va_arg(ap, const void *);
482 errcode = p9pdu_writef(pdu, proto_version, "d",
483 cnt);
484 if (!errcode && pdu_write_readdir(pdu, k, cnt))
485 errcode = -EFAULT;
486 }
487 break;
448 case 'U':{ 488 case 'U':{
449 int32_t count = va_arg(ap, int32_t); 489 int32_t count = va_arg(ap, int32_t);
450 const char __user *udata = 490 const char __user *udata =
@@ -456,7 +496,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
456 } 496 }
457 break; 497 break;
458 case 'T':{ 498 case 'T':{
459 int16_t nwname = va_arg(ap, int); 499 uint16_t nwname = va_arg(ap, int);
460 const char **wnames = va_arg(ap, const char **); 500 const char **wnames = va_arg(ap, const char **);
461 501
462 errcode = p9pdu_writef(pdu, proto_version, "w", 502 errcode = p9pdu_writef(pdu, proto_version, "w",
@@ -579,6 +619,7 @@ EXPORT_SYMBOL(p9stat_read);
579 619
580int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type) 620int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
581{ 621{
622 pdu->id = type;
582 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag); 623 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
583} 624}
584 625
@@ -606,6 +647,10 @@ void p9pdu_reset(struct p9_fcall *pdu)
606{ 647{
607 pdu->offset = 0; 648 pdu->offset = 0;
608 pdu->size = 0; 649 pdu->size = 0;
650 pdu->private = NULL;
651 pdu->pubuf = NULL;
652 pdu->pkbuf = NULL;
653 pdu->pbuf_size = 0;
609} 654}
610 655
611int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, 656int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,