Skip to content

Commit db145db

Browse files
Trond Myklebustamschuma-ntap
authored andcommitted
NFSv4: Add encoders/decoders for the NFSv4.1 dacl and sacl attributes
Add the ability to set or retrieve the acl using the NFSv4.1 'dacl' and 'sacl' attributes to the NFSv4 xdr encoders/decoders. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 7b8b44e commit db145db

File tree

3 files changed

+71
-36
lines changed

3 files changed

+71
-36
lines changed

fs/nfs/nfs4proc.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5911,9 +5911,11 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf,
59115911
struct page **pages;
59125912
struct nfs_getaclargs args = {
59135913
.fh = NFS_FH(inode),
5914+
.acl_type = type,
59145915
.acl_len = buflen,
59155916
};
59165917
struct nfs_getaclres res = {
5918+
.acl_type = type,
59175919
.acl_len = buflen,
59185920
};
59195921
struct rpc_message msg = {
@@ -6028,9 +6030,10 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
60286030
struct nfs_server *server = NFS_SERVER(inode);
60296031
struct page *pages[NFS4ACL_MAXPAGES];
60306032
struct nfs_setaclargs arg = {
6031-
.fh = NFS_FH(inode),
6032-
.acl_pages = pages,
6033-
.acl_len = buflen,
6033+
.fh = NFS_FH(inode),
6034+
.acl_type = type,
6035+
.acl_len = buflen,
6036+
.acl_pages = pages,
60346037
};
60356038
struct nfs_setaclres res;
60366039
struct rpc_message msg = {

fs/nfs/nfs4xdr.c

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

53885404
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)
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+
}
54275456
out:
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

64916520
out:
64926521
return status;

include/linux/nfs_xdr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,7 @@ enum nfs4_acl_type {
810810
struct nfs_setaclargs {
811811
struct nfs4_sequence_args seq_args;
812812
struct nfs_fh * fh;
813+
enum nfs4_acl_type acl_type;
813814
size_t acl_len;
814815
struct page ** acl_pages;
815816
};
@@ -821,6 +822,7 @@ struct nfs_setaclres {
821822
struct nfs_getaclargs {
822823
struct nfs4_sequence_args seq_args;
823824
struct nfs_fh * fh;
825+
enum nfs4_acl_type acl_type;
824826
size_t acl_len;
825827
struct page ** acl_pages;
826828
};
@@ -829,6 +831,7 @@ struct nfs_getaclargs {
829831
#define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */
830832
struct nfs_getaclres {
831833
struct nfs4_sequence_res seq_res;
834+
enum nfs4_acl_type acl_type;
832835
size_t acl_len;
833836
size_t acl_data_offset;
834837
int acl_flags;

0 commit comments

Comments
 (0)