aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-31 12:26:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-31 12:26:50 -0400
commit24c3047095fa3954f114bfff2e37b8fcbb216396 (patch)
treea2263a4425d511ae619ca8b055705261dab9ec12 /fs/nfs/nfs4xdr.c
parent6581058f44533f9d45548bcfe986c125376859e9 (diff)
parent71cdd40fd498f12679070def668f6a4719ddbd1c (diff)
Merge branch 'nfs-for-3.1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'nfs-for-3.1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (28 commits) pnfsblock: write_pagelist handle zero invalid extents pnfsblock: note written INVAL areas for layoutcommit pnfsblock: bl_write_pagelist pnfsblock: bl_read_pagelist pnfsblock: cleanup_layoutcommit pnfsblock: encode_layoutcommit pnfsblock: merge rw extents pnfsblock: add extent manipulation functions pnfsblock: bl_find_get_extent pnfsblock: xdr decode pnfs_block_layout4 pnfsblock: call and parse getdevicelist pnfsblock: merge extents pnfsblock: lseg alloc and free pnfsblock: remove device operations pnfsblock: add device operations pnfsblock: basic extent code pnfsblock: use pageio_ops api pnfsblock: add blocklayout Kconfig option, Makefile, and stubs pnfs: cleanup_layoutcommit pnfs: ask for layout_blksize and save it in nfs_server ...
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c233
1 files changed, 215 insertions, 18 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index c191a9baa42..1dce12f41a4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -113,7 +113,11 @@ static int nfs4_stat_to_errno(int);
113#define encode_restorefh_maxsz (op_encode_hdr_maxsz) 113#define encode_restorefh_maxsz (op_encode_hdr_maxsz)
114#define decode_restorefh_maxsz (op_decode_hdr_maxsz) 114#define decode_restorefh_maxsz (op_decode_hdr_maxsz)
115#define encode_fsinfo_maxsz (encode_getattr_maxsz) 115#define encode_fsinfo_maxsz (encode_getattr_maxsz)
116#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 15) 116/* The 5 accounts for the PNFS attributes, and assumes that at most three
117 * layout types will be returned.
118 */
119#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + \
120 nfs4_fattr_bitmap_maxsz + 4 + 8 + 5)
117#define encode_renew_maxsz (op_encode_hdr_maxsz + 3) 121#define encode_renew_maxsz (op_encode_hdr_maxsz + 3)
118#define decode_renew_maxsz (op_decode_hdr_maxsz) 122#define decode_renew_maxsz (op_decode_hdr_maxsz)
119#define encode_setclientid_maxsz \ 123#define encode_setclientid_maxsz \
@@ -314,6 +318,17 @@ static int nfs4_stat_to_errno(int);
314 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) 318 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
315#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) 319#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)
316#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) 320#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)
321#define encode_getdevicelist_maxsz (op_encode_hdr_maxsz + 4 + \
322 encode_verifier_maxsz)
323#define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + \
324 2 /* nfs_cookie4 gdlr_cookie */ + \
325 decode_verifier_maxsz \
326 /* verifier4 gdlr_verifier */ + \
327 1 /* gdlr_deviceid_list count */ + \
328 XDR_QUADLEN(NFS4_PNFS_GETDEVLIST_MAXNUM * \
329 NFS4_DEVICEID4_SIZE) \
330 /* gdlr_deviceid_list */ + \
331 1 /* bool gdlr_eof */)
317#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \ 332#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \
318 XDR_QUADLEN(NFS4_DEVICEID4_SIZE)) 333 XDR_QUADLEN(NFS4_DEVICEID4_SIZE))
319#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ 334#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \
@@ -748,6 +763,14 @@ static int nfs4_stat_to_errno(int);
748#define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ 763#define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \
749 decode_sequence_maxsz + \ 764 decode_sequence_maxsz + \
750 decode_reclaim_complete_maxsz) 765 decode_reclaim_complete_maxsz)
766#define NFS4_enc_getdevicelist_sz (compound_encode_hdr_maxsz + \
767 encode_sequence_maxsz + \
768 encode_putfh_maxsz + \
769 encode_getdevicelist_maxsz)
770#define NFS4_dec_getdevicelist_sz (compound_decode_hdr_maxsz + \
771 decode_sequence_maxsz + \
772 decode_putfh_maxsz + \
773 decode_getdevicelist_maxsz)
751#define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ 774#define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \
752 encode_sequence_maxsz +\ 775 encode_sequence_maxsz +\
753 encode_getdeviceinfo_maxsz) 776 encode_getdeviceinfo_maxsz)
@@ -1104,6 +1127,35 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm
1104 hdr->replen += decode_getattr_maxsz; 1127 hdr->replen += decode_getattr_maxsz;
1105} 1128}
1106 1129
1130static void
1131encode_getattr_three(struct xdr_stream *xdr,
1132 uint32_t bm0, uint32_t bm1, uint32_t bm2,
1133 struct compound_hdr *hdr)
1134{
1135 __be32 *p;
1136
1137 p = reserve_space(xdr, 4);
1138 *p = cpu_to_be32(OP_GETATTR);
1139 if (bm2) {
1140 p = reserve_space(xdr, 16);
1141 *p++ = cpu_to_be32(3);
1142 *p++ = cpu_to_be32(bm0);
1143 *p++ = cpu_to_be32(bm1);
1144 *p = cpu_to_be32(bm2);
1145 } else if (bm1) {
1146 p = reserve_space(xdr, 12);
1147 *p++ = cpu_to_be32(2);
1148 *p++ = cpu_to_be32(bm0);
1149 *p = cpu_to_be32(bm1);
1150 } else {
1151 p = reserve_space(xdr, 8);
1152 *p++ = cpu_to_be32(1);
1153 *p = cpu_to_be32(bm0);
1154 }
1155 hdr->nops++;
1156 hdr->replen += decode_getattr_maxsz;
1157}
1158
1107static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1159static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1108{ 1160{
1109 encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], 1161 encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0],
@@ -1112,8 +1164,11 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c
1112 1164
1113static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1165static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1114{ 1166{
1115 encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0], 1167 encode_getattr_three(xdr,
1116 bitmask[1] & nfs4_fsinfo_bitmap[1], hdr); 1168 bitmask[0] & nfs4_fsinfo_bitmap[0],
1169 bitmask[1] & nfs4_fsinfo_bitmap[1],
1170 bitmask[2] & nfs4_fsinfo_bitmap[2],
1171 hdr);
1117} 1172}
1118 1173
1119static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1174static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
@@ -1855,6 +1910,26 @@ static void encode_sequence(struct xdr_stream *xdr,
1855 1910
1856#ifdef CONFIG_NFS_V4_1 1911#ifdef CONFIG_NFS_V4_1
1857static void 1912static void
1913encode_getdevicelist(struct xdr_stream *xdr,
1914 const struct nfs4_getdevicelist_args *args,
1915 struct compound_hdr *hdr)
1916{
1917 __be32 *p;
1918 nfs4_verifier dummy = {
1919 .data = "dummmmmy",
1920 };
1921
1922 p = reserve_space(xdr, 20);
1923 *p++ = cpu_to_be32(OP_GETDEVICELIST);
1924 *p++ = cpu_to_be32(args->layoutclass);
1925 *p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM);
1926 xdr_encode_hyper(p, 0ULL); /* cookie */
1927 encode_nfs4_verifier(xdr, &dummy);
1928 hdr->nops++;
1929 hdr->replen += decode_getdevicelist_maxsz;
1930}
1931
1932static void
1858encode_getdeviceinfo(struct xdr_stream *xdr, 1933encode_getdeviceinfo(struct xdr_stream *xdr,
1859 const struct nfs4_getdeviceinfo_args *args, 1934 const struct nfs4_getdeviceinfo_args *args,
1860 struct compound_hdr *hdr) 1935 struct compound_hdr *hdr)
@@ -1916,7 +1991,7 @@ encode_layoutcommit(struct xdr_stream *xdr,
1916 *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); 1991 *p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
1917 /* Only whole file layouts */ 1992 /* Only whole file layouts */
1918 p = xdr_encode_hyper(p, 0); /* offset */ 1993 p = xdr_encode_hyper(p, 0); /* offset */
1919 p = xdr_encode_hyper(p, NFS4_MAX_UINT64); /* length */ 1994 p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */
1920 *p++ = cpu_to_be32(0); /* reclaim */ 1995 *p++ = cpu_to_be32(0); /* reclaim */
1921 p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE); 1996 p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE);
1922 *p++ = cpu_to_be32(1); /* newoffset = TRUE */ 1997 *p++ = cpu_to_be32(1); /* newoffset = TRUE */
@@ -2604,7 +2679,7 @@ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req,
2604 struct compound_hdr hdr = { 2679 struct compound_hdr hdr = {
2605 .nops = 0, 2680 .nops = 0,
2606 }; 2681 };
2607 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; 2682 const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
2608 2683
2609 encode_compound_hdr(xdr, req, &hdr); 2684 encode_compound_hdr(xdr, req, &hdr);
2610 encode_setclientid_confirm(xdr, arg, &hdr); 2685 encode_setclientid_confirm(xdr, arg, &hdr);
@@ -2748,7 +2823,7 @@ static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req,
2748 struct compound_hdr hdr = { 2823 struct compound_hdr hdr = {
2749 .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), 2824 .minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
2750 }; 2825 };
2751 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; 2826 const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
2752 2827
2753 encode_compound_hdr(xdr, req, &hdr); 2828 encode_compound_hdr(xdr, req, &hdr);
2754 encode_sequence(xdr, &args->la_seq_args, &hdr); 2829 encode_sequence(xdr, &args->la_seq_args, &hdr);
@@ -2775,6 +2850,24 @@ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req,
2775} 2850}
2776 2851
2777/* 2852/*
2853 * Encode GETDEVICELIST request
2854 */
2855static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req,
2856 struct xdr_stream *xdr,
2857 struct nfs4_getdevicelist_args *args)
2858{
2859 struct compound_hdr hdr = {
2860 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2861 };
2862
2863 encode_compound_hdr(xdr, req, &hdr);
2864 encode_sequence(xdr, &args->seq_args, &hdr);
2865 encode_putfh(xdr, args->fh, &hdr);
2866 encode_getdevicelist(xdr, args, &hdr);
2867 encode_nops(&hdr);
2868}
2869
2870/*
2778 * Encode GETDEVICEINFO request 2871 * Encode GETDEVICEINFO request
2779 */ 2872 */
2780static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, 2873static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req,
@@ -3011,14 +3104,17 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
3011 goto out_overflow; 3104 goto out_overflow;
3012 bmlen = be32_to_cpup(p); 3105 bmlen = be32_to_cpup(p);
3013 3106
3014 bitmap[0] = bitmap[1] = 0; 3107 bitmap[0] = bitmap[1] = bitmap[2] = 0;
3015 p = xdr_inline_decode(xdr, (bmlen << 2)); 3108 p = xdr_inline_decode(xdr, (bmlen << 2));
3016 if (unlikely(!p)) 3109 if (unlikely(!p))
3017 goto out_overflow; 3110 goto out_overflow;
3018 if (bmlen > 0) { 3111 if (bmlen > 0) {
3019 bitmap[0] = be32_to_cpup(p++); 3112 bitmap[0] = be32_to_cpup(p++);
3020 if (bmlen > 1) 3113 if (bmlen > 1) {
3021 bitmap[1] = be32_to_cpup(p); 3114 bitmap[1] = be32_to_cpup(p++);
3115 if (bmlen > 2)
3116 bitmap[2] = be32_to_cpup(p);
3117 }
3022 } 3118 }
3023 return 0; 3119 return 0;
3024out_overflow: 3120out_overflow:
@@ -3050,8 +3146,9 @@ static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint3
3050 return ret; 3146 return ret;
3051 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; 3147 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
3052 } else 3148 } else
3053 bitmask[0] = bitmask[1] = 0; 3149 bitmask[0] = bitmask[1] = bitmask[2] = 0;
3054 dprintk("%s: bitmask=%08x:%08x\n", __func__, bitmask[0], bitmask[1]); 3150 dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__,
3151 bitmask[0], bitmask[1], bitmask[2]);
3055 return 0; 3152 return 0;
3056} 3153}
3057 3154
@@ -4105,7 +4202,7 @@ out_overflow:
4105static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) 4202static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
4106{ 4203{
4107 __be32 *savep; 4204 __be32 *savep;
4108 uint32_t attrlen, bitmap[2] = {0}; 4205 uint32_t attrlen, bitmap[3] = {0};
4109 int status; 4206 int status;
4110 4207
4111 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 4208 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
@@ -4131,7 +4228,7 @@ xdr_error:
4131static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) 4228static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
4132{ 4229{
4133 __be32 *savep; 4230 __be32 *savep;
4134 uint32_t attrlen, bitmap[2] = {0}; 4231 uint32_t attrlen, bitmap[3] = {0};
4135 int status; 4232 int status;
4136 4233
4137 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 4234 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
@@ -4163,7 +4260,7 @@ xdr_error:
4163static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) 4260static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
4164{ 4261{
4165 __be32 *savep; 4262 __be32 *savep;
4166 uint32_t attrlen, bitmap[2] = {0}; 4263 uint32_t attrlen, bitmap[3] = {0};
4167 int status; 4264 int status;
4168 4265
4169 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 4266 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
@@ -4303,7 +4400,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
4303{ 4400{
4304 __be32 *savep; 4401 __be32 *savep;
4305 uint32_t attrlen, 4402 uint32_t attrlen,
4306 bitmap[2] = {0}; 4403 bitmap[3] = {0};
4307 int status; 4404 int status;
4308 4405
4309 status = decode_op_hdr(xdr, OP_GETATTR); 4406 status = decode_op_hdr(xdr, OP_GETATTR);
@@ -4389,10 +4486,32 @@ static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
4389 return status; 4486 return status;
4390} 4487}
4391 4488
4489/*
4490 * The prefered block size for layout directed io
4491 */
4492static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
4493 uint32_t *res)
4494{
4495 __be32 *p;
4496
4497 dprintk("%s: bitmap is %x\n", __func__, bitmap[2]);
4498 *res = 0;
4499 if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) {
4500 p = xdr_inline_decode(xdr, 4);
4501 if (unlikely(!p)) {
4502 print_overflow_msg(__func__, xdr);
4503 return -EIO;
4504 }
4505 *res = be32_to_cpup(p);
4506 bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE;
4507 }
4508 return 0;
4509}
4510
4392static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 4511static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
4393{ 4512{
4394 __be32 *savep; 4513 __be32 *savep;
4395 uint32_t attrlen, bitmap[2]; 4514 uint32_t attrlen, bitmap[3];
4396 int status; 4515 int status;
4397 4516
4398 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 4517 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
@@ -4420,6 +4539,9 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
4420 status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); 4539 status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype);
4421 if (status != 0) 4540 if (status != 0)
4422 goto xdr_error; 4541 goto xdr_error;
4542 status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize);
4543 if (status)
4544 goto xdr_error;
4423 4545
4424 status = verify_attr_len(xdr, savep, attrlen); 4546 status = verify_attr_len(xdr, savep, attrlen);
4425xdr_error: 4547xdr_error:
@@ -4839,7 +4961,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4839{ 4961{
4840 __be32 *savep; 4962 __be32 *savep;
4841 uint32_t attrlen, 4963 uint32_t attrlen,
4842 bitmap[2] = {0}; 4964 bitmap[3] = {0};
4843 struct kvec *iov = req->rq_rcv_buf.head; 4965 struct kvec *iov = req->rq_rcv_buf.head;
4844 int status; 4966 int status;
4845 4967
@@ -5268,6 +5390,53 @@ out_overflow:
5268} 5390}
5269 5391
5270#if defined(CONFIG_NFS_V4_1) 5392#if defined(CONFIG_NFS_V4_1)
5393/*
5394 * TODO: Need to handle case when EOF != true;
5395 */
5396static int decode_getdevicelist(struct xdr_stream *xdr,
5397 struct pnfs_devicelist *res)
5398{
5399 __be32 *p;
5400 int status, i;
5401 struct nfs_writeverf verftemp;
5402
5403 status = decode_op_hdr(xdr, OP_GETDEVICELIST);
5404 if (status)
5405 return status;
5406
5407 p = xdr_inline_decode(xdr, 8 + 8 + 4);
5408 if (unlikely(!p))
5409 goto out_overflow;
5410
5411 /* TODO: Skip cookie for now */
5412 p += 2;
5413
5414 /* Read verifier */
5415 p = xdr_decode_opaque_fixed(p, verftemp.verifier, 8);
5416
5417 res->num_devs = be32_to_cpup(p);
5418
5419 dprintk("%s: num_dev %d\n", __func__, res->num_devs);
5420
5421 if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) {
5422 printk(KERN_ERR "%s too many result dev_num %u\n",
5423 __func__, res->num_devs);
5424 return -EIO;
5425 }
5426
5427 p = xdr_inline_decode(xdr,
5428 res->num_devs * NFS4_DEVICEID4_SIZE + 4);
5429 if (unlikely(!p))
5430 goto out_overflow;
5431 for (i = 0; i < res->num_devs; i++)
5432 p = xdr_decode_opaque_fixed(p, res->dev_id[i].data,
5433 NFS4_DEVICEID4_SIZE);
5434 res->eof = be32_to_cpup(p);
5435 return 0;
5436out_overflow:
5437 print_overflow_msg(__func__, xdr);
5438 return -EIO;
5439}
5271 5440
5272static int decode_getdeviceinfo(struct xdr_stream *xdr, 5441static int decode_getdeviceinfo(struct xdr_stream *xdr,
5273 struct pnfs_device *pdev) 5442 struct pnfs_device *pdev)
@@ -5430,6 +5599,7 @@ static int decode_layoutcommit(struct xdr_stream *xdr,
5430 int status; 5599 int status;
5431 5600
5432 status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT); 5601 status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT);
5602 res->status = status;
5433 if (status) 5603 if (status)
5434 return status; 5604 return status;
5435 5605
@@ -6542,6 +6712,32 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp,
6542} 6712}
6543 6713
6544/* 6714/*
6715 * Decode GETDEVICELIST response
6716 */
6717static int nfs4_xdr_dec_getdevicelist(struct rpc_rqst *rqstp,
6718 struct xdr_stream *xdr,
6719 struct nfs4_getdevicelist_res *res)
6720{
6721 struct compound_hdr hdr;
6722 int status;
6723
6724 dprintk("encoding getdevicelist!\n");
6725
6726 status = decode_compound_hdr(xdr, &hdr);
6727 if (status != 0)
6728 goto out;
6729 status = decode_sequence(xdr, &res->seq_res, rqstp);
6730 if (status != 0)
6731 goto out;
6732 status = decode_putfh(xdr);
6733 if (status != 0)
6734 goto out;
6735 status = decode_getdevicelist(xdr, res->devlist);
6736out:
6737 return status;
6738}
6739
6740/*
6545 * Decode GETDEVINFO response 6741 * Decode GETDEVINFO response
6546 */ 6742 */
6547static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, 6743static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp,
@@ -6722,7 +6918,7 @@ out:
6722int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, 6918int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
6723 int plus) 6919 int plus)
6724{ 6920{
6725 uint32_t bitmap[2] = {0}; 6921 uint32_t bitmap[3] = {0};
6726 uint32_t len; 6922 uint32_t len;
6727 __be32 *p = xdr_inline_decode(xdr, 4); 6923 __be32 *p = xdr_inline_decode(xdr, 4);
6728 if (unlikely(!p)) 6924 if (unlikely(!p))
@@ -6908,6 +7104,7 @@ struct rpc_procinfo nfs4_procedures[] = {
6908 PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), 7104 PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name),
6909 PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), 7105 PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid),
6910 PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), 7106 PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid),
7107 PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist),
6911#endif /* CONFIG_NFS_V4_1 */ 7108#endif /* CONFIG_NFS_V4_1 */
6912}; 7109};
6913 7110