@@ -85,7 +85,21 @@ static void encode_uint32(struct xdr_stream *xdr, u32 n)
85
85
static void encode_bitmap4 (struct xdr_stream * xdr , const __u32 * bitmap ,
86
86
size_t len )
87
87
{
88
- WARN_ON_ONCE (xdr_stream_encode_uint32_array (xdr , bitmap , len ) < 0 );
88
+ xdr_stream_encode_uint32_array (xdr , bitmap , len );
89
+ }
90
+
91
+ static int decode_cb_fattr4 (struct xdr_stream * xdr , uint32_t * bitmap ,
92
+ struct nfs4_cb_fattr * fattr )
93
+ {
94
+ fattr -> ncf_cb_change = 0 ;
95
+ fattr -> ncf_cb_fsize = 0 ;
96
+ if (bitmap [0 ] & FATTR4_WORD0_CHANGE )
97
+ if (xdr_stream_decode_u64 (xdr , & fattr -> ncf_cb_change ) < 0 )
98
+ return - NFSERR_BAD_XDR ;
99
+ if (bitmap [0 ] & FATTR4_WORD0_SIZE )
100
+ if (xdr_stream_decode_u64 (xdr , & fattr -> ncf_cb_fsize ) < 0 )
101
+ return - NFSERR_BAD_XDR ;
102
+ return 0 ;
89
103
}
90
104
91
105
static void encode_nfs_cb_opnum4 (struct xdr_stream * xdr , enum nfs_cb_opnum4 op )
@@ -333,6 +347,30 @@ encode_cb_recallany4args(struct xdr_stream *xdr,
333
347
hdr -> nops ++ ;
334
348
}
335
349
350
+ /*
351
+ * CB_GETATTR4args
352
+ * struct CB_GETATTR4args {
353
+ * nfs_fh4 fh;
354
+ * bitmap4 attr_request;
355
+ * };
356
+ *
357
+ * The size and change attributes are the only one
358
+ * guaranteed to be serviced by the client.
359
+ */
360
+ static void
361
+ encode_cb_getattr4args (struct xdr_stream * xdr , struct nfs4_cb_compound_hdr * hdr ,
362
+ struct nfs4_cb_fattr * fattr )
363
+ {
364
+ struct nfs4_delegation * dp =
365
+ container_of (fattr , struct nfs4_delegation , dl_cb_fattr );
366
+ struct knfsd_fh * fh = & dp -> dl_stid .sc_file -> fi_fhandle ;
367
+
368
+ encode_nfs_cb_opnum4 (xdr , OP_CB_GETATTR );
369
+ encode_nfs_fh4 (xdr , fh );
370
+ encode_bitmap4 (xdr , fattr -> ncf_cb_bmap , ARRAY_SIZE (fattr -> ncf_cb_bmap ));
371
+ hdr -> nops ++ ;
372
+ }
373
+
336
374
/*
337
375
* CB_SEQUENCE4args
338
376
*
@@ -468,6 +506,26 @@ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
468
506
xdr_reserve_space (xdr , 0 );
469
507
}
470
508
509
+ /*
510
+ * 20.1. Operation 3: CB_GETATTR - Get Attributes
511
+ */
512
+ static void nfs4_xdr_enc_cb_getattr (struct rpc_rqst * req ,
513
+ struct xdr_stream * xdr , const void * data )
514
+ {
515
+ const struct nfsd4_callback * cb = data ;
516
+ struct nfs4_cb_fattr * ncf =
517
+ container_of (cb , struct nfs4_cb_fattr , ncf_getattr );
518
+ struct nfs4_cb_compound_hdr hdr = {
519
+ .ident = cb -> cb_clp -> cl_cb_ident ,
520
+ .minorversion = cb -> cb_clp -> cl_minorversion ,
521
+ };
522
+
523
+ encode_cb_compound4args (xdr , & hdr );
524
+ encode_cb_sequence4args (xdr , cb , & hdr );
525
+ encode_cb_getattr4args (xdr , & hdr , ncf );
526
+ encode_cb_nops (& hdr );
527
+ }
528
+
471
529
/*
472
530
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
473
531
*/
@@ -523,6 +581,42 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
523
581
return 0 ;
524
582
}
525
583
584
+ /*
585
+ * 20.1. Operation 3: CB_GETATTR - Get Attributes
586
+ */
587
+ static int nfs4_xdr_dec_cb_getattr (struct rpc_rqst * rqstp ,
588
+ struct xdr_stream * xdr ,
589
+ void * data )
590
+ {
591
+ struct nfsd4_callback * cb = data ;
592
+ struct nfs4_cb_compound_hdr hdr ;
593
+ int status ;
594
+ u32 bitmap [3 ] = {0 };
595
+ u32 attrlen ;
596
+ struct nfs4_cb_fattr * ncf =
597
+ container_of (cb , struct nfs4_cb_fattr , ncf_getattr );
598
+
599
+ status = decode_cb_compound4res (xdr , & hdr );
600
+ if (unlikely (status ))
601
+ return status ;
602
+
603
+ status = decode_cb_sequence4res (xdr , cb );
604
+ if (unlikely (status || cb -> cb_seq_status ))
605
+ return status ;
606
+
607
+ status = decode_cb_op_status (xdr , OP_CB_GETATTR , & cb -> cb_status );
608
+ if (status )
609
+ return status ;
610
+ if (xdr_stream_decode_uint32_array (xdr , bitmap , 3 ) < 0 )
611
+ return - NFSERR_BAD_XDR ;
612
+ if (xdr_stream_decode_u32 (xdr , & attrlen ) < 0 )
613
+ return - NFSERR_BAD_XDR ;
614
+ if (attrlen > (sizeof (ncf -> ncf_cb_change ) + sizeof (ncf -> ncf_cb_fsize )))
615
+ return - NFSERR_BAD_XDR ;
616
+ status = decode_cb_fattr4 (xdr , bitmap , ncf );
617
+ return status ;
618
+ }
619
+
526
620
/*
527
621
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
528
622
*/
@@ -831,6 +925,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
831
925
PROC (CB_NOTIFY_LOCK , COMPOUND , cb_notify_lock , cb_notify_lock ),
832
926
PROC (CB_OFFLOAD , COMPOUND , cb_offload , cb_offload ),
833
927
PROC (CB_RECALL_ANY , COMPOUND , cb_recall_any , cb_recall_any ),
928
+ PROC (CB_GETATTR , COMPOUND , cb_getattr , cb_getattr ),
834
929
};
835
930
836
931
static unsigned int nfs4_cb_counts [ARRAY_SIZE (nfs4_cb_procedures )];
0 commit comments