[PATCH] NFSv4: Client-side xdr for writing NFSv4 acls
authorJ. Bruce Fields <bfields@citi.umich.edu>
Wed, 22 Jun 2005 17:16:22 +0000 (17:16 +0000)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 22 Jun 2005 20:07:13 +0000 (16:07 -0400)
 Client-side support for NFSv4 acls: xdr encoding and decoding routines for
 writing acls

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4xdr.c
include/linux/nfs4.h
include/linux/nfs_xdr.h

index 6f1c003ee33a0d928628594ce761d2874585c2f4..325cd6d4f23ad4554a086ef37382330e5d5a4a50 100644 (file)
@@ -372,6 +372,13 @@ static int nfs_stat_to_errno(int);
                                decode_putfh_maxsz + \
                                op_decode_hdr_maxsz + \
                                nfs4_fattr_bitmap_maxsz + 1)
+#define NFS4_enc_setacl_sz     (compound_encode_hdr_maxsz + \
+                               encode_putfh_maxsz + \
+                               op_encode_hdr_maxsz + 4 + \
+                               nfs4_fattr_bitmap_maxsz + 1)
+#define NFS4_dec_setacl_sz     (compound_decode_hdr_maxsz + \
+                               decode_putfh_maxsz + \
+                               op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
 
 static struct {
        unsigned int    mode;
@@ -471,7 +478,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
         * In the worst-case, this would be
         *   12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
         *          = 36 bytes, plus any contribution from variable-length fields
-        *            such as owner/group/acl's.
+        *            such as owner/group.
         */
        len = 16;
 
@@ -1095,6 +1102,25 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client
        return 0;
 }
 
+static int
+encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
+{
+       uint32_t *p;
+
+       RESERVE_SPACE(4+sizeof(zero_stateid.data));
+       WRITE32(OP_SETATTR);
+       WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data));
+       RESERVE_SPACE(2*4);
+       WRITE32(1);
+       WRITE32(FATTR4_WORD0_ACL);
+       if (arg->acl_len % 4)
+               return -EINVAL;
+       RESERVE_SPACE(4);
+       WRITE32(arg->acl_len);
+       xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
+       return 0;
+}
+
 static int
 encode_savefh(struct xdr_stream *xdr)
 {
@@ -3492,6 +3518,48 @@ out:
 
 }
 
+/*
+ * Encode an SETACL request
+ */
+static int
+nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args)
+{
+        struct xdr_stream xdr;
+        struct compound_hdr hdr = {
+                .nops   = 2,
+        };
+        int status;
+
+        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+        encode_compound_hdr(&xdr, &hdr);
+        status = encode_putfh(&xdr, args->fh);
+        if (status)
+                goto out;
+        status = encode_setacl(&xdr, args);
+out:
+        return status;
+}
+/*
+ * Decode SETACL response
+ */
+static int
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr;
+       int status;
+
+       xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+       status = decode_compound_hdr(&xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_putfh(&xdr);
+       if (status)
+               goto out;
+       status = decode_setattr(&xdr, res);
+out:
+       return status;
+}
 
 /*
  * Decode GETACL response
@@ -4117,6 +4185,7 @@ struct rpc_procinfo       nfs4_procedures[] = {
   PROC(SERVER_CAPS,    enc_server_caps, dec_server_caps),
   PROC(DELEGRETURN,    enc_delegreturn, dec_delegreturn),
   PROC(GETACL,         enc_getacl,     dec_getacl),
+  PROC(SETACL,         enc_setacl,     dec_setacl),
 };
 
 struct rpc_version             nfs_version4 = {
index 6ee7e2585af58b1bb9d36a0bc65cd5a64b8651c6..5bb5b2fd7ba21edb9585b6495754239cecfa7cb3 100644 (file)
@@ -383,6 +383,7 @@ enum {
        NFSPROC4_CLNT_SERVER_CAPS,
        NFSPROC4_CLNT_DELEGRETURN,
        NFSPROC4_CLNT_GETACL,
+       NFSPROC4_CLNT_SETACL,
 };
 
 #endif
index 9f5e1d407c7bb1f9f5e5e551fc3543cb684a57ad..46b206b460c02dc1b1756210ef1c268a5ca6865a 100644 (file)
@@ -326,6 +326,13 @@ struct nfs_setattrargs {
        const u32 *                     bitmask;
 };
 
+struct nfs_setaclargs {
+       struct nfs_fh *                 fh;
+       size_t                          acl_len;
+       unsigned int                    acl_pgbase;
+       struct page **                  acl_pages;
+};
+
 struct nfs_getaclargs {
        struct nfs_fh *                 fh;
        size_t                          acl_len;