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.c132
1 files changed, 123 insertions, 9 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index c3ccd2c46834..d869a5e5464b 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -338,7 +338,11 @@ static int nfs4_stat_to_errno(int);
338 1 /* layoutupdate4 layout type */ + \ 338 1 /* layoutupdate4 layout type */ + \
339 1 /* NULL filelayout layoutupdate4 payload */) 339 1 /* NULL filelayout layoutupdate4 payload */)
340#define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) 340#define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3)
341 341#define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \
342 encode_stateid_maxsz + \
343 1 /* FIXME: opaque lrf_body always empty at the moment */)
344#define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \
345 1 + decode_stateid_maxsz)
342#else /* CONFIG_NFS_V4_1 */ 346#else /* CONFIG_NFS_V4_1 */
343#define encode_sequence_maxsz 0 347#define encode_sequence_maxsz 0
344#define decode_sequence_maxsz 0 348#define decode_sequence_maxsz 0
@@ -760,7 +764,14 @@ static int nfs4_stat_to_errno(int);
760 decode_putfh_maxsz + \ 764 decode_putfh_maxsz + \
761 decode_layoutcommit_maxsz + \ 765 decode_layoutcommit_maxsz + \
762 decode_getattr_maxsz) 766 decode_getattr_maxsz)
763 767#define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \
768 encode_sequence_maxsz + \
769 encode_putfh_maxsz + \
770 encode_layoutreturn_maxsz)
771#define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \
772 decode_sequence_maxsz + \
773 decode_putfh_maxsz + \
774 decode_layoutreturn_maxsz)
764 775
765const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 776const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
766 compound_encode_hdr_maxsz + 777 compound_encode_hdr_maxsz +
@@ -1864,6 +1875,7 @@ encode_layoutget(struct xdr_stream *xdr,
1864 1875
1865static int 1876static int
1866encode_layoutcommit(struct xdr_stream *xdr, 1877encode_layoutcommit(struct xdr_stream *xdr,
1878 struct inode *inode,
1867 const struct nfs4_layoutcommit_args *args, 1879 const struct nfs4_layoutcommit_args *args,
1868 struct compound_hdr *hdr) 1880 struct compound_hdr *hdr)
1869{ 1881{
@@ -1872,7 +1884,7 @@ encode_layoutcommit(struct xdr_stream *xdr,
1872 dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, 1884 dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten,
1873 NFS_SERVER(args->inode)->pnfs_curr_ld->id); 1885 NFS_SERVER(args->inode)->pnfs_curr_ld->id);
1874 1886
1875 p = reserve_space(xdr, 48 + NFS4_STATEID_SIZE); 1887 p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
1876 *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); 1888 *p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
1877 /* Only whole file layouts */ 1889 /* Only whole file layouts */
1878 p = xdr_encode_hyper(p, 0); /* offset */ 1890 p = xdr_encode_hyper(p, 0); /* offset */
@@ -1883,12 +1895,49 @@ encode_layoutcommit(struct xdr_stream *xdr,
1883 p = xdr_encode_hyper(p, args->lastbytewritten); 1895 p = xdr_encode_hyper(p, args->lastbytewritten);
1884 *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ 1896 *p++ = cpu_to_be32(0); /* Never send time_modify_changed */
1885 *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ 1897 *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
1886 *p++ = cpu_to_be32(0); /* no file layout payload */ 1898
1899 if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit)
1900 NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit(
1901 NFS_I(inode)->layout, xdr, args);
1902 else {
1903 p = reserve_space(xdr, 4);
1904 *p = cpu_to_be32(0); /* no layout-type payload */
1905 }
1887 1906
1888 hdr->nops++; 1907 hdr->nops++;
1889 hdr->replen += decode_layoutcommit_maxsz; 1908 hdr->replen += decode_layoutcommit_maxsz;
1890 return 0; 1909 return 0;
1891} 1910}
1911
1912static void
1913encode_layoutreturn(struct xdr_stream *xdr,
1914 const struct nfs4_layoutreturn_args *args,
1915 struct compound_hdr *hdr)
1916{
1917 __be32 *p;
1918
1919 p = reserve_space(xdr, 20);
1920 *p++ = cpu_to_be32(OP_LAYOUTRETURN);
1921 *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */
1922 *p++ = cpu_to_be32(args->layout_type);
1923 *p++ = cpu_to_be32(IOMODE_ANY);
1924 *p = cpu_to_be32(RETURN_FILE);
1925 p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE);
1926 p = xdr_encode_hyper(p, 0);
1927 p = xdr_encode_hyper(p, NFS4_MAX_UINT64);
1928 spin_lock(&args->inode->i_lock);
1929 xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE);
1930 spin_unlock(&args->inode->i_lock);
1931 if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) {
1932 NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn(
1933 NFS_I(args->inode)->layout, xdr, args);
1934 } else {
1935 p = reserve_space(xdr, 4);
1936 *p = cpu_to_be32(0);
1937 }
1938 hdr->nops++;
1939 hdr->replen += decode_layoutreturn_maxsz;
1940}
1892#endif /* CONFIG_NFS_V4_1 */ 1941#endif /* CONFIG_NFS_V4_1 */
1893 1942
1894/* 1943/*
@@ -2706,10 +2755,12 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
2706/* 2755/*
2707 * Encode LAYOUTCOMMIT request 2756 * Encode LAYOUTCOMMIT request
2708 */ 2757 */
2709static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, 2758static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
2710 struct xdr_stream *xdr, 2759 struct xdr_stream *xdr,
2711 struct nfs4_layoutcommit_args *args) 2760 struct nfs4_layoutcommit_args *args)
2712{ 2761{
2762 struct nfs4_layoutcommit_data *data =
2763 container_of(args, struct nfs4_layoutcommit_data, args);
2713 struct compound_hdr hdr = { 2764 struct compound_hdr hdr = {
2714 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 2765 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2715 }; 2766 };
@@ -2717,10 +2768,27 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
2717 encode_compound_hdr(xdr, req, &hdr); 2768 encode_compound_hdr(xdr, req, &hdr);
2718 encode_sequence(xdr, &args->seq_args, &hdr); 2769 encode_sequence(xdr, &args->seq_args, &hdr);
2719 encode_putfh(xdr, NFS_FH(args->inode), &hdr); 2770 encode_putfh(xdr, NFS_FH(args->inode), &hdr);
2720 encode_layoutcommit(xdr, args, &hdr); 2771 encode_layoutcommit(xdr, data->args.inode, args, &hdr);
2721 encode_getfattr(xdr, args->bitmask, &hdr); 2772 encode_getfattr(xdr, args->bitmask, &hdr);
2722 encode_nops(&hdr); 2773 encode_nops(&hdr);
2723 return 0; 2774}
2775
2776/*
2777 * Encode LAYOUTRETURN request
2778 */
2779static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req,
2780 struct xdr_stream *xdr,
2781 struct nfs4_layoutreturn_args *args)
2782{
2783 struct compound_hdr hdr = {
2784 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2785 };
2786
2787 encode_compound_hdr(xdr, req, &hdr);
2788 encode_sequence(xdr, &args->seq_args, &hdr);
2789 encode_putfh(xdr, NFS_FH(args->inode), &hdr);
2790 encode_layoutreturn(xdr, args, &hdr);
2791 encode_nops(&hdr);
2724} 2792}
2725#endif /* CONFIG_NFS_V4_1 */ 2793#endif /* CONFIG_NFS_V4_1 */
2726 2794
@@ -5203,6 +5271,27 @@ out_overflow:
5203 return -EIO; 5271 return -EIO;
5204} 5272}
5205 5273
5274static int decode_layoutreturn(struct xdr_stream *xdr,
5275 struct nfs4_layoutreturn_res *res)
5276{
5277 __be32 *p;
5278 int status;
5279
5280 status = decode_op_hdr(xdr, OP_LAYOUTRETURN);
5281 if (status)
5282 return status;
5283 p = xdr_inline_decode(xdr, 4);
5284 if (unlikely(!p))
5285 goto out_overflow;
5286 res->lrs_present = be32_to_cpup(p);
5287 if (res->lrs_present)
5288 status = decode_stateid(xdr, &res->stateid);
5289 return status;
5290out_overflow:
5291 print_overflow_msg(__func__, xdr);
5292 return -EIO;
5293}
5294
5206static int decode_layoutcommit(struct xdr_stream *xdr, 5295static int decode_layoutcommit(struct xdr_stream *xdr,
5207 struct rpc_rqst *req, 5296 struct rpc_rqst *req,
5208 struct nfs4_layoutcommit_res *res) 5297 struct nfs4_layoutcommit_res *res)
@@ -6320,6 +6409,30 @@ out:
6320} 6409}
6321 6410
6322/* 6411/*
6412 * Decode LAYOUTRETURN response
6413 */
6414static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp,
6415 struct xdr_stream *xdr,
6416 struct nfs4_layoutreturn_res *res)
6417{
6418 struct compound_hdr hdr;
6419 int status;
6420
6421 status = decode_compound_hdr(xdr, &hdr);
6422 if (status)
6423 goto out;
6424 status = decode_sequence(xdr, &res->seq_res, rqstp);
6425 if (status)
6426 goto out;
6427 status = decode_putfh(xdr);
6428 if (status)
6429 goto out;
6430 status = decode_layoutreturn(xdr, res);
6431out:
6432 return status;
6433}
6434
6435/*
6323 * Decode LAYOUTCOMMIT response 6436 * Decode LAYOUTCOMMIT response
6324 */ 6437 */
6325static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, 6438static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
@@ -6547,6 +6660,7 @@ struct rpc_procinfo nfs4_procedures[] = {
6547 PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), 6660 PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
6548 PROC(LAYOUTGET, enc_layoutget, dec_layoutget), 6661 PROC(LAYOUTGET, enc_layoutget, dec_layoutget),
6549 PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), 6662 PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit),
6663 PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn),
6550#endif /* CONFIG_NFS_V4_1 */ 6664#endif /* CONFIG_NFS_V4_1 */
6551}; 6665};
6552 6666