@@ -1732,6 +1732,35 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
17321732 return nfsd4_decode_stateid4 (argp , & free_stateid -> fr_stateid );
17331733}
17341734
1735+ static __be32
1736+ nfsd4_decode_get_dir_delegation (struct nfsd4_compoundargs * argp ,
1737+ union nfsd4_op_u * u )
1738+ {
1739+ struct nfsd4_get_dir_delegation * gdd = & u -> get_dir_delegation ;
1740+ __be32 status ;
1741+
1742+ memset (gdd , 0 , sizeof (* gdd ));
1743+
1744+ if (xdr_stream_decode_bool (argp -> xdr , & gdd -> gdda_signal_deleg_avail ) < 0 )
1745+ return nfserr_bad_xdr ;
1746+ status = nfsd4_decode_bitmap4 (argp , gdd -> gdda_notification_types ,
1747+ ARRAY_SIZE (gdd -> gdda_notification_types ));
1748+ if (status )
1749+ return status ;
1750+ status = nfsd4_decode_nfstime4 (argp , & gdd -> gdda_child_attr_delay );
1751+ if (status )
1752+ return status ;
1753+ status = nfsd4_decode_nfstime4 (argp , & gdd -> gdda_dir_attr_delay );
1754+ if (status )
1755+ return status ;
1756+ status = nfsd4_decode_bitmap4 (argp , gdd -> gdda_child_attributes ,
1757+ ARRAY_SIZE (gdd -> gdda_child_attributes ));
1758+ if (status )
1759+ return status ;
1760+ return nfsd4_decode_bitmap4 (argp , gdd -> gdda_dir_attributes ,
1761+ ARRAY_SIZE (gdd -> gdda_dir_attributes ));
1762+ }
1763+
17351764#ifdef CONFIG_NFSD_PNFS
17361765static __be32
17371766nfsd4_decode_getdeviceinfo (struct nfsd4_compoundargs * argp ,
@@ -2370,7 +2399,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = {
23702399 [OP_CREATE_SESSION ] = nfsd4_decode_create_session ,
23712400 [OP_DESTROY_SESSION ] = nfsd4_decode_destroy_session ,
23722401 [OP_FREE_STATEID ] = nfsd4_decode_free_stateid ,
2373- [OP_GET_DIR_DELEGATION ] = nfsd4_decode_notsupp ,
2402+ [OP_GET_DIR_DELEGATION ] = nfsd4_decode_get_dir_delegation ,
23742403#ifdef CONFIG_NFSD_PNFS
23752404 [OP_GETDEVICEINFO ] = nfsd4_decode_getdeviceinfo ,
23762405 [OP_GETDEVICELIST ] = nfsd4_decode_notsupp ,
@@ -4963,6 +4992,49 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
49634992 return nfs_ok ;
49644993}
49654994
4995+ static __be32
4996+ nfsd4_encode_get_dir_delegation (struct nfsd4_compoundres * resp , __be32 nfserr ,
4997+ union nfsd4_op_u * u )
4998+ {
4999+ struct nfsd4_get_dir_delegation * gdd = & u -> get_dir_delegation ;
5000+ struct xdr_stream * xdr = resp -> xdr ;
5001+ __be32 status = nfserr_resource ;
5002+
5003+ switch (gdd -> gddrnf_status ) {
5004+ case GDD4_OK :
5005+ if (xdr_stream_encode_u32 (xdr , GDD4_OK ) != XDR_UNIT )
5006+ break ;
5007+ status = nfsd4_encode_verifier4 (xdr , & gdd -> gddr_cookieverf );
5008+ if (status )
5009+ break ;
5010+ status = nfsd4_encode_stateid4 (xdr , & gdd -> gddr_stateid );
5011+ if (status )
5012+ break ;
5013+ status = nfsd4_encode_bitmap4 (xdr , gdd -> gddr_notification [0 ], 0 , 0 );
5014+ if (status )
5015+ break ;
5016+ status = nfsd4_encode_bitmap4 (xdr , gdd -> gddr_child_attributes [0 ],
5017+ gdd -> gddr_child_attributes [1 ],
5018+ gdd -> gddr_child_attributes [2 ]);
5019+ if (status )
5020+ break ;
5021+ status = nfsd4_encode_bitmap4 (xdr , gdd -> gddr_dir_attributes [0 ],
5022+ gdd -> gddr_dir_attributes [1 ],
5023+ gdd -> gddr_dir_attributes [2 ]);
5024+ break ;
5025+ default :
5026+ pr_warn ("nfsd: bad gddrnf_status (%u)\n" , gdd -> gddrnf_status );
5027+ gdd -> gddrnf_will_signal_deleg_avail = 0 ;
5028+ fallthrough ;
5029+ case GDD4_UNAVAIL :
5030+ if (xdr_stream_encode_u32 (xdr , GDD4_UNAVAIL ) != XDR_UNIT )
5031+ break ;
5032+ status = nfsd4_encode_bool (xdr , gdd -> gddrnf_will_signal_deleg_avail );
5033+ break ;
5034+ }
5035+ return status ;
5036+ }
5037+
49665038#ifdef CONFIG_NFSD_PNFS
49675039static __be32
49685040nfsd4_encode_device_addr4 (struct xdr_stream * xdr ,
@@ -5579,7 +5651,7 @@ static const nfsd4_enc nfsd4_enc_ops[] = {
55795651 [OP_CREATE_SESSION ] = nfsd4_encode_create_session ,
55805652 [OP_DESTROY_SESSION ] = nfsd4_encode_noop ,
55815653 [OP_FREE_STATEID ] = nfsd4_encode_noop ,
5582- [OP_GET_DIR_DELEGATION ] = nfsd4_encode_noop ,
5654+ [OP_GET_DIR_DELEGATION ] = nfsd4_encode_get_dir_delegation ,
55835655#ifdef CONFIG_NFSD_PNFS
55845656 [OP_GETDEVICEINFO ] = nfsd4_encode_getdeviceinfo ,
55855657 [OP_GETDEVICELIST ] = nfsd4_encode_noop ,
0 commit comments