aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs3xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs3xdr.c')
-rw-r--r--fs/nfs/nfs3xdr.c833
1 files changed, 830 insertions, 3 deletions
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index f6cc60f06da..3d1043f7667 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -37,6 +37,7 @@
37#define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) 37#define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
38#define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) 38#define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
39#define NFS3_fattr_sz (21) 39#define NFS3_fattr_sz (21)
40#define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2)
40#define NFS3_wcc_attr_sz (6) 41#define NFS3_wcc_attr_sz (6)
41#define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz) 42#define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
42#define NFS3_post_op_attr_sz (1+NFS3_fattr_sz) 43#define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
@@ -59,7 +60,8 @@
59#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) 60#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
60#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) 61#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
61#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) 62#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
62#define NFS3_readdirargs_sz (NFS3_fh_sz+2) 63#define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
64#define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
63#define NFS3_commitargs_sz (NFS3_fh_sz+3) 65#define NFS3_commitargs_sz (NFS3_fh_sz+3)
64 66
65#define NFS3_attrstat_sz (1+NFS3_fattr_sz) 67#define NFS3_attrstat_sz (1+NFS3_fattr_sz)
@@ -108,6 +110,22 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
108} 110}
109 111
110/* 112/*
113 * While encoding arguments, set up the reply buffer in advance to
114 * receive reply data directly into the page cache.
115 */
116static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
117 unsigned int base, unsigned int len,
118 unsigned int bufsize)
119{
120 struct rpc_auth *auth = req->rq_cred->cr_auth;
121 unsigned int replen;
122
123 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
124 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
125}
126
127
128/*
111 * Common NFS XDR functions as inlines 129 * Common NFS XDR functions as inlines
112 */ 130 */
113static inline __be32 * 131static inline __be32 *
@@ -153,7 +171,7 @@ out_overflow:
153 * Encode/decode time. 171 * Encode/decode time.
154 */ 172 */
155static inline __be32 * 173static inline __be32 *
156xdr_encode_time3(__be32 *p, struct timespec *timep) 174xdr_encode_time3(__be32 *p, const struct timespec *timep)
157{ 175{
158 *p++ = htonl(timep->tv_sec); 176 *p++ = htonl(timep->tv_sec);
159 *p++ = htonl(timep->tv_nsec); 177 *p++ = htonl(timep->tv_nsec);
@@ -205,7 +223,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
205} 223}
206 224
207static inline __be32 * 225static inline __be32 *
208xdr_encode_sattr(__be32 *p, struct iattr *attr) 226xdr_encode_sattr(__be32 *p, const struct iattr *attr)
209{ 227{
210 if (attr->ia_valid & ATTR_MODE) { 228 if (attr->ia_valid & ATTR_MODE) {
211 *p++ = xdr_one; 229 *p++ = xdr_one;
@@ -306,6 +324,243 @@ xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
306 return xdr_decode_post_op_attr(p, fattr); 324 return xdr_decode_post_op_attr(p, fattr);
307} 325}
308 326
327
328/*
329 * Encode/decode NFSv3 basic data types
330 *
331 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
332 * "NFS Version 3 Protocol Specification".
333 *
334 * Not all basic data types have their own encoding and decoding
335 * functions. For run-time efficiency, some data types are encoded
336 * or decoded inline.
337 */
338
339static void encode_uint32(struct xdr_stream *xdr, u32 value)
340{
341 __be32 *p = xdr_reserve_space(xdr, 4);
342 *p = cpu_to_be32(value);
343}
344
345/*
346 * filename3
347 *
348 * typedef string filename3<>;
349 */
350static void encode_filename3(struct xdr_stream *xdr,
351 const char *name, u32 length)
352{
353 __be32 *p;
354
355 BUG_ON(length > NFS3_MAXNAMLEN);
356 p = xdr_reserve_space(xdr, 4 + length);
357 xdr_encode_opaque(p, name, length);
358}
359
360/*
361 * nfspath3
362 *
363 * typedef string nfspath3<>;
364 */
365static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
366 const u32 length)
367{
368 BUG_ON(length > NFS3_MAXPATHLEN);
369 encode_uint32(xdr, length);
370 xdr_write_pages(xdr, pages, 0, length);
371}
372
373/*
374 * cookie3
375 *
376 * typedef uint64 cookie3
377 */
378static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
379{
380 return xdr_encode_hyper(p, cookie);
381}
382
383/*
384 * cookieverf3
385 *
386 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
387 */
388static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
389{
390 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
391 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
392}
393
394/*
395 * createverf3
396 *
397 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
398 */
399static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
400{
401 __be32 *p;
402
403 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
404 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
405}
406
407/*
408 * ftype3
409 *
410 * enum ftype3 {
411 * NF3REG = 1,
412 * NF3DIR = 2,
413 * NF3BLK = 3,
414 * NF3CHR = 4,
415 * NF3LNK = 5,
416 * NF3SOCK = 6,
417 * NF3FIFO = 7
418 * };
419 */
420static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
421{
422 BUG_ON(type > NF3FIFO);
423 encode_uint32(xdr, type);
424}
425
426/*
427 * specdata3
428 *
429 * struct specdata3 {
430 * uint32 specdata1;
431 * uint32 specdata2;
432 * };
433 */
434static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
435{
436 __be32 *p;
437
438 p = xdr_reserve_space(xdr, 8);
439 *p++ = cpu_to_be32(MAJOR(rdev));
440 *p = cpu_to_be32(MINOR(rdev));
441}
442
443/*
444 * nfs_fh3
445 *
446 * struct nfs_fh3 {
447 * opaque data<NFS3_FHSIZE>;
448 * };
449 */
450static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
451{
452 __be32 *p;
453
454 BUG_ON(fh->size > NFS3_FHSIZE);
455 p = xdr_reserve_space(xdr, 4 + fh->size);
456 xdr_encode_opaque(p, fh->data, fh->size);
457}
458
459/*
460 * sattr3
461 *
462 * enum time_how {
463 * DONT_CHANGE = 0,
464 * SET_TO_SERVER_TIME = 1,
465 * SET_TO_CLIENT_TIME = 2
466 * };
467 *
468 * union set_mode3 switch (bool set_it) {
469 * case TRUE:
470 * mode3 mode;
471 * default:
472 * void;
473 * };
474 *
475 * union set_uid3 switch (bool set_it) {
476 * case TRUE:
477 * uid3 uid;
478 * default:
479 * void;
480 * };
481 *
482 * union set_gid3 switch (bool set_it) {
483 * case TRUE:
484 * gid3 gid;
485 * default:
486 * void;
487 * };
488 *
489 * union set_size3 switch (bool set_it) {
490 * case TRUE:
491 * size3 size;
492 * default:
493 * void;
494 * };
495 *
496 * union set_atime switch (time_how set_it) {
497 * case SET_TO_CLIENT_TIME:
498 * nfstime3 atime;
499 * default:
500 * void;
501 * };
502 *
503 * union set_mtime switch (time_how set_it) {
504 * case SET_TO_CLIENT_TIME:
505 * nfstime3 mtime;
506 * default:
507 * void;
508 * };
509 *
510 * struct sattr3 {
511 * set_mode3 mode;
512 * set_uid3 uid;
513 * set_gid3 gid;
514 * set_size3 size;
515 * set_atime atime;
516 * set_mtime mtime;
517 * };
518 */
519static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
520{
521 u32 nbytes;
522 __be32 *p;
523
524 /*
525 * In order to make only a single xdr_reserve_space() call,
526 * pre-compute the total number of bytes to be reserved.
527 * Six boolean values, one for each set_foo field, are always
528 * present in the encoded result, so start there.
529 */
530 nbytes = 6 * 4;
531 if (attr->ia_valid & ATTR_MODE)
532 nbytes += 4;
533 if (attr->ia_valid & ATTR_UID)
534 nbytes += 4;
535 if (attr->ia_valid & ATTR_GID)
536 nbytes += 4;
537 if (attr->ia_valid & ATTR_SIZE)
538 nbytes += 8;
539 if (attr->ia_valid & ATTR_ATIME_SET)
540 nbytes += 8;
541 if (attr->ia_valid & ATTR_MTIME_SET)
542 nbytes += 8;
543 p = xdr_reserve_space(xdr, nbytes);
544
545 xdr_encode_sattr(p, attr);
546}
547
548/*
549 * diropargs3
550 *
551 * struct diropargs3 {
552 * nfs_fh3 dir;
553 * filename3 name;
554 * };
555 */
556static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
557 const char *name, u32 length)
558{
559 encode_nfs_fh3(xdr, fh);
560 encode_filename3(xdr, name, length);
561}
562
563
309/* 564/*
310 * NFS encode functions 565 * NFS encode functions
311 */ 566 */
@@ -322,6 +577,23 @@ nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
322} 577}
323 578
324/* 579/*
580 * 3.3.1 GETATTR3args
581 *
582 * struct GETATTR3args {
583 * nfs_fh3 object;
584 * };
585 */
586static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
587 const struct nfs_fh *fh)
588{
589 struct xdr_stream xdr;
590
591 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
592 encode_nfs_fh3(&xdr, fh);
593 return 0;
594}
595
596/*
325 * Encode SETATTR arguments 597 * Encode SETATTR arguments
326 */ 598 */
327static int 599static int
@@ -337,6 +609,49 @@ nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
337} 609}
338 610
339/* 611/*
612 * 3.3.2 SETATTR3args
613 *
614 * union sattrguard3 switch (bool check) {
615 * case TRUE:
616 * nfstime3 obj_ctime;
617 * case FALSE:
618 * void;
619 * };
620 *
621 * struct SETATTR3args {
622 * nfs_fh3 object;
623 * sattr3 new_attributes;
624 * sattrguard3 guard;
625 * };
626 */
627static void encode_sattrguard3(struct xdr_stream *xdr,
628 const struct nfs3_sattrargs *args)
629{
630 __be32 *p;
631
632 if (args->guard) {
633 p = xdr_reserve_space(xdr, 4 + 8);
634 *p++ = xdr_one;
635 xdr_encode_time3(p, &args->guardtime);
636 } else {
637 p = xdr_reserve_space(xdr, 4);
638 *p = xdr_zero;
639 }
640}
641
642static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
643 const struct nfs3_sattrargs *args)
644{
645 struct xdr_stream xdr;
646
647 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
648 encode_nfs_fh3(&xdr, args->fh);
649 encode_sattr3(&xdr, args->sattr);
650 encode_sattrguard3(&xdr, args);
651 return 0;
652}
653
654/*
340 * Encode directory ops argument 655 * Encode directory ops argument
341 */ 656 */
342static int 657static int
@@ -349,6 +664,23 @@ nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
349} 664}
350 665
351/* 666/*
667 * 3.3.3 LOOKUP3args
668 *
669 * struct LOOKUP3args {
670 * diropargs3 what;
671 * };
672 */
673static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
674 const struct nfs3_diropargs *args)
675{
676 struct xdr_stream xdr;
677
678 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
679 encode_diropargs3(&xdr, args->fh, args->name, args->len);
680 return 0;
681}
682
683/*
352 * Encode REMOVE argument 684 * Encode REMOVE argument
353 */ 685 */
354static int 686static int
@@ -373,6 +705,50 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg
373} 705}
374 706
375/* 707/*
708 * 3.3.4 ACCESS3args
709 *
710 * struct ACCESS3args {
711 * nfs_fh3 object;
712 * uint32 access;
713 * };
714 */
715static void encode_access3args(struct xdr_stream *xdr,
716 const struct nfs3_accessargs *args)
717{
718 encode_nfs_fh3(xdr, args->fh);
719 encode_uint32(xdr, args->access);
720}
721
722static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
723 const struct nfs3_accessargs *args)
724{
725 struct xdr_stream xdr;
726
727 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
728 encode_access3args(&xdr, args);
729 return 0;
730}
731
732/*
733 * 3.3.5 READLINK3args
734 *
735 * struct READLINK3args {
736 * nfs_fh3 symlink;
737 * };
738 */
739static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
740 const struct nfs3_readlinkargs *args)
741{
742 struct xdr_stream xdr;
743
744 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
745 encode_nfs_fh3(&xdr, args->fh);
746 prepare_reply_buffer(req, args->pages, args->pgbase,
747 args->pglen, NFS3_readlinkres_sz);
748 return 0;
749}
750
751/*
376 * Arguments to a READ call. Since we read data directly into the page 752 * Arguments to a READ call. Since we read data directly into the page
377 * cache, we also set up the reply iovec here so that iov[1] points 753 * cache, we also set up the reply iovec here so that iov[1] points
378 * exactly to the page we want to fetch. 754 * exactly to the page we want to fetch.
@@ -398,6 +774,40 @@ nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
398} 774}
399 775
400/* 776/*
777 * 3.3.6 READ3args
778 *
779 * struct READ3args {
780 * nfs_fh3 file;
781 * offset3 offset;
782 * count3 count;
783 * };
784 */
785static void encode_read3args(struct xdr_stream *xdr,
786 const struct nfs_readargs *args)
787{
788 __be32 *p;
789
790 encode_nfs_fh3(xdr, args->fh);
791
792 p = xdr_reserve_space(xdr, 8 + 4);
793 p = xdr_encode_hyper(p, args->offset);
794 *p = cpu_to_be32(args->count);
795}
796
797static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
798 const struct nfs_readargs *args)
799{
800 struct xdr_stream xdr;
801
802 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
803 encode_read3args(&xdr, args);
804 prepare_reply_buffer(req, args->pages, args->pgbase,
805 args->count, NFS3_readres_sz);
806 req->rq_rcv_buf.flags |= XDRBUF_READ;
807 return 0;
808}
809
810/*
401 * Write arguments. Splice the buffer to be written into the iovec. 811 * Write arguments. Splice the buffer to be written into the iovec.
402 */ 812 */
403static int 813static int
@@ -420,6 +830,52 @@ nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
420} 830}
421 831
422/* 832/*
833 * 3.3.7 WRITE3args
834 *
835 * enum stable_how {
836 * UNSTABLE = 0,
837 * DATA_SYNC = 1,
838 * FILE_SYNC = 2
839 * };
840 *
841 * struct WRITE3args {
842 * nfs_fh3 file;
843 * offset3 offset;
844 * count3 count;
845 * stable_how stable;
846 * opaque data<>;
847 * };
848 */
849static void encode_write3args(struct xdr_stream *xdr,
850 const struct nfs_writeargs *args)
851{
852 __be32 *p;
853
854 encode_nfs_fh3(xdr, args->fh);
855
856 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
857 p = xdr_encode_hyper(p, args->offset);
858 *p++ = cpu_to_be32(args->count);
859
860 BUG_ON(args->stable > NFS_FILE_SYNC);
861 *p++ = cpu_to_be32(args->stable);
862
863 *p = cpu_to_be32(args->count);
864 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
865}
866
867static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
868 const struct nfs_writeargs *args)
869{
870 struct xdr_stream xdr;
871
872 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
873 encode_write3args(&xdr, args);
874 xdr.buf->flags |= XDRBUF_WRITE;
875 return 0;
876}
877
878/*
423 * Encode CREATE arguments 879 * Encode CREATE arguments
424 */ 880 */
425static int 881static int
@@ -440,6 +896,56 @@ nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *arg
440} 896}
441 897
442/* 898/*
899 * 3.3.8 CREATE3args
900 *
901 * enum createmode3 {
902 * UNCHECKED = 0,
903 * GUARDED = 1,
904 * EXCLUSIVE = 2
905 * };
906 *
907 * union createhow3 switch (createmode3 mode) {
908 * case UNCHECKED:
909 * case GUARDED:
910 * sattr3 obj_attributes;
911 * case EXCLUSIVE:
912 * createverf3 verf;
913 * };
914 *
915 * struct CREATE3args {
916 * diropargs3 where;
917 * createhow3 how;
918 * };
919 */
920static void encode_createhow3(struct xdr_stream *xdr,
921 const struct nfs3_createargs *args)
922{
923 encode_uint32(xdr, args->createmode);
924 switch (args->createmode) {
925 case NFS3_CREATE_UNCHECKED:
926 case NFS3_CREATE_GUARDED:
927 encode_sattr3(xdr, args->sattr);
928 break;
929 case NFS3_CREATE_EXCLUSIVE:
930 encode_createverf3(xdr, args->verifier);
931 break;
932 default:
933 BUG();
934 }
935}
936
937static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
938 const struct nfs3_createargs *args)
939{
940 struct xdr_stream xdr;
941
942 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
943 encode_diropargs3(&xdr, args->fh, args->name, args->len);
944 encode_createhow3(&xdr, args);
945 return 0;
946}
947
948/*
443 * Encode MKDIR arguments 949 * Encode MKDIR arguments
444 */ 950 */
445static int 951static int
@@ -453,6 +959,25 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
453} 959}
454 960
455/* 961/*
962 * 3.3.9 MKDIR3args
963 *
964 * struct MKDIR3args {
965 * diropargs3 where;
966 * sattr3 attributes;
967 * };
968 */
969static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
970 const struct nfs3_mkdirargs *args)
971{
972 struct xdr_stream xdr;
973
974 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
975 encode_diropargs3(&xdr, args->fh, args->name, args->len);
976 encode_sattr3(&xdr, args->sattr);
977 return 0;
978}
979
980/*
456 * Encode SYMLINK arguments 981 * Encode SYMLINK arguments
457 */ 982 */
458static int 983static int
@@ -470,6 +995,37 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *a
470} 995}
471 996
472/* 997/*
998 * 3.3.10 SYMLINK3args
999 *
1000 * struct symlinkdata3 {
1001 * sattr3 symlink_attributes;
1002 * nfspath3 symlink_data;
1003 * };
1004 *
1005 * struct SYMLINK3args {
1006 * diropargs3 where;
1007 * symlinkdata3 symlink;
1008 * };
1009 */
1010static void encode_symlinkdata3(struct xdr_stream *xdr,
1011 const struct nfs3_symlinkargs *args)
1012{
1013 encode_sattr3(xdr, args->sattr);
1014 encode_nfspath3(xdr, args->pages, args->pathlen);
1015}
1016
1017static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1018 const struct nfs3_symlinkargs *args)
1019{
1020 struct xdr_stream xdr;
1021
1022 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1023 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1024 encode_symlinkdata3(&xdr, args);
1025 return 0;
1026}
1027
1028/*
473 * Encode MKNOD arguments 1029 * Encode MKNOD arguments
474 */ 1030 */
475static int 1031static int
@@ -489,6 +1045,86 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
489} 1045}
490 1046
491/* 1047/*
1048 * 3.3.11 MKNOD3args
1049 *
1050 * struct devicedata3 {
1051 * sattr3 dev_attributes;
1052 * specdata3 spec;
1053 * };
1054 *
1055 * union mknoddata3 switch (ftype3 type) {
1056 * case NF3CHR:
1057 * case NF3BLK:
1058 * devicedata3 device;
1059 * case NF3SOCK:
1060 * case NF3FIFO:
1061 * sattr3 pipe_attributes;
1062 * default:
1063 * void;
1064 * };
1065 *
1066 * struct MKNOD3args {
1067 * diropargs3 where;
1068 * mknoddata3 what;
1069 * };
1070 */
1071static void encode_devicedata3(struct xdr_stream *xdr,
1072 const struct nfs3_mknodargs *args)
1073{
1074 encode_sattr3(xdr, args->sattr);
1075 encode_specdata3(xdr, args->rdev);
1076}
1077
1078static void encode_mknoddata3(struct xdr_stream *xdr,
1079 const struct nfs3_mknodargs *args)
1080{
1081 encode_ftype3(xdr, args->type);
1082 switch (args->type) {
1083 case NF3CHR:
1084 case NF3BLK:
1085 encode_devicedata3(xdr, args);
1086 break;
1087 case NF3SOCK:
1088 case NF3FIFO:
1089 encode_sattr3(xdr, args->sattr);
1090 break;
1091 case NF3REG:
1092 case NF3DIR:
1093 break;
1094 default:
1095 BUG();
1096 }
1097}
1098
1099static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1100 const struct nfs3_mknodargs *args)
1101{
1102 struct xdr_stream xdr;
1103
1104 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1105 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1106 encode_mknoddata3(&xdr, args);
1107 return 0;
1108}
1109
1110/*
1111 * 3.3.12 REMOVE3args
1112 *
1113 * struct REMOVE3args {
1114 * diropargs3 object;
1115 * };
1116 */
1117static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1118 const struct nfs_removeargs *args)
1119{
1120 struct xdr_stream xdr;
1121
1122 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1123 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1124 return 0;
1125}
1126
1127/*
492 * Encode RENAME arguments 1128 * Encode RENAME arguments
493 */ 1129 */
494static int 1130static int
@@ -503,6 +1139,27 @@ nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args
503} 1139}
504 1140
505/* 1141/*
1142 * 3.3.14 RENAME3args
1143 *
1144 * struct RENAME3args {
1145 * diropargs3 from;
1146 * diropargs3 to;
1147 * };
1148 */
1149static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1150 const struct nfs_renameargs *args)
1151{
1152 const struct qstr *old = args->old_name;
1153 const struct qstr *new = args->new_name;
1154 struct xdr_stream xdr;
1155
1156 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1157 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1158 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1159 return 0;
1160}
1161
1162/*
506 * Encode LINK arguments 1163 * Encode LINK arguments
507 */ 1164 */
508static int 1165static int
@@ -516,6 +1173,25 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
516} 1173}
517 1174
518/* 1175/*
1176 * 3.3.15 LINK3args
1177 *
1178 * struct LINK3args {
1179 * nfs_fh3 file;
1180 * diropargs3 link;
1181 * };
1182 */
1183static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1184 const struct nfs3_linkargs *args)
1185{
1186 struct xdr_stream xdr;
1187
1188 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1189 encode_nfs_fh3(&xdr, args->fromfh);
1190 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1191 return 0;
1192}
1193
1194/*
519 * Encode arguments to readdir call 1195 * Encode arguments to readdir call
520 */ 1196 */
521static int 1197static int
@@ -544,6 +1220,84 @@ nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *a
544} 1220}
545 1221
546/* 1222/*
1223 * 3.3.16 READDIR3args
1224 *
1225 * struct READDIR3args {
1226 * nfs_fh3 dir;
1227 * cookie3 cookie;
1228 * cookieverf3 cookieverf;
1229 * count3 count;
1230 * };
1231 */
1232static void encode_readdir3args(struct xdr_stream *xdr,
1233 const struct nfs3_readdirargs *args)
1234{
1235 __be32 *p;
1236
1237 encode_nfs_fh3(xdr, args->fh);
1238
1239 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1240 p = xdr_encode_cookie3(p, args->cookie);
1241 p = xdr_encode_cookieverf3(p, args->verf);
1242 *p = cpu_to_be32(args->count);
1243}
1244
1245static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1246 const struct nfs3_readdirargs *args)
1247{
1248 struct xdr_stream xdr;
1249
1250 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1251 encode_readdir3args(&xdr, args);
1252 prepare_reply_buffer(req, args->pages, 0,
1253 args->count, NFS3_readdirres_sz);
1254 return 0;
1255}
1256
1257/*
1258 * 3.3.17 READDIRPLUS3args
1259 *
1260 * struct READDIRPLUS3args {
1261 * nfs_fh3 dir;
1262 * cookie3 cookie;
1263 * cookieverf3 cookieverf;
1264 * count3 dircount;
1265 * count3 maxcount;
1266 * };
1267 */
1268static void encode_readdirplus3args(struct xdr_stream *xdr,
1269 const struct nfs3_readdirargs *args)
1270{
1271 __be32 *p;
1272
1273 encode_nfs_fh3(xdr, args->fh);
1274
1275 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1276 p = xdr_encode_cookie3(p, args->cookie);
1277 p = xdr_encode_cookieverf3(p, args->verf);
1278
1279 /*
1280 * readdirplus: need dircount + buffer size.
1281 * We just make sure we make dircount big enough
1282 */
1283 *p++ = cpu_to_be32(args->count >> 3);
1284
1285 *p = cpu_to_be32(args->count);
1286}
1287
1288static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1289 const struct nfs3_readdirargs *args)
1290{
1291 struct xdr_stream xdr;
1292
1293 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1294 encode_readdirplus3args(&xdr, args);
1295 prepare_reply_buffer(req, args->pages, 0,
1296 args->count, NFS3_readdirres_sz);
1297 return 0;
1298}
1299
1300/*
547 * Decode the result of a readdir call. 1301 * Decode the result of a readdir call.
548 * We just check for syntactical correctness. 1302 * We just check for syntactical correctness.
549 */ 1303 */
@@ -674,6 +1428,37 @@ nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
674 return 0; 1428 return 0;
675} 1429}
676 1430
1431/*
1432 * 3.3.21 COMMIT3args
1433 *
1434 * struct COMMIT3args {
1435 * nfs_fh3 file;
1436 * offset3 offset;
1437 * count3 count;
1438 * };
1439 */
1440static void encode_commit3args(struct xdr_stream *xdr,
1441 const struct nfs_writeargs *args)
1442{
1443 __be32 *p;
1444
1445 encode_nfs_fh3(xdr, args->fh);
1446
1447 p = xdr_reserve_space(xdr, 8 + 4);
1448 p = xdr_encode_hyper(p, args->offset);
1449 *p = cpu_to_be32(args->count);
1450}
1451
1452static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1453 const struct nfs_writeargs *args)
1454{
1455 struct xdr_stream xdr;
1456
1457 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1458 encode_commit3args(&xdr, args);
1459 return 0;
1460}
1461
677#ifdef CONFIG_NFS_V3_ACL 1462#ifdef CONFIG_NFS_V3_ACL
678/* 1463/*
679 * Encode GETACL arguments 1464 * Encode GETACL arguments
@@ -699,6 +1484,21 @@ nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
699 return 0; 1484 return 0;
700} 1485}
701 1486
1487static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1488 const struct nfs3_getaclargs *args)
1489{
1490 struct xdr_stream xdr;
1491
1492 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1493 encode_nfs_fh3(&xdr, args->fh);
1494 encode_uint32(&xdr, args->mask);
1495 if (args->mask & (NFS_ACL | NFS_DFACL))
1496 prepare_reply_buffer(req, args->pages, 0,
1497 NFSACL_MAXPAGES << PAGE_SHIFT,
1498 ACL3_getaclres_sz);
1499 return 0;
1500}
1501
702/* 1502/*
703 * Encode SETACL arguments 1503 * Encode SETACL arguments
704 */ 1504 */
@@ -731,6 +1531,33 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
731 NFS_ACL_DEFAULT); 1531 NFS_ACL_DEFAULT);
732 return (err > 0) ? 0 : err; 1532 return (err > 0) ? 0 : err;
733} 1533}
1534
1535static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1536 const struct nfs3_setaclargs *args)
1537{
1538 struct xdr_stream xdr;
1539 unsigned int base;
1540 int error;
1541
1542 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1543 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1544 encode_uint32(&xdr, args->mask);
1545 if (args->npages != 0)
1546 xdr_write_pages(&xdr, args->pages, 0, args->len);
1547
1548 base = req->rq_slen;
1549 error = nfsacl_encode(xdr.buf, base, args->inode,
1550 (args->mask & NFS_ACL) ?
1551 args->acl_access : NULL, 1, 0);
1552 BUG_ON(error < 0);
1553 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1554 (args->mask & NFS_DFACL) ?
1555 args->acl_default : NULL, 1,
1556 NFS_ACL_DEFAULT);
1557 BUG_ON(error < 0);
1558 return 0;
1559}
1560
734#endif /* CONFIG_NFS_V3_ACL */ 1561#endif /* CONFIG_NFS_V3_ACL */
735 1562
736/* 1563/*