@@ -1680,19 +1680,35 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1680
1680
encode_op_hdr (xdr , OP_RESTOREFH , decode_restorefh_maxsz , hdr );
1681
1681
}
1682
1682
1683
- static void
1684
- encode_setacl (struct xdr_stream * xdr , const struct nfs_setaclargs * arg ,
1685
- struct compound_hdr * hdr )
1683
+ static void nfs4_acltype_to_bitmap (enum nfs4_acl_type type , __u32 bitmap [2 ])
1686
1684
{
1687
- __be32 * p ;
1685
+ switch (type ) {
1686
+ default :
1687
+ bitmap [0 ] = FATTR4_WORD0_ACL ;
1688
+ bitmap [1 ] = 0 ;
1689
+ break ;
1690
+ case NFS4ACL_DACL :
1691
+ bitmap [0 ] = 0 ;
1692
+ bitmap [1 ] = FATTR4_WORD1_DACL ;
1693
+ break ;
1694
+ case NFS4ACL_SACL :
1695
+ bitmap [0 ] = 0 ;
1696
+ bitmap [1 ] = FATTR4_WORD1_SACL ;
1697
+ }
1698
+ }
1699
+
1700
+ static void encode_setacl (struct xdr_stream * xdr ,
1701
+ const struct nfs_setaclargs * arg ,
1702
+ struct compound_hdr * hdr )
1703
+ {
1704
+ __u32 bitmap [2 ];
1705
+
1706
+ nfs4_acltype_to_bitmap (arg -> acl_type , bitmap );
1688
1707
1689
1708
encode_op_hdr (xdr , OP_SETATTR , decode_setacl_maxsz , hdr );
1690
1709
encode_nfs4_stateid (xdr , & zero_stateid );
1691
- p = reserve_space (xdr , 2 * 4 );
1692
- * p ++ = cpu_to_be32 (1 );
1693
- * p = cpu_to_be32 (FATTR4_WORD0_ACL );
1694
- p = reserve_space (xdr , 4 );
1695
- * p = cpu_to_be32 (arg -> acl_len );
1710
+ xdr_encode_bitmap4 (xdr , bitmap , ARRAY_SIZE (bitmap ));
1711
+ encode_uint32 (xdr , arg -> acl_len );
1696
1712
xdr_write_pages (xdr , arg -> acl_pages , 0 , arg -> acl_len );
1697
1713
}
1698
1714
@@ -2587,11 +2603,11 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
2587
2603
struct compound_hdr hdr = {
2588
2604
.minorversion = nfs4_xdr_minorversion (& args -> seq_args ),
2589
2605
};
2590
- const __u32 nfs4_acl_bitmap [1 ] = {
2591
- [0 ] = FATTR4_WORD0_ACL ,
2592
- };
2606
+ __u32 nfs4_acl_bitmap [2 ];
2593
2607
uint32_t replen ;
2594
2608
2609
+ nfs4_acltype_to_bitmap (args -> acl_type , nfs4_acl_bitmap );
2610
+
2595
2611
encode_compound_hdr (xdr , req , & hdr );
2596
2612
encode_sequence (xdr , & args -> seq_args , & hdr );
2597
2613
encode_putfh (xdr , args -> fh , & hdr );
@@ -5386,7 +5402,7 @@ decode_restorefh(struct xdr_stream *xdr)
5386
5402
}
5387
5403
5388
5404
static int decode_getacl (struct xdr_stream * xdr , struct rpc_rqst * req ,
5389
- struct nfs_getaclres * res )
5405
+ struct nfs_getaclres * res , enum nfs4_acl_type type )
5390
5406
{
5391
5407
unsigned int savep ;
5392
5408
uint32_t attrlen ,
@@ -5404,26 +5420,39 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
5404
5420
if ((status = decode_attr_length (xdr , & attrlen , & savep )) != 0 )
5405
5421
goto out ;
5406
5422
5407
- if ( unlikely ( bitmap [ 0 ] & ( FATTR4_WORD0_ACL - 1U )))
5408
- return - EIO ;
5409
- if (likely (bitmap [0 ] & FATTR4_WORD0_ACL )) {
5410
-
5411
- /* The bitmap (xdr len + bitmaps) and the attr xdr len words
5412
- * are stored with the acl data to handle the problem of
5413
- * variable length bitmaps.*/
5414
- res -> acl_data_offset = xdr_page_pos ( xdr );
5415
- res -> acl_len = attrlen ;
5416
-
5417
- /* Check for receive buffer overflow */
5418
- if ( res -> acl_len > xdr_stream_remaining ( xdr ) ||
5419
- res -> acl_len + res -> acl_data_offset > xdr -> buf -> page_len ) {
5420
- res -> acl_flags |= NFS4_ACL_TRUNC ;
5421
- dprintk ( "NFS: acl reply: attrlen %u > page_len %zu\n" ,
5422
- attrlen , xdr_stream_remaining ( xdr )) ;
5423
- }
5424
- } else
5425
- status = - EOPNOTSUPP ;
5423
+ switch ( type ) {
5424
+ default :
5425
+ if (unlikely (bitmap [0 ] & ( FATTR4_WORD0_ACL - 1U )))
5426
+ return - EIO ;
5427
+ if (!( bitmap [ 0 ] & FATTR4_WORD0_ACL ))
5428
+ return - EOPNOTSUPP ;
5429
+ break ;
5430
+ case NFS4ACL_DACL :
5431
+ if ( unlikely ( bitmap [ 0 ] || bitmap [ 1 ] & ( FATTR4_WORD1_DACL - 1U )))
5432
+ return - EIO ;
5433
+ if (!( bitmap [ 1 ] & FATTR4_WORD1_DACL ))
5434
+ return - EOPNOTSUPP ;
5435
+ break ;
5436
+ case NFS4ACL_SACL :
5437
+ if ( unlikely ( bitmap [ 0 ] || bitmap [ 1 ] & ( FATTR4_WORD1_SACL - 1U )))
5438
+ return - EIO ;
5439
+ if (!( bitmap [ 1 ] & FATTR4_WORD1_SACL ))
5440
+ return - EOPNOTSUPP ;
5441
+ }
5426
5442
5443
+ /* The bitmap (xdr len + bitmaps) and the attr xdr len words
5444
+ * are stored with the acl data to handle the problem of
5445
+ * variable length bitmaps.*/
5446
+ res -> acl_data_offset = xdr_page_pos (xdr );
5447
+ res -> acl_len = attrlen ;
5448
+
5449
+ /* Check for receive buffer overflow */
5450
+ if (res -> acl_len > xdr_stream_remaining (xdr ) ||
5451
+ res -> acl_len + res -> acl_data_offset > xdr -> buf -> page_len ) {
5452
+ res -> acl_flags |= NFS4_ACL_TRUNC ;
5453
+ dprintk ("NFS: acl reply: attrlen %u > page_len %zu\n" ,
5454
+ attrlen , xdr_stream_remaining (xdr ));
5455
+ }
5427
5456
out :
5428
5457
return status ;
5429
5458
}
@@ -6486,7 +6515,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6486
6515
status = decode_putfh (xdr );
6487
6516
if (status )
6488
6517
goto out ;
6489
- status = decode_getacl (xdr , rqstp , res );
6518
+ status = decode_getacl (xdr , rqstp , res , res -> acl_type );
6490
6519
6491
6520
out :
6492
6521
return status ;
0 commit comments