@@ -1680,19 +1680,35 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
16801680 encode_op_hdr (xdr , OP_RESTOREFH , decode_restorefh_maxsz , hdr );
16811681}
16821682
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 ])
16861684{
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 );
16881707
16891708 encode_op_hdr (xdr , OP_SETATTR , decode_setacl_maxsz , hdr );
16901709 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 );
16961712 xdr_write_pages (xdr , arg -> acl_pages , 0 , arg -> acl_len );
16971713}
16981714
@@ -2587,11 +2603,11 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
25872603 struct compound_hdr hdr = {
25882604 .minorversion = nfs4_xdr_minorversion (& args -> seq_args ),
25892605 };
2590- const __u32 nfs4_acl_bitmap [1 ] = {
2591- [0 ] = FATTR4_WORD0_ACL ,
2592- };
2606+ __u32 nfs4_acl_bitmap [2 ];
25932607 uint32_t replen ;
25942608
2609+ nfs4_acltype_to_bitmap (args -> acl_type , nfs4_acl_bitmap );
2610+
25952611 encode_compound_hdr (xdr , req , & hdr );
25962612 encode_sequence (xdr , & args -> seq_args , & hdr );
25972613 encode_putfh (xdr , args -> fh , & hdr );
@@ -5386,7 +5402,7 @@ decode_restorefh(struct xdr_stream *xdr)
53865402}
53875403
53885404static 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 )
53905406{
53915407 unsigned int savep ;
53925408 uint32_t attrlen ,
@@ -5404,26 +5420,39 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
54045420 if ((status = decode_attr_length (xdr , & attrlen , & savep )) != 0 )
54055421 goto out ;
54065422
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+ }
54265442
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+ }
54275456out :
54285457 return status ;
54295458}
@@ -6486,7 +6515,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
64866515 status = decode_putfh (xdr );
64876516 if (status )
64886517 goto out ;
6489- status = decode_getacl (xdr , rqstp , res );
6518+ status = decode_getacl (xdr , rqstp , res , res -> acl_type );
64906519
64916520out :
64926521 return status ;
0 commit comments