summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c53
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
1665static void 1665static 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 */
4783static 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
4767static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 4802static 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);
4803xdr_error: 4851xdr_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