aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 07cdf925c524..207d399c8dee 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -324,6 +324,18 @@ static int nfs4_stat_to_errno(int);
324#define decode_layoutget_maxsz (op_decode_hdr_maxsz + 8 + \ 324#define decode_layoutget_maxsz (op_decode_hdr_maxsz + 8 + \
325 decode_stateid_maxsz + \ 325 decode_stateid_maxsz + \
326 XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE)) 326 XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE))
327#define encode_layoutcommit_maxsz (op_encode_hdr_maxsz + \
328 2 /* offset */ + \
329 2 /* length */ + \
330 1 /* reclaim */ + \
331 encode_stateid_maxsz + \
332 1 /* new offset (true) */ + \
333 2 /* last byte written */ + \
334 1 /* nt_timechanged (false) */ + \
335 1 /* layoutupdate4 layout type */ + \
336 1 /* NULL filelayout layoutupdate4 payload */)
337#define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3)
338
327#else /* CONFIG_NFS_V4_1 */ 339#else /* CONFIG_NFS_V4_1 */
328#define encode_sequence_maxsz 0 340#define encode_sequence_maxsz 0
329#define decode_sequence_maxsz 0 341#define decode_sequence_maxsz 0
@@ -727,6 +739,17 @@ static int nfs4_stat_to_errno(int);
727 decode_sequence_maxsz + \ 739 decode_sequence_maxsz + \
728 decode_putfh_maxsz + \ 740 decode_putfh_maxsz + \
729 decode_layoutget_maxsz) 741 decode_layoutget_maxsz)
742#define NFS4_enc_layoutcommit_sz (compound_encode_hdr_maxsz + \
743 encode_sequence_maxsz +\
744 encode_putfh_maxsz + \
745 encode_layoutcommit_maxsz + \
746 encode_getattr_maxsz)
747#define NFS4_dec_layoutcommit_sz (compound_decode_hdr_maxsz + \
748 decode_sequence_maxsz + \
749 decode_putfh_maxsz + \
750 decode_layoutcommit_maxsz + \
751 decode_getattr_maxsz)
752
730 753
731const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 754const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
732 compound_encode_hdr_maxsz + 755 compound_encode_hdr_maxsz +
@@ -1816,6 +1839,34 @@ encode_layoutget(struct xdr_stream *xdr,
1816 hdr->nops++; 1839 hdr->nops++;
1817 hdr->replen += decode_layoutget_maxsz; 1840 hdr->replen += decode_layoutget_maxsz;
1818} 1841}
1842
1843static int
1844encode_layoutcommit(struct xdr_stream *xdr,
1845 const struct nfs4_layoutcommit_args *args,
1846 struct compound_hdr *hdr)
1847{
1848 __be32 *p;
1849
1850 dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten,
1851 NFS_SERVER(args->inode)->pnfs_curr_ld->id);
1852
1853 p = reserve_space(xdr, 48 + NFS4_STATEID_SIZE);
1854 *p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
1855 /* Only whole file layouts */
1856 p = xdr_encode_hyper(p, 0); /* offset */
1857 p = xdr_encode_hyper(p, NFS4_MAX_UINT64); /* length */
1858 *p++ = cpu_to_be32(0); /* reclaim */
1859 p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE);
1860 *p++ = cpu_to_be32(1); /* newoffset = TRUE */
1861 p = xdr_encode_hyper(p, args->lastbytewritten);
1862 *p++ = cpu_to_be32(0); /* Never send time_modify_changed */
1863 *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
1864 *p++ = cpu_to_be32(0); /* no file layout payload */
1865
1866 hdr->nops++;
1867 hdr->replen += decode_layoutcommit_maxsz;
1868 return 0;
1869}
1819#endif /* CONFIG_NFS_V4_1 */ 1870#endif /* CONFIG_NFS_V4_1 */
1820 1871
1821/* 1872/*
@@ -2607,6 +2658,26 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
2607 encode_layoutget(xdr, args, &hdr); 2658 encode_layoutget(xdr, args, &hdr);
2608 encode_nops(&hdr); 2659 encode_nops(&hdr);
2609} 2660}
2661
2662/*
2663 * Encode LAYOUTCOMMIT request
2664 */
2665static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
2666 struct xdr_stream *xdr,
2667 struct nfs4_layoutcommit_args *args)
2668{
2669 struct compound_hdr hdr = {
2670 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2671 };
2672
2673 encode_compound_hdr(xdr, req, &hdr);
2674 encode_sequence(xdr, &args->seq_args, &hdr);
2675 encode_putfh(xdr, NFS_FH(args->inode), &hdr);
2676 encode_layoutcommit(xdr, args, &hdr);
2677 encode_getfattr(xdr, args->bitmask, &hdr);
2678 encode_nops(&hdr);
2679 return 0;
2680}
2610#endif /* CONFIG_NFS_V4_1 */ 2681#endif /* CONFIG_NFS_V4_1 */
2611 2682
2612static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 2683static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
@@ -5007,6 +5078,35 @@ out_overflow:
5007 print_overflow_msg(__func__, xdr); 5078 print_overflow_msg(__func__, xdr);
5008 return -EIO; 5079 return -EIO;
5009} 5080}
5081
5082static int decode_layoutcommit(struct xdr_stream *xdr,
5083 struct rpc_rqst *req,
5084 struct nfs4_layoutcommit_res *res)
5085{
5086 __be32 *p;
5087 __u32 sizechanged;
5088 int status;
5089
5090 status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT);
5091 if (status)
5092 return status;
5093
5094 p = xdr_inline_decode(xdr, 4);
5095 if (unlikely(!p))
5096 goto out_overflow;
5097 sizechanged = be32_to_cpup(p);
5098
5099 if (sizechanged) {
5100 /* throw away new size */
5101 p = xdr_inline_decode(xdr, 8);
5102 if (unlikely(!p))
5103 goto out_overflow;
5104 }
5105 return 0;
5106out_overflow:
5107 print_overflow_msg(__func__, xdr);
5108 return -EIO;
5109}
5010#endif /* CONFIG_NFS_V4_1 */ 5110#endif /* CONFIG_NFS_V4_1 */
5011 5111
5012/* 5112/*
@@ -6068,6 +6168,34 @@ static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp,
6068out: 6168out:
6069 return status; 6169 return status;
6070} 6170}
6171
6172/*
6173 * Decode LAYOUTCOMMIT response
6174 */
6175static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
6176 struct xdr_stream *xdr,
6177 struct nfs4_layoutcommit_res *res)
6178{
6179 struct compound_hdr hdr;
6180 int status;
6181
6182 status = decode_compound_hdr(xdr, &hdr);
6183 if (status)
6184 goto out;
6185 status = decode_sequence(xdr, &res->seq_res, rqstp);
6186 if (status)
6187 goto out;
6188 status = decode_putfh(xdr);
6189 if (status)
6190 goto out;
6191 status = decode_layoutcommit(xdr, rqstp, res);
6192 if (status)
6193 goto out;
6194 decode_getfattr(xdr, res->fattr, res->server,
6195 !RPC_IS_ASYNC(rqstp->rq_task));
6196out:
6197 return status;
6198}
6071#endif /* CONFIG_NFS_V4_1 */ 6199#endif /* CONFIG_NFS_V4_1 */
6072 6200
6073/** 6201/**
@@ -6269,6 +6397,7 @@ struct rpc_procinfo nfs4_procedures[] = {
6269 PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete), 6397 PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete),
6270 PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), 6398 PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
6271 PROC(LAYOUTGET, enc_layoutget, dec_layoutget), 6399 PROC(LAYOUTGET, enc_layoutget, dec_layoutget),
6400 PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit),
6272#endif /* CONFIG_NFS_V4_1 */ 6401#endif /* CONFIG_NFS_V4_1 */
6273}; 6402};
6274 6403