aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/conv.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/conv.c')
-rw-r--r--fs/9p/conv.c86
1 files changed, 45 insertions, 41 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 18121af99d3e..1b9b15dfeaf0 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -208,7 +208,7 @@ static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
208 len = buf_get_int16(buf); 208 len = buf_get_int16(buf);
209 209
210 if (!buf_check_overflow(buf) && buf_check_size(buf, len) && 210 if (!buf_check_overflow(buf) && buf_check_size(buf, len) &&
211 buf_check_size(sbuf, len+1)) { 211 buf_check_size(sbuf, len + 1)) {
212 212
213 memcpy(sbuf->p, buf->p, len); 213 memcpy(sbuf->p, buf->p, len);
214 sbuf->p[len] = 0; 214 sbuf->p[len] = 0;
@@ -252,13 +252,12 @@ static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
252 252
253/** 253/**
254 * v9fs_size_stat - calculate the size of a variable length stat struct 254 * v9fs_size_stat - calculate the size of a variable length stat struct
255 * @v9ses: session information
256 * @stat: metadata (stat) structure 255 * @stat: metadata (stat) structure
256 * @extended: non-zero if 9P2000.u
257 * 257 *
258 */ 258 */
259 259
260static int v9fs_size_stat(struct v9fs_session_info *v9ses, 260static int v9fs_size_stat(struct v9fs_stat *stat, int extended)
261 struct v9fs_stat *stat)
262{ 261{
263 int size = 0; 262 int size = 0;
264 263
@@ -288,7 +287,7 @@ static int v9fs_size_stat(struct v9fs_session_info *v9ses,
288 if (stat->muid) 287 if (stat->muid)
289 size += strlen(stat->muid); 288 size += strlen(stat->muid);
290 289
291 if (v9ses->extended) { 290 if (extended) {
292 size += 4 + /* n_uid[4] */ 291 size += 4 + /* n_uid[4] */
293 4 + /* n_gid[4] */ 292 4 + /* n_gid[4] */
294 4 + /* n_muid[4] */ 293 4 + /* n_muid[4] */
@@ -302,15 +301,14 @@ static int v9fs_size_stat(struct v9fs_session_info *v9ses,
302 301
303/** 302/**
304 * serialize_stat - safely format a stat structure for transmission 303 * serialize_stat - safely format a stat structure for transmission
305 * @v9ses: session info
306 * @stat: metadata (stat) structure 304 * @stat: metadata (stat) structure
307 * @bufp: buffer to serialize structure into 305 * @bufp: buffer to serialize structure into
306 * @extended: non-zero if 9P2000.u
308 * 307 *
309 */ 308 */
310 309
311static int 310static int
312serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat, 311serialize_stat(struct v9fs_stat *stat, struct cbuf *bufp, int extended)
313 struct cbuf *bufp)
314{ 312{
315 buf_put_int16(bufp, stat->size); 313 buf_put_int16(bufp, stat->size);
316 buf_put_int16(bufp, stat->type); 314 buf_put_int16(bufp, stat->type);
@@ -328,7 +326,7 @@ serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat,
328 buf_put_string(bufp, stat->gid); 326 buf_put_string(bufp, stat->gid);
329 buf_put_string(bufp, stat->muid); 327 buf_put_string(bufp, stat->muid);
330 328
331 if (v9ses->extended) { 329 if (extended) {
332 buf_put_string(bufp, stat->extension); 330 buf_put_string(bufp, stat->extension);
333 buf_put_int32(bufp, stat->n_uid); 331 buf_put_int32(bufp, stat->n_uid);
334 buf_put_int32(bufp, stat->n_gid); 332 buf_put_int32(bufp, stat->n_gid);
@@ -343,16 +341,16 @@ serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat,
343 341
344/** 342/**
345 * deserialize_stat - safely decode a recieved metadata (stat) structure 343 * deserialize_stat - safely decode a recieved metadata (stat) structure
346 * @v9ses: session info
347 * @bufp: buffer to deserialize 344 * @bufp: buffer to deserialize
348 * @stat: metadata (stat) structure 345 * @stat: metadata (stat) structure
349 * @dbufp: buffer to deserialize variable strings into 346 * @dbufp: buffer to deserialize variable strings into
347 * @extended: non-zero if 9P2000.u
350 * 348 *
351 */ 349 */
352 350
353static inline int 351static inline int
354deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp, 352deserialize_stat(struct cbuf *bufp, struct v9fs_stat *stat,
355 struct v9fs_stat *stat, struct cbuf *dbufp) 353 struct cbuf *dbufp, int extended)
356{ 354{
357 355
358 stat->size = buf_get_int16(bufp); 356 stat->size = buf_get_int16(bufp);
@@ -370,7 +368,7 @@ deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp,
370 stat->gid = buf_get_stringb(bufp, dbufp); 368 stat->gid = buf_get_stringb(bufp, dbufp);
371 stat->muid = buf_get_stringb(bufp, dbufp); 369 stat->muid = buf_get_stringb(bufp, dbufp);
372 370
373 if (v9ses->extended) { 371 if (extended) {
374 stat->extension = buf_get_stringb(bufp, dbufp); 372 stat->extension = buf_get_stringb(bufp, dbufp);
375 stat->n_uid = buf_get_int32(bufp); 373 stat->n_uid = buf_get_int32(bufp);
376 stat->n_gid = buf_get_int32(bufp); 374 stat->n_gid = buf_get_int32(bufp);
@@ -385,20 +383,20 @@ deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp,
385 383
386/** 384/**
387 * deserialize_statb - wrapper for decoding a received metadata structure 385 * deserialize_statb - wrapper for decoding a received metadata structure
388 * @v9ses: session info
389 * @bufp: buffer to deserialize 386 * @bufp: buffer to deserialize
390 * @dbufp: buffer to deserialize variable strings into 387 * @dbufp: buffer to deserialize variable strings into
388 * @extended: non-zero if 9P2000.u
391 * 389 *
392 */ 390 */
393 391
394static inline struct v9fs_stat *deserialize_statb(struct v9fs_session_info 392static inline struct v9fs_stat *deserialize_statb(struct cbuf *bufp,
395 *v9ses, struct cbuf *bufp, 393 struct cbuf *dbufp,
396 struct cbuf *dbufp) 394 int extended)
397{ 395{
398 struct v9fs_stat *ret = buf_alloc(dbufp, sizeof(struct v9fs_stat)); 396 struct v9fs_stat *ret = buf_alloc(dbufp, sizeof(struct v9fs_stat));
399 397
400 if (ret) { 398 if (ret) {
401 int n = deserialize_stat(v9ses, bufp, ret, dbufp); 399 int n = deserialize_stat(bufp, ret, dbufp, extended);
402 if (n <= 0) 400 if (n <= 0)
403 return NULL; 401 return NULL;
404 } 402 }
@@ -408,17 +406,16 @@ static inline struct v9fs_stat *deserialize_statb(struct v9fs_session_info
408 406
409/** 407/**
410 * v9fs_deserialize_stat - decode a received metadata structure 408 * v9fs_deserialize_stat - decode a received metadata structure
411 * @v9ses: session info
412 * @buf: buffer to deserialize 409 * @buf: buffer to deserialize
413 * @buflen: length of received buffer 410 * @buflen: length of received buffer
414 * @stat: metadata structure to decode into 411 * @stat: metadata structure to decode into
415 * @statlen: length of destination metadata structure 412 * @statlen: length of destination metadata structure
413 * @extended: non-zero if 9P2000.u
416 * 414 *
417 */ 415 */
418 416
419int 417int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat,
420v9fs_deserialize_stat(struct v9fs_session_info *v9ses, void *buf, 418 u32 statlen, int extended)
421 u32 buflen, struct v9fs_stat *stat, u32 statlen)
422{ 419{
423 struct cbuf buffer; 420 struct cbuf buffer;
424 struct cbuf *bufp = &buffer; 421 struct cbuf *bufp = &buffer;
@@ -429,11 +426,10 @@ v9fs_deserialize_stat(struct v9fs_session_info *v9ses, void *buf,
429 buf_init(dbufp, (char *)stat + sizeof(struct v9fs_stat), 426 buf_init(dbufp, (char *)stat + sizeof(struct v9fs_stat),
430 statlen - sizeof(struct v9fs_stat)); 427 statlen - sizeof(struct v9fs_stat));
431 428
432 return deserialize_stat(v9ses, bufp, stat, dbufp); 429 return deserialize_stat(bufp, stat, dbufp, extended);
433} 430}
434 431
435static inline int 432static inline int v9fs_size_fcall(struct v9fs_fcall *fcall, int extended)
436v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
437{ 433{
438 int size = 4 + 1 + 2; /* size[4] msg[1] tag[2] */ 434 int size = 4 + 1 + 2; /* size[4] msg[1] tag[2] */
439 int i = 0; 435 int i = 0;
@@ -485,7 +481,7 @@ v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
485 break; 481 break;
486 case TWSTAT: /* fid[4] stat[n] */ 482 case TWSTAT: /* fid[4] stat[n] */
487 fcall->params.twstat.stat->size = 483 fcall->params.twstat.stat->size =
488 v9fs_size_stat(v9ses, fcall->params.twstat.stat); 484 v9fs_size_stat(fcall->params.twstat.stat, extended);
489 size += 4 + 2 + 2 + fcall->params.twstat.stat->size; 485 size += 4 + 2 + 2 + fcall->params.twstat.stat->size;
490 } 486 }
491 return size; 487 return size;
@@ -493,16 +489,16 @@ v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
493 489
494/* 490/*
495 * v9fs_serialize_fcall - marshall fcall struct into a packet 491 * v9fs_serialize_fcall - marshall fcall struct into a packet
496 * @v9ses: session information
497 * @fcall: structure to convert 492 * @fcall: structure to convert
498 * @data: buffer to serialize fcall into 493 * @data: buffer to serialize fcall into
499 * @datalen: length of buffer to serialize fcall into 494 * @datalen: length of buffer to serialize fcall into
495 * @extended: non-zero if 9P2000.u
500 * 496 *
501 */ 497 */
502 498
503int 499int
504v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall, 500v9fs_serialize_fcall(struct v9fs_fcall *fcall, void *data, u32 datalen,
505 void *data, u32 datalen) 501 int extended)
506{ 502{
507 int i = 0; 503 int i = 0;
508 struct v9fs_stat *stat = NULL; 504 struct v9fs_stat *stat = NULL;
@@ -516,7 +512,7 @@ v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall,
516 return -EINVAL; 512 return -EINVAL;
517 } 513 }
518 514
519 fcall->size = v9fs_size_fcall(v9ses, fcall); 515 fcall->size = v9fs_size_fcall(fcall, extended);
520 516
521 buf_put_int32(bufp, fcall->size); 517 buf_put_int32(bufp, fcall->size);
522 buf_put_int8(bufp, fcall->id); 518 buf_put_int8(bufp, fcall->id);
@@ -591,31 +587,31 @@ v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall,
591 stat = fcall->params.twstat.stat; 587 stat = fcall->params.twstat.stat;
592 588
593 buf_put_int16(bufp, stat->size + 2); 589 buf_put_int16(bufp, stat->size + 2);
594 serialize_stat(v9ses, stat, bufp); 590 serialize_stat(stat, bufp, extended);
595 break; 591 break;
596 } 592 }
597 593
598 if (buf_check_overflow(bufp)) 594 if (buf_check_overflow(bufp)) {
595 dprintk(DEBUG_ERROR, "buffer overflow\n");
599 return -EIO; 596 return -EIO;
597 }
600 598
601 return fcall->size; 599 return fcall->size;
602} 600}
603 601
604/** 602/**
605 * deserialize_fcall - unmarshal a response 603 * deserialize_fcall - unmarshal a response
606 * @v9ses: session information
607 * @msgsize: size of rcall message
608 * @buf: recieved buffer 604 * @buf: recieved buffer
609 * @buflen: length of received buffer 605 * @buflen: length of received buffer
610 * @rcall: fcall structure to populate 606 * @rcall: fcall structure to populate
611 * @rcalllen: length of fcall structure to populate 607 * @rcalllen: length of fcall structure to populate
608 * @extended: non-zero if 9P2000.u
612 * 609 *
613 */ 610 */
614 611
615int 612int
616v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize, 613v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall,
617 void *buf, u32 buflen, struct v9fs_fcall *rcall, 614 int rcalllen, int extended)
618 int rcalllen)
619{ 615{
620 616
621 struct cbuf buffer; 617 struct cbuf buffer;
@@ -628,7 +624,7 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
628 buf_init(dbufp, (char *)rcall + sizeof(struct v9fs_fcall), 624 buf_init(dbufp, (char *)rcall + sizeof(struct v9fs_fcall),
629 rcalllen - sizeof(struct v9fs_fcall)); 625 rcalllen - sizeof(struct v9fs_fcall));
630 626
631 rcall->size = msgsize; 627 rcall->size = buf_get_int32(bufp);
632 rcall->id = buf_get_int8(bufp); 628 rcall->id = buf_get_int8(bufp);
633 rcall->tag = buf_get_int16(bufp); 629 rcall->tag = buf_get_int16(bufp);
634 630
@@ -651,6 +647,12 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
651 break; 647 break;
652 case RWALK: 648 case RWALK:
653 rcall->params.rwalk.nwqid = buf_get_int16(bufp); 649 rcall->params.rwalk.nwqid = buf_get_int16(bufp);
650 if (rcall->params.rwalk.nwqid > 16) {
651 eprintk(KERN_ERR, "Rwalk with more than 16 qids: %d\n",
652 rcall->params.rwalk.nwqid);
653 return -EPROTO;
654 }
655
654 rcall->params.rwalk.wqids = buf_alloc(dbufp, 656 rcall->params.rwalk.wqids = buf_alloc(dbufp,
655 rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid)); 657 rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid));
656 if (rcall->params.rwalk.wqids) 658 if (rcall->params.rwalk.wqids)
@@ -690,19 +692,21 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
690 case RSTAT: 692 case RSTAT:
691 buf_get_int16(bufp); 693 buf_get_int16(bufp);
692 rcall->params.rstat.stat = 694 rcall->params.rstat.stat =
693 deserialize_statb(v9ses, bufp, dbufp); 695 deserialize_statb(bufp, dbufp, extended);
694 break; 696 break;
695 case RWSTAT: 697 case RWSTAT:
696 break; 698 break;
697 case RERROR: 699 case RERROR:
698 rcall->params.rerror.error = buf_get_stringb(bufp, dbufp); 700 rcall->params.rerror.error = buf_get_stringb(bufp, dbufp);
699 if (v9ses->extended) 701 if (extended)
700 rcall->params.rerror.errno = buf_get_int16(bufp); 702 rcall->params.rerror.errno = buf_get_int16(bufp);
701 break; 703 break;
702 } 704 }
703 705
704 if (buf_check_overflow(bufp) || buf_check_overflow(dbufp)) 706 if (buf_check_overflow(bufp) || buf_check_overflow(dbufp)) {
707 dprintk(DEBUG_ERROR, "buffer overflow\n");
705 return -EIO; 708 return -EIO;
709 }
706 710
707 return rcall->size; 711 return rcall->size;
708} 712}