| .. | .. |
|---|
| 14 | 14 | #include "vfs.h" |
|---|
| 15 | 15 | |
|---|
| 16 | 16 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
|---|
| 17 | | -#define RETURN_STATUS(st) { resp->status = (st); return (st); } |
|---|
| 18 | 17 | |
|---|
| 19 | 18 | /* |
|---|
| 20 | 19 | * NULL call. |
|---|
| .. | .. |
|---|
| 22 | 21 | static __be32 |
|---|
| 23 | 22 | nfsacld_proc_null(struct svc_rqst *rqstp) |
|---|
| 24 | 23 | { |
|---|
| 25 | | - return nfs_ok; |
|---|
| 24 | + return rpc_success; |
|---|
| 26 | 25 | } |
|---|
| 27 | 26 | |
|---|
| 28 | 27 | /* |
|---|
| .. | .. |
|---|
| 35 | 34 | struct posix_acl *acl; |
|---|
| 36 | 35 | struct inode *inode; |
|---|
| 37 | 36 | svc_fh *fh; |
|---|
| 38 | | - __be32 nfserr = 0; |
|---|
| 39 | 37 | |
|---|
| 40 | 38 | dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); |
|---|
| 41 | 39 | |
|---|
| 42 | 40 | fh = fh_copy(&resp->fh, &argp->fh); |
|---|
| 43 | | - nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); |
|---|
| 44 | | - if (nfserr) |
|---|
| 45 | | - RETURN_STATUS(nfserr); |
|---|
| 41 | + resp->status = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); |
|---|
| 42 | + if (resp->status != nfs_ok) |
|---|
| 43 | + goto out; |
|---|
| 46 | 44 | |
|---|
| 47 | 45 | inode = d_inode(fh->fh_dentry); |
|---|
| 48 | 46 | |
|---|
| 49 | | - if (argp->mask & ~NFS_ACL_MASK) |
|---|
| 50 | | - RETURN_STATUS(nfserr_inval); |
|---|
| 47 | + if (argp->mask & ~NFS_ACL_MASK) { |
|---|
| 48 | + resp->status = nfserr_inval; |
|---|
| 49 | + goto out; |
|---|
| 50 | + } |
|---|
| 51 | 51 | resp->mask = argp->mask; |
|---|
| 52 | 52 | |
|---|
| 53 | | - nfserr = fh_getattr(fh, &resp->stat); |
|---|
| 54 | | - if (nfserr) |
|---|
| 55 | | - RETURN_STATUS(nfserr); |
|---|
| 53 | + resp->status = fh_getattr(fh, &resp->stat); |
|---|
| 54 | + if (resp->status != nfs_ok) |
|---|
| 55 | + goto out; |
|---|
| 56 | 56 | |
|---|
| 57 | 57 | if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { |
|---|
| 58 | 58 | acl = get_acl(inode, ACL_TYPE_ACCESS); |
|---|
| .. | .. |
|---|
| 61 | 61 | acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); |
|---|
| 62 | 62 | } |
|---|
| 63 | 63 | if (IS_ERR(acl)) { |
|---|
| 64 | | - nfserr = nfserrno(PTR_ERR(acl)); |
|---|
| 64 | + resp->status = nfserrno(PTR_ERR(acl)); |
|---|
| 65 | 65 | goto fail; |
|---|
| 66 | 66 | } |
|---|
| 67 | 67 | resp->acl_access = acl; |
|---|
| .. | .. |
|---|
| 71 | 71 | of a non-directory! */ |
|---|
| 72 | 72 | acl = get_acl(inode, ACL_TYPE_DEFAULT); |
|---|
| 73 | 73 | if (IS_ERR(acl)) { |
|---|
| 74 | | - nfserr = nfserrno(PTR_ERR(acl)); |
|---|
| 74 | + resp->status = nfserrno(PTR_ERR(acl)); |
|---|
| 75 | 75 | goto fail; |
|---|
| 76 | 76 | } |
|---|
| 77 | 77 | resp->acl_default = acl; |
|---|
| 78 | 78 | } |
|---|
| 79 | 79 | |
|---|
| 80 | 80 | /* resp->acl_{access,default} are released in nfssvc_release_getacl. */ |
|---|
| 81 | | - RETURN_STATUS(0); |
|---|
| 81 | +out: |
|---|
| 82 | + return rpc_success; |
|---|
| 82 | 83 | |
|---|
| 83 | 84 | fail: |
|---|
| 84 | 85 | posix_acl_release(resp->acl_access); |
|---|
| 85 | 86 | posix_acl_release(resp->acl_default); |
|---|
| 86 | | - RETURN_STATUS(nfserr); |
|---|
| 87 | + goto out; |
|---|
| 87 | 88 | } |
|---|
| 88 | 89 | |
|---|
| 89 | 90 | /* |
|---|
| .. | .. |
|---|
| 95 | 96 | struct nfsd_attrstat *resp = rqstp->rq_resp; |
|---|
| 96 | 97 | struct inode *inode; |
|---|
| 97 | 98 | svc_fh *fh; |
|---|
| 98 | | - __be32 nfserr = 0; |
|---|
| 99 | 99 | int error; |
|---|
| 100 | 100 | |
|---|
| 101 | 101 | dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); |
|---|
| 102 | 102 | |
|---|
| 103 | 103 | fh = fh_copy(&resp->fh, &argp->fh); |
|---|
| 104 | | - nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR); |
|---|
| 105 | | - if (nfserr) |
|---|
| 104 | + resp->status = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR); |
|---|
| 105 | + if (resp->status != nfs_ok) |
|---|
| 106 | 106 | goto out; |
|---|
| 107 | 107 | |
|---|
| 108 | 108 | inode = d_inode(fh->fh_dentry); |
|---|
| .. | .. |
|---|
| 124 | 124 | |
|---|
| 125 | 125 | fh_drop_write(fh); |
|---|
| 126 | 126 | |
|---|
| 127 | | - nfserr = fh_getattr(fh, &resp->stat); |
|---|
| 127 | + resp->status = fh_getattr(fh, &resp->stat); |
|---|
| 128 | 128 | |
|---|
| 129 | 129 | out: |
|---|
| 130 | 130 | /* argp->acl_{access,default} may have been allocated in |
|---|
| 131 | 131 | nfssvc_decode_setaclargs. */ |
|---|
| 132 | 132 | posix_acl_release(argp->acl_access); |
|---|
| 133 | 133 | posix_acl_release(argp->acl_default); |
|---|
| 134 | | - return nfserr; |
|---|
| 134 | + return rpc_success; |
|---|
| 135 | + |
|---|
| 135 | 136 | out_drop_lock: |
|---|
| 136 | 137 | fh_unlock(fh); |
|---|
| 137 | 138 | fh_drop_write(fh); |
|---|
| 138 | 139 | out_errno: |
|---|
| 139 | | - nfserr = nfserrno(error); |
|---|
| 140 | + resp->status = nfserrno(error); |
|---|
| 140 | 141 | goto out; |
|---|
| 141 | 142 | } |
|---|
| 142 | 143 | |
|---|
| .. | .. |
|---|
| 147 | 148 | { |
|---|
| 148 | 149 | struct nfsd_fhandle *argp = rqstp->rq_argp; |
|---|
| 149 | 150 | struct nfsd_attrstat *resp = rqstp->rq_resp; |
|---|
| 150 | | - __be32 nfserr; |
|---|
| 151 | + |
|---|
| 151 | 152 | dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); |
|---|
| 152 | 153 | |
|---|
| 153 | 154 | fh_copy(&resp->fh, &argp->fh); |
|---|
| 154 | | - nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); |
|---|
| 155 | | - if (nfserr) |
|---|
| 156 | | - return nfserr; |
|---|
| 157 | | - nfserr = fh_getattr(&resp->fh, &resp->stat); |
|---|
| 158 | | - return nfserr; |
|---|
| 155 | + resp->status = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); |
|---|
| 156 | + if (resp->status != nfs_ok) |
|---|
| 157 | + goto out; |
|---|
| 158 | + resp->status = fh_getattr(&resp->fh, &resp->stat); |
|---|
| 159 | +out: |
|---|
| 160 | + return rpc_success; |
|---|
| 159 | 161 | } |
|---|
| 160 | 162 | |
|---|
| 161 | 163 | /* |
|---|
| .. | .. |
|---|
| 165 | 167 | { |
|---|
| 166 | 168 | struct nfsd3_accessargs *argp = rqstp->rq_argp; |
|---|
| 167 | 169 | struct nfsd3_accessres *resp = rqstp->rq_resp; |
|---|
| 168 | | - __be32 nfserr; |
|---|
| 169 | 170 | |
|---|
| 170 | 171 | dprintk("nfsd: ACCESS(2acl) %s 0x%x\n", |
|---|
| 171 | 172 | SVCFH_fmt(&argp->fh), |
|---|
| .. | .. |
|---|
| 173 | 174 | |
|---|
| 174 | 175 | fh_copy(&resp->fh, &argp->fh); |
|---|
| 175 | 176 | resp->access = argp->access; |
|---|
| 176 | | - nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL); |
|---|
| 177 | | - if (nfserr) |
|---|
| 178 | | - return nfserr; |
|---|
| 179 | | - nfserr = fh_getattr(&resp->fh, &resp->stat); |
|---|
| 180 | | - return nfserr; |
|---|
| 177 | + resp->status = nfsd_access(rqstp, &resp->fh, &resp->access, NULL); |
|---|
| 178 | + if (resp->status != nfs_ok) |
|---|
| 179 | + goto out; |
|---|
| 180 | + resp->status = fh_getattr(&resp->fh, &resp->stat); |
|---|
| 181 | +out: |
|---|
| 182 | + return rpc_success; |
|---|
| 181 | 183 | } |
|---|
| 182 | 184 | |
|---|
| 183 | 185 | /* |
|---|
| 184 | 186 | * XDR decode functions |
|---|
| 185 | 187 | */ |
|---|
| 188 | +static int nfsaclsvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p) |
|---|
| 189 | +{ |
|---|
| 190 | + return 1; |
|---|
| 191 | +} |
|---|
| 192 | + |
|---|
| 186 | 193 | static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p) |
|---|
| 187 | 194 | { |
|---|
| 188 | 195 | struct nfsd3_getaclargs *argp = rqstp->rq_argp; |
|---|
| .. | .. |
|---|
| 268 | 275 | int n; |
|---|
| 269 | 276 | int w; |
|---|
| 270 | 277 | |
|---|
| 278 | + *p++ = resp->status; |
|---|
| 279 | + if (resp->status != nfs_ok) |
|---|
| 280 | + return xdr_ressize_check(rqstp, p); |
|---|
| 281 | + |
|---|
| 271 | 282 | /* |
|---|
| 272 | 283 | * Since this is version 2, the check for nfserr in |
|---|
| 273 | 284 | * nfsd_dispatch actually ensures the following cannot happen. |
|---|
| .. | .. |
|---|
| 307 | 318 | { |
|---|
| 308 | 319 | struct nfsd_attrstat *resp = rqstp->rq_resp; |
|---|
| 309 | 320 | |
|---|
| 321 | + *p++ = resp->status; |
|---|
| 322 | + if (resp->status != nfs_ok) |
|---|
| 323 | + goto out; |
|---|
| 324 | + |
|---|
| 310 | 325 | p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
|---|
| 326 | +out: |
|---|
| 311 | 327 | return xdr_ressize_check(rqstp, p); |
|---|
| 312 | 328 | } |
|---|
| 313 | 329 | |
|---|
| .. | .. |
|---|
| 316 | 332 | { |
|---|
| 317 | 333 | struct nfsd3_accessres *resp = rqstp->rq_resp; |
|---|
| 318 | 334 | |
|---|
| 335 | + *p++ = resp->status; |
|---|
| 336 | + if (resp->status != nfs_ok) |
|---|
| 337 | + goto out; |
|---|
| 338 | + |
|---|
| 319 | 339 | p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
|---|
| 320 | 340 | *p++ = htonl(resp->access); |
|---|
| 341 | +out: |
|---|
| 321 | 342 | return xdr_ressize_check(rqstp, p); |
|---|
| 322 | 343 | } |
|---|
| 323 | 344 | |
|---|
| .. | .. |
|---|
| 347 | 368 | fh_put(&resp->fh); |
|---|
| 348 | 369 | } |
|---|
| 349 | 370 | |
|---|
| 350 | | -#define nfsaclsvc_decode_voidargs NULL |
|---|
| 351 | | -#define nfsaclsvc_release_void NULL |
|---|
| 352 | | -#define nfsd3_fhandleargs nfsd_fhandle |
|---|
| 353 | | -#define nfsd3_attrstatres nfsd_attrstat |
|---|
| 354 | | -#define nfsd3_voidres nfsd3_voidargs |
|---|
| 355 | 371 | struct nfsd3_voidargs { int dummy; }; |
|---|
| 356 | | - |
|---|
| 357 | | -#define PROC(name, argt, rest, relt, cache, respsize) \ |
|---|
| 358 | | -{ \ |
|---|
| 359 | | - .pc_func = nfsacld_proc_##name, \ |
|---|
| 360 | | - .pc_decode = nfsaclsvc_decode_##argt##args, \ |
|---|
| 361 | | - .pc_encode = nfsaclsvc_encode_##rest##res, \ |
|---|
| 362 | | - .pc_release = nfsaclsvc_release_##relt, \ |
|---|
| 363 | | - .pc_argsize = sizeof(struct nfsd3_##argt##args), \ |
|---|
| 364 | | - .pc_ressize = sizeof(struct nfsd3_##rest##res), \ |
|---|
| 365 | | - .pc_cachetype = cache, \ |
|---|
| 366 | | - .pc_xdrressize = respsize, \ |
|---|
| 367 | | -} |
|---|
| 368 | 372 | |
|---|
| 369 | 373 | #define ST 1 /* status*/ |
|---|
| 370 | 374 | #define AT 21 /* attributes */ |
|---|
| 371 | 375 | #define pAT (1+AT) /* post attributes - conditional */ |
|---|
| 372 | 376 | #define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */ |
|---|
| 373 | 377 | |
|---|
| 374 | | -static const struct svc_procedure nfsd_acl_procedures2[] = { |
|---|
| 375 | | - PROC(null, void, void, void, RC_NOCACHE, ST), |
|---|
| 376 | | - PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)), |
|---|
| 377 | | - PROC(setacl, setacl, attrstat, attrstat, RC_NOCACHE, ST+AT), |
|---|
| 378 | | - PROC(getattr, fhandle, attrstat, attrstat, RC_NOCACHE, ST+AT), |
|---|
| 379 | | - PROC(access, access, access, access, RC_NOCACHE, ST+AT+1), |
|---|
| 378 | +static const struct svc_procedure nfsd_acl_procedures2[5] = { |
|---|
| 379 | + [ACLPROC2_NULL] = { |
|---|
| 380 | + .pc_func = nfsacld_proc_null, |
|---|
| 381 | + .pc_decode = nfsaclsvc_decode_voidarg, |
|---|
| 382 | + .pc_encode = nfsaclsvc_encode_voidres, |
|---|
| 383 | + .pc_argsize = sizeof(struct nfsd3_voidargs), |
|---|
| 384 | + .pc_ressize = sizeof(struct nfsd3_voidargs), |
|---|
| 385 | + .pc_cachetype = RC_NOCACHE, |
|---|
| 386 | + .pc_xdrressize = ST, |
|---|
| 387 | + }, |
|---|
| 388 | + [ACLPROC2_GETACL] = { |
|---|
| 389 | + .pc_func = nfsacld_proc_getacl, |
|---|
| 390 | + .pc_decode = nfsaclsvc_decode_getaclargs, |
|---|
| 391 | + .pc_encode = nfsaclsvc_encode_getaclres, |
|---|
| 392 | + .pc_release = nfsaclsvc_release_getacl, |
|---|
| 393 | + .pc_argsize = sizeof(struct nfsd3_getaclargs), |
|---|
| 394 | + .pc_ressize = sizeof(struct nfsd3_getaclres), |
|---|
| 395 | + .pc_cachetype = RC_NOCACHE, |
|---|
| 396 | + .pc_xdrressize = ST+1+2*(1+ACL), |
|---|
| 397 | + }, |
|---|
| 398 | + [ACLPROC2_SETACL] = { |
|---|
| 399 | + .pc_func = nfsacld_proc_setacl, |
|---|
| 400 | + .pc_decode = nfsaclsvc_decode_setaclargs, |
|---|
| 401 | + .pc_encode = nfsaclsvc_encode_attrstatres, |
|---|
| 402 | + .pc_release = nfsaclsvc_release_attrstat, |
|---|
| 403 | + .pc_argsize = sizeof(struct nfsd3_setaclargs), |
|---|
| 404 | + .pc_ressize = sizeof(struct nfsd_attrstat), |
|---|
| 405 | + .pc_cachetype = RC_NOCACHE, |
|---|
| 406 | + .pc_xdrressize = ST+AT, |
|---|
| 407 | + }, |
|---|
| 408 | + [ACLPROC2_GETATTR] = { |
|---|
| 409 | + .pc_func = nfsacld_proc_getattr, |
|---|
| 410 | + .pc_decode = nfsaclsvc_decode_fhandleargs, |
|---|
| 411 | + .pc_encode = nfsaclsvc_encode_attrstatres, |
|---|
| 412 | + .pc_release = nfsaclsvc_release_attrstat, |
|---|
| 413 | + .pc_argsize = sizeof(struct nfsd_fhandle), |
|---|
| 414 | + .pc_ressize = sizeof(struct nfsd_attrstat), |
|---|
| 415 | + .pc_cachetype = RC_NOCACHE, |
|---|
| 416 | + .pc_xdrressize = ST+AT, |
|---|
| 417 | + }, |
|---|
| 418 | + [ACLPROC2_ACCESS] = { |
|---|
| 419 | + .pc_func = nfsacld_proc_access, |
|---|
| 420 | + .pc_decode = nfsaclsvc_decode_accessargs, |
|---|
| 421 | + .pc_encode = nfsaclsvc_encode_accessres, |
|---|
| 422 | + .pc_release = nfsaclsvc_release_access, |
|---|
| 423 | + .pc_argsize = sizeof(struct nfsd3_accessargs), |
|---|
| 424 | + .pc_ressize = sizeof(struct nfsd3_accessres), |
|---|
| 425 | + .pc_cachetype = RC_NOCACHE, |
|---|
| 426 | + .pc_xdrressize = ST+AT+1, |
|---|
| 427 | + }, |
|---|
| 380 | 428 | }; |
|---|
| 381 | 429 | |
|---|
| 382 | 430 | static unsigned int nfsd_acl_count2[ARRAY_SIZE(nfsd_acl_procedures2)]; |
|---|