diff options
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 617273e7d47f..e65cc2e650c8 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -3075,7 +3075,8 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t | |||
| 3075 | return ret; | 3075 | return ret; |
| 3076 | } | 3076 | } |
| 3077 | 3077 | ||
| 3078 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid) | 3078 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, |
| 3079 | struct nfs_client *clp, uint32_t *uid, int may_sleep) | ||
| 3079 | { | 3080 | { |
| 3080 | uint32_t len; | 3081 | uint32_t len; |
| 3081 | __be32 *p; | 3082 | __be32 *p; |
| @@ -3088,7 +3089,9 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
| 3088 | READ_BUF(4); | 3089 | READ_BUF(4); |
| 3089 | READ32(len); | 3090 | READ32(len); |
| 3090 | READ_BUF(len); | 3091 | READ_BUF(len); |
| 3091 | if (len < XDR_MAX_NETOBJ) { | 3092 | if (!may_sleep) { |
| 3093 | /* do nothing */ | ||
| 3094 | } else if (len < XDR_MAX_NETOBJ) { | ||
| 3092 | if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) | 3095 | if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) |
| 3093 | ret = NFS_ATTR_FATTR_OWNER; | 3096 | ret = NFS_ATTR_FATTR_OWNER; |
| 3094 | else | 3097 | else |
| @@ -3103,7 +3106,8 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
| 3103 | return ret; | 3106 | return ret; |
| 3104 | } | 3107 | } |
| 3105 | 3108 | ||
| 3106 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid) | 3109 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, |
| 3110 | struct nfs_client *clp, uint32_t *gid, int may_sleep) | ||
| 3107 | { | 3111 | { |
| 3108 | uint32_t len; | 3112 | uint32_t len; |
| 3109 | __be32 *p; | 3113 | __be32 *p; |
| @@ -3116,7 +3120,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
| 3116 | READ_BUF(4); | 3120 | READ_BUF(4); |
| 3117 | READ32(len); | 3121 | READ32(len); |
| 3118 | READ_BUF(len); | 3122 | READ_BUF(len); |
| 3119 | if (len < XDR_MAX_NETOBJ) { | 3123 | if (!may_sleep) { |
| 3124 | /* do nothing */ | ||
| 3125 | } else if (len < XDR_MAX_NETOBJ) { | ||
| 3120 | if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) | 3126 | if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) |
| 3121 | ret = NFS_ATTR_FATTR_GROUP; | 3127 | ret = NFS_ATTR_FATTR_GROUP; |
| 3122 | else | 3128 | else |
| @@ -3466,7 +3472,8 @@ xdr_error: | |||
| 3466 | return status; | 3472 | return status; |
| 3467 | } | 3473 | } |
| 3468 | 3474 | ||
| 3469 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server) | 3475 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, |
| 3476 | const struct nfs_server *server, int may_sleep) | ||
| 3470 | { | 3477 | { |
| 3471 | __be32 *savep; | 3478 | __be32 *savep; |
| 3472 | uint32_t attrlen, | 3479 | uint32_t attrlen, |
| @@ -3538,12 +3545,14 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons | |||
| 3538 | goto xdr_error; | 3545 | goto xdr_error; |
| 3539 | fattr->valid |= status; | 3546 | fattr->valid |= status; |
| 3540 | 3547 | ||
| 3541 | status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid); | 3548 | status = decode_attr_owner(xdr, bitmap, server->nfs_client, |
| 3549 | &fattr->uid, may_sleep); | ||
| 3542 | if (status < 0) | 3550 | if (status < 0) |
| 3543 | goto xdr_error; | 3551 | goto xdr_error; |
| 3544 | fattr->valid |= status; | 3552 | fattr->valid |= status; |
| 3545 | 3553 | ||
| 3546 | status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid); | 3554 | status = decode_attr_group(xdr, bitmap, server->nfs_client, |
| 3555 | &fattr->gid, may_sleep); | ||
| 3547 | if (status < 0) | 3556 | if (status < 0) |
| 3548 | goto xdr_error; | 3557 | goto xdr_error; |
| 3549 | fattr->valid |= status; | 3558 | fattr->valid |= status; |
| @@ -4370,7 +4379,8 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct | |||
| 4370 | status = decode_open_downgrade(&xdr, res); | 4379 | status = decode_open_downgrade(&xdr, res); |
| 4371 | if (status != 0) | 4380 | if (status != 0) |
| 4372 | goto out; | 4381 | goto out; |
| 4373 | decode_getfattr(&xdr, res->fattr, res->server); | 4382 | decode_getfattr(&xdr, res->fattr, res->server, |
| 4383 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4374 | out: | 4384 | out: |
| 4375 | return status; | 4385 | return status; |
| 4376 | } | 4386 | } |
| @@ -4397,7 +4407,8 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac | |||
| 4397 | status = decode_access(&xdr, res); | 4407 | status = decode_access(&xdr, res); |
| 4398 | if (status != 0) | 4408 | if (status != 0) |
| 4399 | goto out; | 4409 | goto out; |
| 4400 | decode_getfattr(&xdr, res->fattr, res->server); | 4410 | decode_getfattr(&xdr, res->fattr, res->server, |
| 4411 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4401 | out: | 4412 | out: |
| 4402 | return status; | 4413 | return status; |
| 4403 | } | 4414 | } |
| @@ -4424,7 +4435,8 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo | |||
| 4424 | goto out; | 4435 | goto out; |
| 4425 | if ((status = decode_getfh(&xdr, res->fh)) != 0) | 4436 | if ((status = decode_getfh(&xdr, res->fh)) != 0) |
| 4426 | goto out; | 4437 | goto out; |
| 4427 | status = decode_getfattr(&xdr, res->fattr, res->server); | 4438 | status = decode_getfattr(&xdr, res->fattr, res->server |
| 4439 | ,!RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4428 | out: | 4440 | out: |
| 4429 | return status; | 4441 | return status; |
| 4430 | } | 4442 | } |
| @@ -4448,7 +4460,8 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf | |||
| 4448 | if ((status = decode_putrootfh(&xdr)) != 0) | 4460 | if ((status = decode_putrootfh(&xdr)) != 0) |
| 4449 | goto out; | 4461 | goto out; |
| 4450 | if ((status = decode_getfh(&xdr, res->fh)) == 0) | 4462 | if ((status = decode_getfh(&xdr, res->fh)) == 0) |
| 4451 | status = decode_getfattr(&xdr, res->fattr, res->server); | 4463 | status = decode_getfattr(&xdr, res->fattr, res->server, |
| 4464 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4452 | out: | 4465 | out: |
| 4453 | return status; | 4466 | return status; |
| 4454 | } | 4467 | } |
| @@ -4473,7 +4486,8 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem | |||
| 4473 | goto out; | 4486 | goto out; |
| 4474 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) | 4487 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) |
| 4475 | goto out; | 4488 | goto out; |
| 4476 | decode_getfattr(&xdr, &res->dir_attr, res->server); | 4489 | decode_getfattr(&xdr, &res->dir_attr, res->server, |
| 4490 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4477 | out: | 4491 | out: |
| 4478 | return status; | 4492 | return status; |
| 4479 | } | 4493 | } |
| @@ -4503,11 +4517,13 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re | |||
| 4503 | if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) | 4517 | if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) |
| 4504 | goto out; | 4518 | goto out; |
| 4505 | /* Current FH is target directory */ | 4519 | /* Current FH is target directory */ |
| 4506 | if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0) | 4520 | if (decode_getfattr(&xdr, res->new_fattr, res->server, |
| 4521 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
| 4507 | goto out; | 4522 | goto out; |
| 4508 | if ((status = decode_restorefh(&xdr)) != 0) | 4523 | if ((status = decode_restorefh(&xdr)) != 0) |
| 4509 | goto out; | 4524 | goto out; |
| 4510 | decode_getfattr(&xdr, res->old_fattr, res->server); | 4525 | decode_getfattr(&xdr, res->old_fattr, res->server, |
| 4526 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4511 | out: | 4527 | out: |
| 4512 | return status; | 4528 | return status; |
| 4513 | } | 4529 | } |
| @@ -4540,11 +4556,13 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link | |||
| 4540 | * Note order: OP_LINK leaves the directory as the current | 4556 | * Note order: OP_LINK leaves the directory as the current |
| 4541 | * filehandle. | 4557 | * filehandle. |
| 4542 | */ | 4558 | */ |
| 4543 | if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0) | 4559 | if (decode_getfattr(&xdr, res->dir_attr, res->server, |
| 4560 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
| 4544 | goto out; | 4561 | goto out; |
| 4545 | if ((status = decode_restorefh(&xdr)) != 0) | 4562 | if ((status = decode_restorefh(&xdr)) != 0) |
| 4546 | goto out; | 4563 | goto out; |
| 4547 | decode_getfattr(&xdr, res->fattr, res->server); | 4564 | decode_getfattr(&xdr, res->fattr, res->server, |
| 4565 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4548 | out: | 4566 | out: |
| 4549 | return status; | 4567 | return status; |
| 4550 | } | 4568 | } |
| @@ -4573,11 +4591,13 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr | |||
| 4573 | goto out; | 4591 | goto out; |
| 4574 | if ((status = decode_getfh(&xdr, res->fh)) != 0) | 4592 | if ((status = decode_getfh(&xdr, res->fh)) != 0) |
| 4575 | goto out; | 4593 | goto out; |
| 4576 | if (decode_getfattr(&xdr, res->fattr, res->server) != 0) | 4594 | if (decode_getfattr(&xdr, res->fattr, res->server, |
| 4595 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
| 4577 | goto out; | 4596 | goto out; |
| 4578 | if ((status = decode_restorefh(&xdr)) != 0) | 4597 | if ((status = decode_restorefh(&xdr)) != 0) |
| 4579 | goto out; | 4598 | goto out; |
| 4580 | decode_getfattr(&xdr, res->dir_fattr, res->server); | 4599 | decode_getfattr(&xdr, res->dir_fattr, res->server, |
| 4600 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4581 | out: | 4601 | out: |
| 4582 | return status; | 4602 | return status; |
| 4583 | } | 4603 | } |
| @@ -4609,7 +4629,8 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g | |||
| 4609 | status = decode_putfh(&xdr); | 4629 | status = decode_putfh(&xdr); |
| 4610 | if (status) | 4630 | if (status) |
| 4611 | goto out; | 4631 | goto out; |
| 4612 | status = decode_getfattr(&xdr, res->fattr, res->server); | 4632 | status = decode_getfattr(&xdr, res->fattr, res->server, |
| 4633 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4613 | out: | 4634 | out: |
| 4614 | return status; | 4635 | return status; |
| 4615 | } | 4636 | } |
| @@ -4716,7 +4737,8 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos | |||
| 4716 | * an ESTALE error. Shouldn't be a problem, | 4737 | * an ESTALE error. Shouldn't be a problem, |
| 4717 | * though, since fattr->valid will remain unset. | 4738 | * though, since fattr->valid will remain unset. |
| 4718 | */ | 4739 | */ |
| 4719 | decode_getfattr(&xdr, res->fattr, res->server); | 4740 | decode_getfattr(&xdr, res->fattr, res->server, |
| 4741 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4720 | out: | 4742 | out: |
| 4721 | return status; | 4743 | return status; |
| 4722 | } | 4744 | } |
| @@ -4748,11 +4770,13 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr | |||
| 4748 | goto out; | 4770 | goto out; |
| 4749 | if (decode_getfh(&xdr, &res->fh) != 0) | 4771 | if (decode_getfh(&xdr, &res->fh) != 0) |
| 4750 | goto out; | 4772 | goto out; |
| 4751 | if (decode_getfattr(&xdr, res->f_attr, res->server) != 0) | 4773 | if (decode_getfattr(&xdr, res->f_attr, res->server, |
| 4774 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
| 4752 | goto out; | 4775 | goto out; |
| 4753 | if (decode_restorefh(&xdr) != 0) | 4776 | if (decode_restorefh(&xdr) != 0) |
| 4754 | goto out; | 4777 | goto out; |
| 4755 | decode_getfattr(&xdr, res->dir_attr, res->server); | 4778 | decode_getfattr(&xdr, res->dir_attr, res->server, |
| 4779 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4756 | out: | 4780 | out: |
| 4757 | return status; | 4781 | return status; |
| 4758 | } | 4782 | } |
| @@ -4800,7 +4824,8 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf | |||
| 4800 | status = decode_open(&xdr, res); | 4824 | status = decode_open(&xdr, res); |
| 4801 | if (status) | 4825 | if (status) |
| 4802 | goto out; | 4826 | goto out; |
| 4803 | decode_getfattr(&xdr, res->f_attr, res->server); | 4827 | decode_getfattr(&xdr, res->f_attr, res->server, |
| 4828 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4804 | out: | 4829 | out: |
| 4805 | return status; | 4830 | return status; |
| 4806 | } | 4831 | } |
| @@ -4827,7 +4852,8 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se | |||
| 4827 | status = decode_setattr(&xdr); | 4852 | status = decode_setattr(&xdr); |
| 4828 | if (status) | 4853 | if (status) |
| 4829 | goto out; | 4854 | goto out; |
| 4830 | decode_getfattr(&xdr, res->fattr, res->server); | 4855 | decode_getfattr(&xdr, res->fattr, res->server, |
| 4856 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 4831 | out: | 4857 | out: |
| 4832 | return status; | 4858 | return status; |
| 4833 | } | 4859 | } |
| @@ -5001,7 +5027,8 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ | |||
| 5001 | status = decode_write(&xdr, res); | 5027 | status = decode_write(&xdr, res); |
| 5002 | if (status) | 5028 | if (status) |
| 5003 | goto out; | 5029 | goto out; |
| 5004 | decode_getfattr(&xdr, res->fattr, res->server); | 5030 | decode_getfattr(&xdr, res->fattr, res->server, |
| 5031 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 5005 | if (!status) | 5032 | if (!status) |
| 5006 | status = res->count; | 5033 | status = res->count; |
| 5007 | out: | 5034 | out: |
| @@ -5030,7 +5057,8 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri | |||
| 5030 | status = decode_commit(&xdr, res); | 5057 | status = decode_commit(&xdr, res); |
| 5031 | if (status) | 5058 | if (status) |
| 5032 | goto out; | 5059 | goto out; |
| 5033 | decode_getfattr(&xdr, res->fattr, res->server); | 5060 | decode_getfattr(&xdr, res->fattr, res->server, |
| 5061 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 5034 | out: | 5062 | out: |
| 5035 | return status; | 5063 | return status; |
| 5036 | } | 5064 | } |
| @@ -5194,7 +5222,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf | |||
| 5194 | if (status != 0) | 5222 | if (status != 0) |
| 5195 | goto out; | 5223 | goto out; |
| 5196 | status = decode_delegreturn(&xdr); | 5224 | status = decode_delegreturn(&xdr); |
| 5197 | decode_getfattr(&xdr, res->fattr, res->server); | 5225 | decode_getfattr(&xdr, res->fattr, res->server, |
| 5226 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
| 5198 | out: | 5227 | out: |
| 5199 | return status; | 5228 | return status; |
| 5200 | } | 5229 | } |
| @@ -5222,7 +5251,8 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, | |||
| 5222 | goto out; | 5251 | goto out; |
| 5223 | xdr_enter_page(&xdr, PAGE_SIZE); | 5252 | xdr_enter_page(&xdr, PAGE_SIZE); |
| 5224 | status = decode_getfattr(&xdr, &res->fs_locations->fattr, | 5253 | status = decode_getfattr(&xdr, &res->fs_locations->fattr, |
| 5225 | res->fs_locations->server); | 5254 | res->fs_locations->server, |
| 5255 | !RPC_IS_ASYNC(req->rq_task)); | ||
| 5226 | out: | 5256 | out: |
| 5227 | return status; | 5257 | return status; |
| 5228 | } | 5258 | } |
