@@ -84,7 +84,21 @@ static void encode_uint32(struct xdr_stream *xdr, u32 n)
84
84
static void encode_bitmap4 (struct xdr_stream * xdr , const __u32 * bitmap ,
85
85
size_t len )
86
86
{
87
- WARN_ON_ONCE (xdr_stream_encode_uint32_array (xdr , bitmap , len ) < 0 );
87
+ xdr_stream_encode_uint32_array (xdr , bitmap , len );
88
+ }
89
+
90
+ static int decode_cb_fattr4 (struct xdr_stream * xdr , uint32_t * bitmap ,
91
+ struct nfs4_cb_fattr * fattr )
92
+ {
93
+ fattr -> ncf_cb_change = 0 ;
94
+ fattr -> ncf_cb_fsize = 0 ;
95
+ if (bitmap [0 ] & FATTR4_WORD0_CHANGE )
96
+ if (xdr_stream_decode_u64 (xdr , & fattr -> ncf_cb_change ) < 0 )
97
+ return - NFSERR_BAD_XDR ;
98
+ if (bitmap [0 ] & FATTR4_WORD0_SIZE )
99
+ if (xdr_stream_decode_u64 (xdr , & fattr -> ncf_cb_fsize ) < 0 )
100
+ return - NFSERR_BAD_XDR ;
101
+ return 0 ;
88
102
}
89
103
90
104
/*
@@ -357,6 +371,30 @@ encode_cb_recallany4args(struct xdr_stream *xdr,
357
371
hdr -> nops ++ ;
358
372
}
359
373
374
+ /*
375
+ * CB_GETATTR4args
376
+ * struct CB_GETATTR4args {
377
+ * nfs_fh4 fh;
378
+ * bitmap4 attr_request;
379
+ * };
380
+ *
381
+ * The size and change attributes are the only one
382
+ * guaranteed to be serviced by the client.
383
+ */
384
+ static void
385
+ encode_cb_getattr4args (struct xdr_stream * xdr , struct nfs4_cb_compound_hdr * hdr ,
386
+ struct nfs4_cb_fattr * fattr )
387
+ {
388
+ struct nfs4_delegation * dp =
389
+ container_of (fattr , struct nfs4_delegation , dl_cb_fattr );
390
+ struct knfsd_fh * fh = & dp -> dl_stid .sc_file -> fi_fhandle ;
391
+
392
+ encode_nfs_cb_opnum4 (xdr , OP_CB_GETATTR );
393
+ encode_nfs_fh4 (xdr , fh );
394
+ encode_bitmap4 (xdr , fattr -> ncf_cb_bmap , ARRAY_SIZE (fattr -> ncf_cb_bmap ));
395
+ hdr -> nops ++ ;
396
+ }
397
+
360
398
/*
361
399
* CB_SEQUENCE4args
362
400
*
@@ -492,6 +530,26 @@ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
492
530
xdr_reserve_space (xdr , 0 );
493
531
}
494
532
533
+ /*
534
+ * 20.1. Operation 3: CB_GETATTR - Get Attributes
535
+ */
536
+ static void nfs4_xdr_enc_cb_getattr (struct rpc_rqst * req ,
537
+ struct xdr_stream * xdr , const void * data )
538
+ {
539
+ const struct nfsd4_callback * cb = data ;
540
+ struct nfs4_cb_fattr * ncf =
541
+ container_of (cb , struct nfs4_cb_fattr , ncf_getattr );
542
+ struct nfs4_cb_compound_hdr hdr = {
543
+ .ident = cb -> cb_clp -> cl_cb_ident ,
544
+ .minorversion = cb -> cb_clp -> cl_minorversion ,
545
+ };
546
+
547
+ encode_cb_compound4args (xdr , & hdr );
548
+ encode_cb_sequence4args (xdr , cb , & hdr );
549
+ encode_cb_getattr4args (xdr , & hdr , ncf );
550
+ encode_cb_nops (& hdr );
551
+ }
552
+
495
553
/*
496
554
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
497
555
*/
@@ -547,6 +605,42 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
547
605
return 0 ;
548
606
}
549
607
608
+ /*
609
+ * 20.1. Operation 3: CB_GETATTR - Get Attributes
610
+ */
611
+ static int nfs4_xdr_dec_cb_getattr (struct rpc_rqst * rqstp ,
612
+ struct xdr_stream * xdr ,
613
+ void * data )
614
+ {
615
+ struct nfsd4_callback * cb = data ;
616
+ struct nfs4_cb_compound_hdr hdr ;
617
+ int status ;
618
+ u32 bitmap [3 ] = {0 };
619
+ u32 attrlen ;
620
+ struct nfs4_cb_fattr * ncf =
621
+ container_of (cb , struct nfs4_cb_fattr , ncf_getattr );
622
+
623
+ status = decode_cb_compound4res (xdr , & hdr );
624
+ if (unlikely (status ))
625
+ return status ;
626
+
627
+ status = decode_cb_sequence4res (xdr , cb );
628
+ if (unlikely (status || cb -> cb_seq_status ))
629
+ return status ;
630
+
631
+ status = decode_cb_op_status (xdr , OP_CB_GETATTR , & cb -> cb_status );
632
+ if (status )
633
+ return status ;
634
+ if (xdr_stream_decode_uint32_array (xdr , bitmap , 3 ) < 0 )
635
+ return - NFSERR_BAD_XDR ;
636
+ if (xdr_stream_decode_u32 (xdr , & attrlen ) < 0 )
637
+ return - NFSERR_BAD_XDR ;
638
+ if (attrlen > (sizeof (ncf -> ncf_cb_change ) + sizeof (ncf -> ncf_cb_fsize )))
639
+ return - NFSERR_BAD_XDR ;
640
+ status = decode_cb_fattr4 (xdr , bitmap , ncf );
641
+ return status ;
642
+ }
643
+
550
644
/*
551
645
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
552
646
*/
@@ -855,6 +949,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
855
949
PROC (CB_NOTIFY_LOCK , COMPOUND , cb_notify_lock , cb_notify_lock ),
856
950
PROC (CB_OFFLOAD , COMPOUND , cb_offload , cb_offload ),
857
951
PROC (CB_RECALL_ANY , COMPOUND , cb_recall_any , cb_recall_any ),
952
+ PROC (CB_GETATTR , COMPOUND , cb_getattr , cb_getattr ),
858
953
};
859
954
860
955
static unsigned int nfs4_cb_counts [ARRAY_SIZE (nfs4_cb_procedures )];
0 commit comments