@@ -464,86 +464,20 @@ static void encode_setxattr(struct xdr_stream *xdr,
464464 xdr_write_pages (xdr , arg -> xattr_pages , 0 , arg -> xattr_len );
465465}
466466
467- static int decode_setxattr (struct xdr_stream * xdr ,
468- struct nfs4_change_info * cinfo )
469- {
470- int status ;
471-
472- status = decode_op_hdr (xdr , OP_SETXATTR );
473- if (status )
474- goto out ;
475- status = decode_change_info (xdr , cinfo );
476- out :
477- return status ;
478- }
479-
480-
481467static void encode_getxattr (struct xdr_stream * xdr , const char * name ,
482468 struct compound_hdr * hdr )
483469{
484470 encode_op_hdr (xdr , OP_GETXATTR , decode_getxattr_maxsz , hdr );
485471 encode_string (xdr , strlen (name ), name );
486472}
487473
488- static int decode_getxattr (struct xdr_stream * xdr ,
489- struct nfs42_getxattrres * res ,
490- struct rpc_rqst * req )
491- {
492- int status ;
493- __be32 * p ;
494- u32 len , rdlen ;
495-
496- status = decode_op_hdr (xdr , OP_GETXATTR );
497- if (status )
498- return status ;
499-
500- p = xdr_inline_decode (xdr , 4 );
501- if (unlikely (!p ))
502- return - EIO ;
503-
504- len = be32_to_cpup (p );
505-
506- /*
507- * Only check against the page length here. The actual
508- * requested length may be smaller, but that is only
509- * checked against after possibly caching a valid reply.
510- */
511- if (len > req -> rq_rcv_buf .page_len )
512- return - ERANGE ;
513-
514- res -> xattr_len = len ;
515-
516- if (len > 0 ) {
517- rdlen = xdr_read_pages (xdr , len );
518- if (rdlen < len )
519- return - EIO ;
520- }
521-
522- return 0 ;
523- }
524-
525474static void encode_removexattr (struct xdr_stream * xdr , const char * name ,
526475 struct compound_hdr * hdr )
527476{
528477 encode_op_hdr (xdr , OP_REMOVEXATTR , decode_removexattr_maxsz , hdr );
529478 encode_string (xdr , strlen (name ), name );
530479}
531480
532-
533- static int decode_removexattr (struct xdr_stream * xdr ,
534- struct nfs4_change_info * cinfo )
535- {
536- int status ;
537-
538- status = decode_op_hdr (xdr , OP_REMOVEXATTR );
539- if (status )
540- goto out ;
541-
542- status = decode_change_info (xdr , cinfo );
543- out :
544- return status ;
545- }
546-
547481static void encode_listxattrs (struct xdr_stream * xdr ,
548482 const struct nfs42_listxattrsargs * arg ,
549483 struct compound_hdr * hdr )
@@ -565,104 +499,6 @@ static void encode_listxattrs(struct xdr_stream *xdr,
565499 * p = cpu_to_be32 (arg -> count + 8 + 4 );
566500}
567501
568- static int decode_listxattrs (struct xdr_stream * xdr ,
569- struct nfs42_listxattrsres * res )
570- {
571- int status ;
572- __be32 * p ;
573- u32 count , len , ulen ;
574- size_t left , copied ;
575- char * buf ;
576-
577- status = decode_op_hdr (xdr , OP_LISTXATTRS );
578- if (status ) {
579- /*
580- * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
581- * should be translated to ERANGE.
582- */
583- if (status == - ETOOSMALL )
584- status = - ERANGE ;
585- /*
586- * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
587- * should be translated to success with zero-length reply.
588- */
589- if (status == - ENODATA ) {
590- res -> eof = true;
591- status = 0 ;
592- }
593- goto out ;
594- }
595-
596- p = xdr_inline_decode (xdr , 8 );
597- if (unlikely (!p ))
598- return - EIO ;
599-
600- xdr_decode_hyper (p , & res -> cookie );
601-
602- p = xdr_inline_decode (xdr , 4 );
603- if (unlikely (!p ))
604- return - EIO ;
605-
606- left = res -> xattr_len ;
607- buf = res -> xattr_buf ;
608-
609- count = be32_to_cpup (p );
610- copied = 0 ;
611-
612- /*
613- * We have asked for enough room to encode the maximum number
614- * of possible attribute names, so everything should fit.
615- *
616- * But, don't rely on that assumption. Just decode entries
617- * until they don't fit anymore, just in case the server did
618- * something odd.
619- */
620- while (count -- ) {
621- p = xdr_inline_decode (xdr , 4 );
622- if (unlikely (!p ))
623- return - EIO ;
624-
625- len = be32_to_cpup (p );
626- if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN )) {
627- status = - ERANGE ;
628- goto out ;
629- }
630-
631- p = xdr_inline_decode (xdr , len );
632- if (unlikely (!p ))
633- return - EIO ;
634-
635- ulen = len + XATTR_USER_PREFIX_LEN + 1 ;
636- if (buf ) {
637- if (ulen > left ) {
638- status = - ERANGE ;
639- goto out ;
640- }
641-
642- memcpy (buf , XATTR_USER_PREFIX , XATTR_USER_PREFIX_LEN );
643- memcpy (buf + XATTR_USER_PREFIX_LEN , p , len );
644-
645- buf [ulen - 1 ] = 0 ;
646- buf += ulen ;
647- left -= ulen ;
648- }
649- copied += ulen ;
650- }
651-
652- p = xdr_inline_decode (xdr , 4 );
653- if (unlikely (!p ))
654- return - EIO ;
655-
656- res -> eof = be32_to_cpup (p );
657- res -> copied = copied ;
658-
659- out :
660- if (status == - ERANGE && res -> xattr_len == XATTR_LIST_MAX )
661- status = - E2BIG ;
662-
663- return status ;
664- }
665-
666502/*
667503 * Encode ALLOCATE request
668504 */
@@ -1192,6 +1028,168 @@ static int decode_layouterror(struct xdr_stream *xdr)
11921028 return decode_op_hdr (xdr , OP_LAYOUTERROR );
11931029}
11941030
1031+ static int decode_setxattr (struct xdr_stream * xdr ,
1032+ struct nfs4_change_info * cinfo )
1033+ {
1034+ int status ;
1035+
1036+ status = decode_op_hdr (xdr , OP_SETXATTR );
1037+ if (status )
1038+ goto out ;
1039+ status = decode_change_info (xdr , cinfo );
1040+ out :
1041+ return status ;
1042+ }
1043+
1044+ static int decode_getxattr (struct xdr_stream * xdr ,
1045+ struct nfs42_getxattrres * res ,
1046+ struct rpc_rqst * req )
1047+ {
1048+ int status ;
1049+ __be32 * p ;
1050+ u32 len , rdlen ;
1051+
1052+ status = decode_op_hdr (xdr , OP_GETXATTR );
1053+ if (status )
1054+ return status ;
1055+
1056+ p = xdr_inline_decode (xdr , 4 );
1057+ if (unlikely (!p ))
1058+ return - EIO ;
1059+
1060+ len = be32_to_cpup (p );
1061+
1062+ /*
1063+ * Only check against the page length here. The actual
1064+ * requested length may be smaller, but that is only
1065+ * checked against after possibly caching a valid reply.
1066+ */
1067+ if (len > req -> rq_rcv_buf .page_len )
1068+ return - ERANGE ;
1069+
1070+ res -> xattr_len = len ;
1071+
1072+ if (len > 0 ) {
1073+ rdlen = xdr_read_pages (xdr , len );
1074+ if (rdlen < len )
1075+ return - EIO ;
1076+ }
1077+
1078+ return 0 ;
1079+ }
1080+
1081+ static int decode_removexattr (struct xdr_stream * xdr ,
1082+ struct nfs4_change_info * cinfo )
1083+ {
1084+ int status ;
1085+
1086+ status = decode_op_hdr (xdr , OP_REMOVEXATTR );
1087+ if (status )
1088+ goto out ;
1089+
1090+ status = decode_change_info (xdr , cinfo );
1091+ out :
1092+ return status ;
1093+ }
1094+
1095+ static int decode_listxattrs (struct xdr_stream * xdr ,
1096+ struct nfs42_listxattrsres * res )
1097+ {
1098+ int status ;
1099+ __be32 * p ;
1100+ u32 count , len , ulen ;
1101+ size_t left , copied ;
1102+ char * buf ;
1103+
1104+ status = decode_op_hdr (xdr , OP_LISTXATTRS );
1105+ if (status ) {
1106+ /*
1107+ * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
1108+ * should be translated to ERANGE.
1109+ */
1110+ if (status == - ETOOSMALL )
1111+ status = - ERANGE ;
1112+ /*
1113+ * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
1114+ * should be translated to success with zero-length reply.
1115+ */
1116+ if (status == - ENODATA ) {
1117+ res -> eof = true;
1118+ status = 0 ;
1119+ }
1120+ goto out ;
1121+ }
1122+
1123+ p = xdr_inline_decode (xdr , 8 );
1124+ if (unlikely (!p ))
1125+ return - EIO ;
1126+
1127+ xdr_decode_hyper (p , & res -> cookie );
1128+
1129+ p = xdr_inline_decode (xdr , 4 );
1130+ if (unlikely (!p ))
1131+ return - EIO ;
1132+
1133+ left = res -> xattr_len ;
1134+ buf = res -> xattr_buf ;
1135+
1136+ count = be32_to_cpup (p );
1137+ copied = 0 ;
1138+
1139+ /*
1140+ * We have asked for enough room to encode the maximum number
1141+ * of possible attribute names, so everything should fit.
1142+ *
1143+ * But, don't rely on that assumption. Just decode entries
1144+ * until they don't fit anymore, just in case the server did
1145+ * something odd.
1146+ */
1147+ while (count -- ) {
1148+ p = xdr_inline_decode (xdr , 4 );
1149+ if (unlikely (!p ))
1150+ return - EIO ;
1151+
1152+ len = be32_to_cpup (p );
1153+ if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN )) {
1154+ status = - ERANGE ;
1155+ goto out ;
1156+ }
1157+
1158+ p = xdr_inline_decode (xdr , len );
1159+ if (unlikely (!p ))
1160+ return - EIO ;
1161+
1162+ ulen = len + XATTR_USER_PREFIX_LEN + 1 ;
1163+ if (buf ) {
1164+ if (ulen > left ) {
1165+ status = - ERANGE ;
1166+ goto out ;
1167+ }
1168+
1169+ memcpy (buf , XATTR_USER_PREFIX , XATTR_USER_PREFIX_LEN );
1170+ memcpy (buf + XATTR_USER_PREFIX_LEN , p , len );
1171+
1172+ buf [ulen - 1 ] = 0 ;
1173+ buf += ulen ;
1174+ left -= ulen ;
1175+ }
1176+ copied += ulen ;
1177+ }
1178+
1179+ p = xdr_inline_decode (xdr , 4 );
1180+ if (unlikely (!p ))
1181+ return - EIO ;
1182+
1183+ res -> eof = be32_to_cpup (p );
1184+ res -> copied = copied ;
1185+
1186+ out :
1187+ if (status == - ERANGE && res -> xattr_len == XATTR_LIST_MAX )
1188+ status = - E2BIG ;
1189+
1190+ return status ;
1191+ }
1192+
11951193/*
11961194 * Decode ALLOCATE request
11971195 */
0 commit comments