1*a257cdd0SAndreas Gruenbacher /* 2*a257cdd0SAndreas Gruenbacher * linux/fs/nfsd/nfsacl.c 3*a257cdd0SAndreas Gruenbacher * 4*a257cdd0SAndreas Gruenbacher * Process version 2 NFSACL requests. 5*a257cdd0SAndreas Gruenbacher * 6*a257cdd0SAndreas Gruenbacher * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de> 7*a257cdd0SAndreas Gruenbacher */ 8*a257cdd0SAndreas Gruenbacher 9*a257cdd0SAndreas Gruenbacher #include <linux/sunrpc/svc.h> 10*a257cdd0SAndreas Gruenbacher #include <linux/nfs.h> 11*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/nfsd.h> 12*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/cache.h> 13*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/xdr.h> 14*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/xdr3.h> 15*a257cdd0SAndreas Gruenbacher #include <linux/posix_acl.h> 16*a257cdd0SAndreas Gruenbacher #include <linux/nfsacl.h> 17*a257cdd0SAndreas Gruenbacher 18*a257cdd0SAndreas Gruenbacher #define NFSDDBG_FACILITY NFSDDBG_PROC 19*a257cdd0SAndreas Gruenbacher #define RETURN_STATUS(st) { resp->status = (st); return (st); } 20*a257cdd0SAndreas Gruenbacher 21*a257cdd0SAndreas Gruenbacher /* 22*a257cdd0SAndreas Gruenbacher * NULL call. 23*a257cdd0SAndreas Gruenbacher */ 24*a257cdd0SAndreas Gruenbacher static int 25*a257cdd0SAndreas Gruenbacher nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 26*a257cdd0SAndreas Gruenbacher { 27*a257cdd0SAndreas Gruenbacher return nfs_ok; 28*a257cdd0SAndreas Gruenbacher } 29*a257cdd0SAndreas Gruenbacher 30*a257cdd0SAndreas Gruenbacher /* 31*a257cdd0SAndreas Gruenbacher * Get the Access and/or Default ACL of a file. 32*a257cdd0SAndreas Gruenbacher */ 33*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_getacl(struct svc_rqst * rqstp, 34*a257cdd0SAndreas Gruenbacher struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) 35*a257cdd0SAndreas Gruenbacher { 36*a257cdd0SAndreas Gruenbacher svc_fh *fh; 37*a257cdd0SAndreas Gruenbacher struct posix_acl *acl; 38*a257cdd0SAndreas Gruenbacher int nfserr = 0; 39*a257cdd0SAndreas Gruenbacher 40*a257cdd0SAndreas Gruenbacher dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 41*a257cdd0SAndreas Gruenbacher 42*a257cdd0SAndreas Gruenbacher fh = fh_copy(&resp->fh, &argp->fh); 43*a257cdd0SAndreas Gruenbacher if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) 44*a257cdd0SAndreas Gruenbacher RETURN_STATUS(nfserr_inval); 45*a257cdd0SAndreas Gruenbacher 46*a257cdd0SAndreas Gruenbacher if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) 47*a257cdd0SAndreas Gruenbacher RETURN_STATUS(nfserr_inval); 48*a257cdd0SAndreas Gruenbacher resp->mask = argp->mask; 49*a257cdd0SAndreas Gruenbacher 50*a257cdd0SAndreas Gruenbacher if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { 51*a257cdd0SAndreas Gruenbacher acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS); 52*a257cdd0SAndreas Gruenbacher if (IS_ERR(acl)) { 53*a257cdd0SAndreas Gruenbacher int err = PTR_ERR(acl); 54*a257cdd0SAndreas Gruenbacher 55*a257cdd0SAndreas Gruenbacher if (err == -ENODATA || err == -EOPNOTSUPP) 56*a257cdd0SAndreas Gruenbacher acl = NULL; 57*a257cdd0SAndreas Gruenbacher else { 58*a257cdd0SAndreas Gruenbacher nfserr = nfserrno(err); 59*a257cdd0SAndreas Gruenbacher goto fail; 60*a257cdd0SAndreas Gruenbacher } 61*a257cdd0SAndreas Gruenbacher } 62*a257cdd0SAndreas Gruenbacher if (acl == NULL) { 63*a257cdd0SAndreas Gruenbacher /* Solaris returns the inode's minimum ACL. */ 64*a257cdd0SAndreas Gruenbacher 65*a257cdd0SAndreas Gruenbacher struct inode *inode = fh->fh_dentry->d_inode; 66*a257cdd0SAndreas Gruenbacher acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 67*a257cdd0SAndreas Gruenbacher } 68*a257cdd0SAndreas Gruenbacher resp->acl_access = acl; 69*a257cdd0SAndreas Gruenbacher } 70*a257cdd0SAndreas Gruenbacher if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) { 71*a257cdd0SAndreas Gruenbacher /* Check how Solaris handles requests for the Default ACL 72*a257cdd0SAndreas Gruenbacher of a non-directory! */ 73*a257cdd0SAndreas Gruenbacher 74*a257cdd0SAndreas Gruenbacher acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT); 75*a257cdd0SAndreas Gruenbacher if (IS_ERR(acl)) { 76*a257cdd0SAndreas Gruenbacher int err = PTR_ERR(acl); 77*a257cdd0SAndreas Gruenbacher 78*a257cdd0SAndreas Gruenbacher if (err == -ENODATA || err == -EOPNOTSUPP) 79*a257cdd0SAndreas Gruenbacher acl = NULL; 80*a257cdd0SAndreas Gruenbacher else { 81*a257cdd0SAndreas Gruenbacher nfserr = nfserrno(err); 82*a257cdd0SAndreas Gruenbacher goto fail; 83*a257cdd0SAndreas Gruenbacher } 84*a257cdd0SAndreas Gruenbacher } 85*a257cdd0SAndreas Gruenbacher resp->acl_default = acl; 86*a257cdd0SAndreas Gruenbacher } 87*a257cdd0SAndreas Gruenbacher 88*a257cdd0SAndreas Gruenbacher /* resp->acl_{access,default} are released in nfssvc_release_getacl. */ 89*a257cdd0SAndreas Gruenbacher RETURN_STATUS(0); 90*a257cdd0SAndreas Gruenbacher 91*a257cdd0SAndreas Gruenbacher fail: 92*a257cdd0SAndreas Gruenbacher posix_acl_release(resp->acl_access); 93*a257cdd0SAndreas Gruenbacher posix_acl_release(resp->acl_default); 94*a257cdd0SAndreas Gruenbacher RETURN_STATUS(nfserr); 95*a257cdd0SAndreas Gruenbacher } 96*a257cdd0SAndreas Gruenbacher 97*a257cdd0SAndreas Gruenbacher /* 98*a257cdd0SAndreas Gruenbacher * Set the Access and/or Default ACL of a file. 99*a257cdd0SAndreas Gruenbacher */ 100*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_setacl(struct svc_rqst * rqstp, 101*a257cdd0SAndreas Gruenbacher struct nfsd3_setaclargs *argp, 102*a257cdd0SAndreas Gruenbacher struct nfsd_attrstat *resp) 103*a257cdd0SAndreas Gruenbacher { 104*a257cdd0SAndreas Gruenbacher svc_fh *fh; 105*a257cdd0SAndreas Gruenbacher int nfserr = 0; 106*a257cdd0SAndreas Gruenbacher 107*a257cdd0SAndreas Gruenbacher dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 108*a257cdd0SAndreas Gruenbacher 109*a257cdd0SAndreas Gruenbacher fh = fh_copy(&resp->fh, &argp->fh); 110*a257cdd0SAndreas Gruenbacher nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP); 111*a257cdd0SAndreas Gruenbacher 112*a257cdd0SAndreas Gruenbacher if (!nfserr) { 113*a257cdd0SAndreas Gruenbacher nfserr = nfserrno( nfsd_set_posix_acl( 114*a257cdd0SAndreas Gruenbacher fh, ACL_TYPE_ACCESS, argp->acl_access) ); 115*a257cdd0SAndreas Gruenbacher } 116*a257cdd0SAndreas Gruenbacher if (!nfserr) { 117*a257cdd0SAndreas Gruenbacher nfserr = nfserrno( nfsd_set_posix_acl( 118*a257cdd0SAndreas Gruenbacher fh, ACL_TYPE_DEFAULT, argp->acl_default) ); 119*a257cdd0SAndreas Gruenbacher } 120*a257cdd0SAndreas Gruenbacher 121*a257cdd0SAndreas Gruenbacher /* argp->acl_{access,default} may have been allocated in 122*a257cdd0SAndreas Gruenbacher nfssvc_decode_setaclargs. */ 123*a257cdd0SAndreas Gruenbacher posix_acl_release(argp->acl_access); 124*a257cdd0SAndreas Gruenbacher posix_acl_release(argp->acl_default); 125*a257cdd0SAndreas Gruenbacher return nfserr; 126*a257cdd0SAndreas Gruenbacher } 127*a257cdd0SAndreas Gruenbacher 128*a257cdd0SAndreas Gruenbacher /* 129*a257cdd0SAndreas Gruenbacher * Check file attributes 130*a257cdd0SAndreas Gruenbacher */ 131*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_getattr(struct svc_rqst * rqstp, 132*a257cdd0SAndreas Gruenbacher struct nfsd_fhandle *argp, struct nfsd_attrstat *resp) 133*a257cdd0SAndreas Gruenbacher { 134*a257cdd0SAndreas Gruenbacher dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); 135*a257cdd0SAndreas Gruenbacher 136*a257cdd0SAndreas Gruenbacher fh_copy(&resp->fh, &argp->fh); 137*a257cdd0SAndreas Gruenbacher return fh_verify(rqstp, &resp->fh, 0, MAY_NOP); 138*a257cdd0SAndreas Gruenbacher } 139*a257cdd0SAndreas Gruenbacher 140*a257cdd0SAndreas Gruenbacher /* 141*a257cdd0SAndreas Gruenbacher * Check file access 142*a257cdd0SAndreas Gruenbacher */ 143*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, 144*a257cdd0SAndreas Gruenbacher struct nfsd3_accessres *resp) 145*a257cdd0SAndreas Gruenbacher { 146*a257cdd0SAndreas Gruenbacher int nfserr; 147*a257cdd0SAndreas Gruenbacher 148*a257cdd0SAndreas Gruenbacher dprintk("nfsd: ACCESS(2acl) %s 0x%x\n", 149*a257cdd0SAndreas Gruenbacher SVCFH_fmt(&argp->fh), 150*a257cdd0SAndreas Gruenbacher argp->access); 151*a257cdd0SAndreas Gruenbacher 152*a257cdd0SAndreas Gruenbacher fh_copy(&resp->fh, &argp->fh); 153*a257cdd0SAndreas Gruenbacher resp->access = argp->access; 154*a257cdd0SAndreas Gruenbacher nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL); 155*a257cdd0SAndreas Gruenbacher return nfserr; 156*a257cdd0SAndreas Gruenbacher } 157*a257cdd0SAndreas Gruenbacher 158*a257cdd0SAndreas Gruenbacher /* 159*a257cdd0SAndreas Gruenbacher * XDR decode functions 160*a257cdd0SAndreas Gruenbacher */ 161*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p, 162*a257cdd0SAndreas Gruenbacher struct nfsd3_getaclargs *argp) 163*a257cdd0SAndreas Gruenbacher { 164*a257cdd0SAndreas Gruenbacher if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 165*a257cdd0SAndreas Gruenbacher return 0; 166*a257cdd0SAndreas Gruenbacher argp->mask = ntohl(*p); p++; 167*a257cdd0SAndreas Gruenbacher 168*a257cdd0SAndreas Gruenbacher return xdr_argsize_check(rqstp, p); 169*a257cdd0SAndreas Gruenbacher } 170*a257cdd0SAndreas Gruenbacher 171*a257cdd0SAndreas Gruenbacher 172*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p, 173*a257cdd0SAndreas Gruenbacher struct nfsd3_setaclargs *argp) 174*a257cdd0SAndreas Gruenbacher { 175*a257cdd0SAndreas Gruenbacher struct kvec *head = rqstp->rq_arg.head; 176*a257cdd0SAndreas Gruenbacher unsigned int base; 177*a257cdd0SAndreas Gruenbacher int n; 178*a257cdd0SAndreas Gruenbacher 179*a257cdd0SAndreas Gruenbacher if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 180*a257cdd0SAndreas Gruenbacher return 0; 181*a257cdd0SAndreas Gruenbacher argp->mask = ntohl(*p++); 182*a257cdd0SAndreas Gruenbacher if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) || 183*a257cdd0SAndreas Gruenbacher !xdr_argsize_check(rqstp, p)) 184*a257cdd0SAndreas Gruenbacher return 0; 185*a257cdd0SAndreas Gruenbacher 186*a257cdd0SAndreas Gruenbacher base = (char *)p - (char *)head->iov_base; 187*a257cdd0SAndreas Gruenbacher n = nfsacl_decode(&rqstp->rq_arg, base, NULL, 188*a257cdd0SAndreas Gruenbacher (argp->mask & NFS_ACL) ? 189*a257cdd0SAndreas Gruenbacher &argp->acl_access : NULL); 190*a257cdd0SAndreas Gruenbacher if (n > 0) 191*a257cdd0SAndreas Gruenbacher n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL, 192*a257cdd0SAndreas Gruenbacher (argp->mask & NFS_DFACL) ? 193*a257cdd0SAndreas Gruenbacher &argp->acl_default : NULL); 194*a257cdd0SAndreas Gruenbacher return (n > 0); 195*a257cdd0SAndreas Gruenbacher } 196*a257cdd0SAndreas Gruenbacher 197*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p, 198*a257cdd0SAndreas Gruenbacher struct nfsd_fhandle *argp) 199*a257cdd0SAndreas Gruenbacher { 200*a257cdd0SAndreas Gruenbacher if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 201*a257cdd0SAndreas Gruenbacher return 0; 202*a257cdd0SAndreas Gruenbacher return xdr_argsize_check(rqstp, p); 203*a257cdd0SAndreas Gruenbacher } 204*a257cdd0SAndreas Gruenbacher 205*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p, 206*a257cdd0SAndreas Gruenbacher struct nfsd3_accessargs *argp) 207*a257cdd0SAndreas Gruenbacher { 208*a257cdd0SAndreas Gruenbacher if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 209*a257cdd0SAndreas Gruenbacher return 0; 210*a257cdd0SAndreas Gruenbacher argp->access = ntohl(*p++); 211*a257cdd0SAndreas Gruenbacher 212*a257cdd0SAndreas Gruenbacher return xdr_argsize_check(rqstp, p); 213*a257cdd0SAndreas Gruenbacher } 214*a257cdd0SAndreas Gruenbacher 215*a257cdd0SAndreas Gruenbacher /* 216*a257cdd0SAndreas Gruenbacher * XDR encode functions 217*a257cdd0SAndreas Gruenbacher */ 218*a257cdd0SAndreas Gruenbacher 219*a257cdd0SAndreas Gruenbacher /* GETACL */ 220*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, 221*a257cdd0SAndreas Gruenbacher struct nfsd3_getaclres *resp) 222*a257cdd0SAndreas Gruenbacher { 223*a257cdd0SAndreas Gruenbacher struct dentry *dentry = resp->fh.fh_dentry; 224*a257cdd0SAndreas Gruenbacher struct inode *inode = dentry->d_inode; 225*a257cdd0SAndreas Gruenbacher int w = nfsacl_size( 226*a257cdd0SAndreas Gruenbacher (resp->mask & NFS_ACL) ? resp->acl_access : NULL, 227*a257cdd0SAndreas Gruenbacher (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); 228*a257cdd0SAndreas Gruenbacher struct kvec *head = rqstp->rq_res.head; 229*a257cdd0SAndreas Gruenbacher unsigned int base; 230*a257cdd0SAndreas Gruenbacher int n; 231*a257cdd0SAndreas Gruenbacher 232*a257cdd0SAndreas Gruenbacher if (dentry == NULL || dentry->d_inode == NULL) 233*a257cdd0SAndreas Gruenbacher return 0; 234*a257cdd0SAndreas Gruenbacher inode = dentry->d_inode; 235*a257cdd0SAndreas Gruenbacher 236*a257cdd0SAndreas Gruenbacher p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); 237*a257cdd0SAndreas Gruenbacher *p++ = htonl(resp->mask); 238*a257cdd0SAndreas Gruenbacher if (!xdr_ressize_check(rqstp, p)) 239*a257cdd0SAndreas Gruenbacher return 0; 240*a257cdd0SAndreas Gruenbacher base = (char *)p - (char *)head->iov_base; 241*a257cdd0SAndreas Gruenbacher 242*a257cdd0SAndreas Gruenbacher rqstp->rq_res.page_len = w; 243*a257cdd0SAndreas Gruenbacher while (w > 0) { 244*a257cdd0SAndreas Gruenbacher if (!svc_take_res_page(rqstp)) 245*a257cdd0SAndreas Gruenbacher return 0; 246*a257cdd0SAndreas Gruenbacher w -= PAGE_SIZE; 247*a257cdd0SAndreas Gruenbacher } 248*a257cdd0SAndreas Gruenbacher 249*a257cdd0SAndreas Gruenbacher n = nfsacl_encode(&rqstp->rq_res, base, inode, 250*a257cdd0SAndreas Gruenbacher resp->acl_access, 251*a257cdd0SAndreas Gruenbacher resp->mask & NFS_ACL, 0); 252*a257cdd0SAndreas Gruenbacher if (n > 0) 253*a257cdd0SAndreas Gruenbacher n = nfsacl_encode(&rqstp->rq_res, base + n, inode, 254*a257cdd0SAndreas Gruenbacher resp->acl_default, 255*a257cdd0SAndreas Gruenbacher resp->mask & NFS_DFACL, 256*a257cdd0SAndreas Gruenbacher NFS_ACL_DEFAULT); 257*a257cdd0SAndreas Gruenbacher if (n <= 0) 258*a257cdd0SAndreas Gruenbacher return 0; 259*a257cdd0SAndreas Gruenbacher return 1; 260*a257cdd0SAndreas Gruenbacher } 261*a257cdd0SAndreas Gruenbacher 262*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p, 263*a257cdd0SAndreas Gruenbacher struct nfsd_attrstat *resp) 264*a257cdd0SAndreas Gruenbacher { 265*a257cdd0SAndreas Gruenbacher p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); 266*a257cdd0SAndreas Gruenbacher return xdr_ressize_check(rqstp, p); 267*a257cdd0SAndreas Gruenbacher } 268*a257cdd0SAndreas Gruenbacher 269*a257cdd0SAndreas Gruenbacher /* ACCESS */ 270*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p, 271*a257cdd0SAndreas Gruenbacher struct nfsd3_accessres *resp) 272*a257cdd0SAndreas Gruenbacher { 273*a257cdd0SAndreas Gruenbacher p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); 274*a257cdd0SAndreas Gruenbacher *p++ = htonl(resp->access); 275*a257cdd0SAndreas Gruenbacher return xdr_ressize_check(rqstp, p); 276*a257cdd0SAndreas Gruenbacher } 277*a257cdd0SAndreas Gruenbacher 278*a257cdd0SAndreas Gruenbacher /* 279*a257cdd0SAndreas Gruenbacher * XDR release functions 280*a257cdd0SAndreas Gruenbacher */ 281*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p, 282*a257cdd0SAndreas Gruenbacher struct nfsd3_getaclres *resp) 283*a257cdd0SAndreas Gruenbacher { 284*a257cdd0SAndreas Gruenbacher fh_put(&resp->fh); 285*a257cdd0SAndreas Gruenbacher posix_acl_release(resp->acl_access); 286*a257cdd0SAndreas Gruenbacher posix_acl_release(resp->acl_default); 287*a257cdd0SAndreas Gruenbacher return 1; 288*a257cdd0SAndreas Gruenbacher } 289*a257cdd0SAndreas Gruenbacher 290*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p, 291*a257cdd0SAndreas Gruenbacher struct nfsd_fhandle *resp) 292*a257cdd0SAndreas Gruenbacher { 293*a257cdd0SAndreas Gruenbacher fh_put(&resp->fh); 294*a257cdd0SAndreas Gruenbacher return 1; 295*a257cdd0SAndreas Gruenbacher } 296*a257cdd0SAndreas Gruenbacher 297*a257cdd0SAndreas Gruenbacher #define nfsaclsvc_decode_voidargs NULL 298*a257cdd0SAndreas Gruenbacher #define nfsaclsvc_encode_voidres NULL 299*a257cdd0SAndreas Gruenbacher #define nfsaclsvc_release_void NULL 300*a257cdd0SAndreas Gruenbacher #define nfsd3_fhandleargs nfsd_fhandle 301*a257cdd0SAndreas Gruenbacher #define nfsd3_attrstatres nfsd_attrstat 302*a257cdd0SAndreas Gruenbacher #define nfsd3_voidres nfsd3_voidargs 303*a257cdd0SAndreas Gruenbacher struct nfsd3_voidargs { int dummy; }; 304*a257cdd0SAndreas Gruenbacher 305*a257cdd0SAndreas Gruenbacher #define PROC(name, argt, rest, relt, cache, respsize) \ 306*a257cdd0SAndreas Gruenbacher { (svc_procfunc) nfsacld_proc_##name, \ 307*a257cdd0SAndreas Gruenbacher (kxdrproc_t) nfsaclsvc_decode_##argt##args, \ 308*a257cdd0SAndreas Gruenbacher (kxdrproc_t) nfsaclsvc_encode_##rest##res, \ 309*a257cdd0SAndreas Gruenbacher (kxdrproc_t) nfsaclsvc_release_##relt, \ 310*a257cdd0SAndreas Gruenbacher sizeof(struct nfsd3_##argt##args), \ 311*a257cdd0SAndreas Gruenbacher sizeof(struct nfsd3_##rest##res), \ 312*a257cdd0SAndreas Gruenbacher 0, \ 313*a257cdd0SAndreas Gruenbacher cache, \ 314*a257cdd0SAndreas Gruenbacher respsize, \ 315*a257cdd0SAndreas Gruenbacher } 316*a257cdd0SAndreas Gruenbacher 317*a257cdd0SAndreas Gruenbacher #define ST 1 /* status*/ 318*a257cdd0SAndreas Gruenbacher #define AT 21 /* attributes */ 319*a257cdd0SAndreas Gruenbacher #define pAT (1+AT) /* post attributes - conditional */ 320*a257cdd0SAndreas Gruenbacher #define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */ 321*a257cdd0SAndreas Gruenbacher 322*a257cdd0SAndreas Gruenbacher static struct svc_procedure nfsd_acl_procedures2[] = { 323*a257cdd0SAndreas Gruenbacher PROC(null, void, void, void, RC_NOCACHE, ST), 324*a257cdd0SAndreas Gruenbacher PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)), 325*a257cdd0SAndreas Gruenbacher PROC(setacl, setacl, attrstat, fhandle, RC_NOCACHE, ST+AT), 326*a257cdd0SAndreas Gruenbacher PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE, ST+AT), 327*a257cdd0SAndreas Gruenbacher PROC(access, access, access, fhandle, RC_NOCACHE, ST+AT+1), 328*a257cdd0SAndreas Gruenbacher }; 329*a257cdd0SAndreas Gruenbacher 330*a257cdd0SAndreas Gruenbacher struct svc_version nfsd_acl_version2 = { 331*a257cdd0SAndreas Gruenbacher .vs_vers = 2, 332*a257cdd0SAndreas Gruenbacher .vs_nproc = 5, 333*a257cdd0SAndreas Gruenbacher .vs_proc = nfsd_acl_procedures2, 334*a257cdd0SAndreas Gruenbacher .vs_dispatch = nfsd_dispatch, 335*a257cdd0SAndreas Gruenbacher .vs_xdrsize = NFS3_SVC_XDRSIZE, 336*a257cdd0SAndreas Gruenbacher }; 337