2929#define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
3030 XDR_QUADLEN(NFS4_STATEID_SIZE))
3131#define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
32+ #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \
33+ XDR_QUADLEN(NFS4_STATEID_SIZE) + \
34+ 1 + /* nl4_type */ \
35+ 1 + XDR_QUADLEN (NFS4_OPAQUE_LIMIT ))
36+ #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \
37+ 3 + /* cnr_lease_time */ \
38+ XDR_QUADLEN (NFS4_STATEID_SIZE ) + \
39+ 1 + /* Support 1 cnr_source_server */ \
40+ 1 + /* nl4_type */ \
41+ 1 + XDR_QUADLEN (NFS4_OPAQUE_LIMIT ))
3242#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
3343 encode_fallocate_maxsz)
3444#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
99109 decode_sequence_maxsz + \
100110 decode_putfh_maxsz + \
101111 decode_offload_cancel_maxsz)
112+ #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \
113+ encode_putfh_maxsz + \
114+ encode_copy_notify_maxsz)
115+ #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \
116+ decode_putfh_maxsz + \
117+ decode_copy_notify_maxsz)
102118#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
103119 encode_sequence_maxsz + \
104120 encode_putfh_maxsz + \
@@ -166,6 +182,26 @@ static void encode_allocate(struct xdr_stream *xdr,
166182 encode_fallocate (xdr , args );
167183}
168184
185+ static void encode_nl4_server (struct xdr_stream * xdr ,
186+ const struct nl4_server * ns )
187+ {
188+ encode_uint32 (xdr , ns -> nl4_type );
189+ switch (ns -> nl4_type ) {
190+ case NL4_NAME :
191+ case NL4_URL :
192+ encode_string (xdr , ns -> u .nl4_str_sz , ns -> u .nl4_str );
193+ break ;
194+ case NL4_NETADDR :
195+ encode_string (xdr , ns -> u .nl4_addr .netid_len ,
196+ ns -> u .nl4_addr .netid );
197+ encode_string (xdr , ns -> u .nl4_addr .addr_len ,
198+ ns -> u .nl4_addr .addr );
199+ break ;
200+ default :
201+ WARN_ON_ONCE (1 );
202+ }
203+ }
204+
169205static void encode_copy (struct xdr_stream * xdr ,
170206 const struct nfs42_copy_args * args ,
171207 struct compound_hdr * hdr )
@@ -191,6 +227,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr,
191227 encode_nfs4_stateid (xdr , & args -> osa_stateid );
192228}
193229
230+ static void encode_copy_notify (struct xdr_stream * xdr ,
231+ const struct nfs42_copy_notify_args * args ,
232+ struct compound_hdr * hdr )
233+ {
234+ encode_op_hdr (xdr , OP_COPY_NOTIFY , decode_copy_notify_maxsz , hdr );
235+ encode_nfs4_stateid (xdr , & args -> cna_src_stateid );
236+ encode_nl4_server (xdr , & args -> cna_dst );
237+ }
238+
194239static void encode_deallocate (struct xdr_stream * xdr ,
195240 const struct nfs42_falloc_args * args ,
196241 struct compound_hdr * hdr )
@@ -354,6 +399,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
354399 encode_nops (& hdr );
355400}
356401
402+ /*
403+ * Encode COPY_NOTIFY request
404+ */
405+ static void nfs4_xdr_enc_copy_notify (struct rpc_rqst * req ,
406+ struct xdr_stream * xdr ,
407+ const void * data )
408+ {
409+ const struct nfs42_copy_notify_args * args = data ;
410+ struct compound_hdr hdr = {
411+ .minorversion = nfs4_xdr_minorversion (& args -> cna_seq_args ),
412+ };
413+
414+ encode_compound_hdr (xdr , req , & hdr );
415+ encode_sequence (xdr , & args -> cna_seq_args , & hdr );
416+ encode_putfh (xdr , args -> cna_src_fh , & hdr );
417+ encode_copy_notify (xdr , args , & hdr );
418+ encode_nops (& hdr );
419+ }
420+
357421/*
358422 * Encode DEALLOCATE request
359423 */
@@ -490,6 +554,58 @@ static int decode_write_response(struct xdr_stream *xdr,
490554 return decode_verifier (xdr , & res -> verifier .verifier );
491555}
492556
557+ static int decode_nl4_server (struct xdr_stream * xdr , struct nl4_server * ns )
558+ {
559+ struct nfs42_netaddr * naddr ;
560+ uint32_t dummy ;
561+ char * dummy_str ;
562+ __be32 * p ;
563+ int status ;
564+
565+ /* nl_type */
566+ p = xdr_inline_decode (xdr , 4 );
567+ if (unlikely (!p ))
568+ return - EIO ;
569+ ns -> nl4_type = be32_to_cpup (p );
570+ switch (ns -> nl4_type ) {
571+ case NL4_NAME :
572+ case NL4_URL :
573+ status = decode_opaque_inline (xdr , & dummy , & dummy_str );
574+ if (unlikely (status ))
575+ return status ;
576+ if (unlikely (dummy > NFS4_OPAQUE_LIMIT ))
577+ return - EIO ;
578+ memcpy (& ns -> u .nl4_str , dummy_str , dummy );
579+ ns -> u .nl4_str_sz = dummy ;
580+ break ;
581+ case NL4_NETADDR :
582+ naddr = & ns -> u .nl4_addr ;
583+
584+ /* netid string */
585+ status = decode_opaque_inline (xdr , & dummy , & dummy_str );
586+ if (unlikely (status ))
587+ return status ;
588+ if (unlikely (dummy > RPCBIND_MAXNETIDLEN ))
589+ return - EIO ;
590+ naddr -> netid_len = dummy ;
591+ memcpy (naddr -> netid , dummy_str , naddr -> netid_len );
592+
593+ /* uaddr string */
594+ status = decode_opaque_inline (xdr , & dummy , & dummy_str );
595+ if (unlikely (status ))
596+ return status ;
597+ if (unlikely (dummy > RPCBIND_MAXUADDRLEN ))
598+ return - EIO ;
599+ naddr -> addr_len = dummy ;
600+ memcpy (naddr -> addr , dummy_str , naddr -> addr_len );
601+ break ;
602+ default :
603+ WARN_ON_ONCE (1 );
604+ return - EIO ;
605+ }
606+ return 0 ;
607+ }
608+
493609static int decode_copy_requirements (struct xdr_stream * xdr ,
494610 struct nfs42_copy_res * res ) {
495611 __be32 * p ;
@@ -529,6 +645,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr,
529645 return decode_op_hdr (xdr , OP_OFFLOAD_CANCEL );
530646}
531647
648+ static int decode_copy_notify (struct xdr_stream * xdr ,
649+ struct nfs42_copy_notify_res * res )
650+ {
651+ __be32 * p ;
652+ int status , count ;
653+
654+ status = decode_op_hdr (xdr , OP_COPY_NOTIFY );
655+ if (status )
656+ return status ;
657+ /* cnr_lease_time */
658+ p = xdr_inline_decode (xdr , 12 );
659+ if (unlikely (!p ))
660+ return - EIO ;
661+ p = xdr_decode_hyper (p , & res -> cnr_lease_time .seconds );
662+ res -> cnr_lease_time .nseconds = be32_to_cpup (p );
663+
664+ status = decode_opaque_fixed (xdr , & res -> cnr_stateid , NFS4_STATEID_SIZE );
665+ if (unlikely (status ))
666+ return - EIO ;
667+
668+ /* number of source addresses */
669+ p = xdr_inline_decode (xdr , 4 );
670+ if (unlikely (!p ))
671+ return - EIO ;
672+
673+ count = be32_to_cpup (p );
674+ if (count > 1 )
675+ pr_warn ("NFS: %s: nsvr %d > Supported. Use first servers\n" ,
676+ __func__ , count );
677+
678+ status = decode_nl4_server (xdr , & res -> cnr_src );
679+ if (unlikely (status ))
680+ return - EIO ;
681+ return 0 ;
682+ }
683+
532684static int decode_deallocate (struct xdr_stream * xdr , struct nfs42_falloc_res * res )
533685{
534686 return decode_op_hdr (xdr , OP_DEALLOCATE );
@@ -656,6 +808,32 @@ static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
656808 return status ;
657809}
658810
811+ /*
812+ * Decode COPY_NOTIFY response
813+ */
814+ static int nfs4_xdr_dec_copy_notify (struct rpc_rqst * rqstp ,
815+ struct xdr_stream * xdr ,
816+ void * data )
817+ {
818+ struct nfs42_copy_notify_res * res = data ;
819+ struct compound_hdr hdr ;
820+ int status ;
821+
822+ status = decode_compound_hdr (xdr , & hdr );
823+ if (status )
824+ goto out ;
825+ status = decode_sequence (xdr , & res -> cnr_seq_res , rqstp );
826+ if (status )
827+ goto out ;
828+ status = decode_putfh (xdr );
829+ if (status )
830+ goto out ;
831+ status = decode_copy_notify (xdr , res );
832+
833+ out :
834+ return status ;
835+ }
836+
659837/*
660838 * Decode DEALLOCATE request
661839 */
0 commit comments