diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 788adf3897c7..dfed4f5c8fcc 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -1659,7 +1659,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun | |||
1659 | *p = cpu_to_be32(FATTR4_WORD0_ACL); | 1659 | *p = cpu_to_be32(FATTR4_WORD0_ACL); |
1660 | p = reserve_space(xdr, 4); | 1660 | p = reserve_space(xdr, 4); |
1661 | *p = cpu_to_be32(arg->acl_len); | 1661 | *p = cpu_to_be32(arg->acl_len); |
1662 | xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); | 1662 | xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); |
1663 | } | 1663 | } |
1664 | 1664 | ||
1665 | static void | 1665 | static void |
@@ -2491,7 +2491,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
2491 | encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); | 2491 | encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); |
2492 | 2492 | ||
2493 | xdr_inline_pages(&req->rq_rcv_buf, replen << 2, | 2493 | xdr_inline_pages(&req->rq_rcv_buf, replen << 2, |
2494 | args->acl_pages, args->acl_pgbase, args->acl_len); | 2494 | args->acl_pages, 0, args->acl_len); |
2495 | 2495 | ||
2496 | encode_nops(&hdr); | 2496 | encode_nops(&hdr); |
2497 | } | 2497 | } |
@@ -4375,6 +4375,11 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) | |||
4375 | goto xdr_error; | 4375 | goto xdr_error; |
4376 | if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) | 4376 | if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) |
4377 | goto xdr_error; | 4377 | goto xdr_error; |
4378 | |||
4379 | status = -EIO; | ||
4380 | if (unlikely(bitmap[0])) | ||
4381 | goto xdr_error; | ||
4382 | |||
4378 | if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) | 4383 | if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) |
4379 | goto xdr_error; | 4384 | goto xdr_error; |
4380 | if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) | 4385 | if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) |
@@ -4574,6 +4579,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4574 | goto xdr_error; | 4579 | goto xdr_error; |
4575 | fattr->valid |= status; | 4580 | fattr->valid |= status; |
4576 | 4581 | ||
4582 | status = -EIO; | ||
4583 | if (unlikely(bitmap[0])) | ||
4584 | goto xdr_error; | ||
4585 | |||
4577 | status = decode_attr_mode(xdr, bitmap, &fmode); | 4586 | status = decode_attr_mode(xdr, bitmap, &fmode); |
4578 | if (status < 0) | 4587 | if (status < 0) |
4579 | goto xdr_error; | 4588 | goto xdr_error; |
@@ -4627,6 +4636,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4627 | goto xdr_error; | 4636 | goto xdr_error; |
4628 | fattr->valid |= status; | 4637 | fattr->valid |= status; |
4629 | 4638 | ||
4639 | status = -EIO; | ||
4640 | if (unlikely(bitmap[1])) | ||
4641 | goto xdr_error; | ||
4642 | |||
4630 | status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); | 4643 | status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); |
4631 | if (status < 0) | 4644 | if (status < 0) |
4632 | goto xdr_error; | 4645 | goto xdr_error; |
@@ -4764,6 +4777,28 @@ static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4764 | return 0; | 4777 | return 0; |
4765 | } | 4778 | } |
4766 | 4779 | ||
4780 | /* | ||
4781 | * The granularity of a CLONE operation. | ||
4782 | */ | ||
4783 | static int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap, | ||
4784 | uint32_t *res) | ||
4785 | { | ||
4786 | __be32 *p; | ||
4787 | |||
4788 | dprintk("%s: bitmap is %x\n", __func__, bitmap[2]); | ||
4789 | *res = 0; | ||
4790 | if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) { | ||
4791 | p = xdr_inline_decode(xdr, 4); | ||
4792 | if (unlikely(!p)) { | ||
4793 | print_overflow_msg(__func__, xdr); | ||
4794 | return -EIO; | ||
4795 | } | ||
4796 | *res = be32_to_cpup(p); | ||
4797 | bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE; | ||
4798 | } | ||
4799 | return 0; | ||
4800 | } | ||
4801 | |||
4767 | static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | 4802 | static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) |
4768 | { | 4803 | { |
4769 | unsigned int savep; | 4804 | unsigned int savep; |
@@ -4789,15 +4824,28 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | |||
4789 | if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) | 4824 | if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) |
4790 | goto xdr_error; | 4825 | goto xdr_error; |
4791 | fsinfo->wtpref = fsinfo->wtmax; | 4826 | fsinfo->wtpref = fsinfo->wtmax; |
4827 | |||
4828 | status = -EIO; | ||
4829 | if (unlikely(bitmap[0])) | ||
4830 | goto xdr_error; | ||
4831 | |||
4792 | status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); | 4832 | status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); |
4793 | if (status != 0) | 4833 | if (status != 0) |
4794 | goto xdr_error; | 4834 | goto xdr_error; |
4795 | status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); | 4835 | status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); |
4796 | if (status != 0) | 4836 | if (status != 0) |
4797 | goto xdr_error; | 4837 | goto xdr_error; |
4838 | |||
4839 | status = -EIO; | ||
4840 | if (unlikely(bitmap[1])) | ||
4841 | goto xdr_error; | ||
4842 | |||
4798 | status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); | 4843 | status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); |
4799 | if (status) | 4844 | if (status) |
4800 | goto xdr_error; | 4845 | goto xdr_error; |
4846 | status = decode_attr_clone_blksize(xdr, bitmap, &fsinfo->clone_blksize); | ||
4847 | if (status) | ||
4848 | goto xdr_error; | ||
4801 | 4849 | ||
4802 | status = verify_attr_len(xdr, savep, attrlen); | 4850 | status = verify_attr_len(xdr, savep, attrlen); |
4803 | xdr_error: | 4851 | xdr_error: |
@@ -7465,6 +7513,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
7465 | PROC(ALLOCATE, enc_allocate, dec_allocate), | 7513 | PROC(ALLOCATE, enc_allocate, dec_allocate), |
7466 | PROC(DEALLOCATE, enc_deallocate, dec_deallocate), | 7514 | PROC(DEALLOCATE, enc_deallocate, dec_deallocate), |
7467 | PROC(LAYOUTSTATS, enc_layoutstats, dec_layoutstats), | 7515 | PROC(LAYOUTSTATS, enc_layoutstats, dec_layoutstats), |
7516 | PROC(CLONE, enc_clone, dec_clone), | ||
7468 | #endif /* CONFIG_NFS_V4_2 */ | 7517 | #endif /* CONFIG_NFS_V4_2 */ |
7469 | }; | 7518 | }; |
7470 | 7519 | ||