@@ -4452,85 +4452,83 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr,
4452
4452
return nfserr ;
4453
4453
}
4454
4454
4455
- static __be32
4456
- nfsd4_encode_readdir ( struct nfsd4_compoundres * resp , __be32 nfserr ,
4457
- union nfsd4_op_u * u )
4455
+ static __be32 nfsd4_encode_dirlist4 ( struct xdr_stream * xdr ,
4456
+ struct nfsd4_readdir * readdir ,
4457
+ u32 max_payload )
4458
4458
{
4459
- struct nfsd4_readdir * readdir = & u -> readdir ;
4460
- int maxcount ;
4461
- int bytes_left ;
4459
+ int bytes_left , maxcount , starting_len = xdr -> buf -> len ;
4462
4460
loff_t offset ;
4463
- struct xdr_stream * xdr = resp -> xdr ;
4464
- int starting_len = xdr -> buf -> len ;
4465
- __be32 * p ;
4466
-
4467
- nfserr = nfsd4_encode_verifier4 (xdr , & readdir -> rd_verf );
4468
- if (nfserr != nfs_ok )
4469
- return nfserr ;
4461
+ __be32 status ;
4470
4462
4471
4463
/*
4472
4464
* Number of bytes left for directory entries allowing for the
4473
- * final 8 bytes of the readdir and a following failed op:
4465
+ * final 8 bytes of the readdir and a following failed op.
4474
4466
*/
4475
- bytes_left = xdr -> buf -> buflen - xdr -> buf -> len
4476
- - COMPOUND_ERR_SLACK_SPACE - 8 ;
4477
- if (bytes_left < 0 ) {
4478
- nfserr = nfserr_resource ;
4479
- goto err_no_verf ;
4480
- }
4481
- maxcount = svc_max_payload (resp -> rqstp );
4482
- maxcount = min_t (u32 , readdir -> rd_maxcount , maxcount );
4467
+ bytes_left = xdr -> buf -> buflen - xdr -> buf -> len -
4468
+ COMPOUND_ERR_SLACK_SPACE - XDR_UNIT * 2 ;
4469
+ if (bytes_left < 0 )
4470
+ return nfserr_resource ;
4471
+ maxcount = min_t (u32 , readdir -> rd_maxcount , max_payload );
4472
+
4483
4473
/*
4484
- * Note the rfc defines rd_maxcount as the size of the
4485
- * READDIR4resok structure, which includes the verifier above
4486
- * and the 8 bytes encoded at the end of this function:
4474
+ * The RFC defines rd_maxcount as the size of the
4475
+ * READDIR4resok structure, which includes the verifier
4476
+ * and the 8 bytes encoded at the end of this function.
4487
4477
*/
4488
- if (maxcount < 16 ) {
4489
- nfserr = nfserr_toosmall ;
4490
- goto err_no_verf ;
4491
- }
4492
- maxcount = min_t (int , maxcount - 16 , bytes_left );
4478
+ if (maxcount < XDR_UNIT * 4 )
4479
+ return nfserr_toosmall ;
4480
+ maxcount = min_t (int , maxcount - XDR_UNIT * 4 , bytes_left );
4493
4481
4494
- /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
4482
+ /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0 */
4495
4483
if (!readdir -> rd_dircount )
4496
- readdir -> rd_dircount = svc_max_payload ( resp -> rqstp ) ;
4484
+ readdir -> rd_dircount = max_payload ;
4497
4485
4486
+ /* *entries */
4498
4487
readdir -> xdr = xdr ;
4499
4488
readdir -> rd_maxcount = maxcount ;
4500
4489
readdir -> common .err = 0 ;
4501
4490
readdir -> cookie_offset = 0 ;
4502
-
4503
4491
offset = readdir -> rd_cookie ;
4504
- nfserr = nfsd_readdir (readdir -> rd_rqstp , readdir -> rd_fhp , & offset ,
4492
+ status = nfsd_readdir (readdir -> rd_rqstp , readdir -> rd_fhp , & offset ,
4505
4493
& readdir -> common , nfsd4_encode_entry4 );
4506
- if (nfserr == nfs_ok &&
4507
- readdir -> common . err == nfserr_toosmall &&
4508
- xdr -> buf -> len == starting_len + 8 ) {
4509
- /* nothing encoded; which limit did we hit?: */
4510
- if ( maxcount - 16 < bytes_left )
4511
- /* It was the fault of rd_maxcount: */
4512
- nfserr = nfserr_toosmall ;
4513
- else
4514
- /* We ran out of buffer space: */
4515
- nfserr = nfserr_resource ;
4494
+ if (status )
4495
+ return status ;
4496
+ if ( readdir -> common . err == nfserr_toosmall &&
4497
+ xdr -> buf -> len == starting_len ) {
4498
+ /* No entries were encoded. Which limit did we hit? */
4499
+ if ( maxcount - XDR_UNIT * 4 < bytes_left )
4500
+ /* It was the fault of rd_maxcount */
4501
+ return nfserr_toosmall ;
4502
+ /* We ran out of buffer space */
4503
+ return nfserr_resource ;
4516
4504
}
4517
- if (nfserr )
4518
- goto err_no_verf ;
4519
-
4520
4505
/* Encode the final entry's cookie value */
4521
4506
nfsd4_encode_entry4_nfs_cookie4 (readdir , offset );
4507
+ /* No entries follow */
4508
+ if (xdr_stream_encode_item_absent (xdr ) != XDR_UNIT )
4509
+ return nfserr_resource ;
4522
4510
4523
- p = xdr_reserve_space (xdr , 8 );
4524
- if (!p ) {
4525
- WARN_ON_ONCE (1 );
4526
- goto err_no_verf ;
4527
- }
4528
- * p ++ = 0 ; /* no more entries */
4529
- * p ++ = htonl (readdir -> common .err == nfserr_eof );
4511
+ /* eof */
4512
+ return nfsd4_encode_bool (xdr , readdir -> common .err == nfserr_eof );
4513
+ }
4530
4514
4531
- return 0 ;
4532
- err_no_verf :
4533
- xdr_truncate_encode (xdr , starting_len );
4515
+ static __be32
4516
+ nfsd4_encode_readdir (struct nfsd4_compoundres * resp , __be32 nfserr ,
4517
+ union nfsd4_op_u * u )
4518
+ {
4519
+ struct nfsd4_readdir * readdir = & u -> readdir ;
4520
+ struct xdr_stream * xdr = resp -> xdr ;
4521
+ int starting_len = xdr -> buf -> len ;
4522
+
4523
+ /* cookieverf */
4524
+ nfserr = nfsd4_encode_verifier4 (xdr , & readdir -> rd_verf );
4525
+ if (nfserr != nfs_ok )
4526
+ return nfserr ;
4527
+
4528
+ /* reply */
4529
+ nfserr = nfsd4_encode_dirlist4 (xdr , readdir , svc_max_payload (resp -> rqstp ));
4530
+ if (nfserr != nfs_ok )
4531
+ xdr_truncate_encode (xdr , starting_len );
4534
4532
return nfserr ;
4535
4533
}
4536
4534
0 commit comments