diff options
author | Benny Halevy <bhalevy@panasas.com> | 2011-05-22 12:52:37 -0400 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2011-05-29 13:54:36 -0400 |
commit | cbe8260369c9f88eafa035cd327dc3e02fad528c (patch) | |
tree | 13316d9b1a761cf58c35e663375b72f6ac07c5d2 /fs/nfs/nfs4xdr.c | |
parent | 04f83450388e87d86b387cf4a27b81eb7e69de7d (diff) |
pnfs: layoutreturn
NFSv4.1 LAYOUTRETURN implementation
Currently, does not support layout-type payload encoding.
Signed-off-by: Alexandros Batsakis <batsakis@netapp.com>
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: Fred Isaman <iisaman@netapp.com>
Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: Zhang Jingwang <zhangjingwang@nrchpc.ac.cn>
[call pnfs_return_layout right before pnfs_destroy_layout]
[remove assert_spin_locked from pnfs_clear_lseg_list]
[remove wait parameter from the layoutreturn path.]
[remove return_type field from nfs4_layoutreturn_args]
[remove range from nfs4_layoutreturn_args]
[no need to send layoutcommit from _pnfs_return_layout]
[don't wait on sync layoutreturn]
[fix layout stateid in layoutreturn args]
[fixed NULL deref in _pnfs_return_layout]
[removed recaim member of nfs4_layoutreturn_args]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 111 |
1 files changed, 105 insertions, 6 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c3ccd2c46834..f24212064356 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 | ||
765 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + | 776 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + |
766 | compound_encode_hdr_maxsz + | 777 | compound_encode_hdr_maxsz + |
@@ -1889,6 +1900,31 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
1889 | hdr->replen += decode_layoutcommit_maxsz; | 1900 | hdr->replen += decode_layoutcommit_maxsz; |
1890 | return 0; | 1901 | return 0; |
1891 | } | 1902 | } |
1903 | |||
1904 | static void | ||
1905 | encode_layoutreturn(struct xdr_stream *xdr, | ||
1906 | const struct nfs4_layoutreturn_args *args, | ||
1907 | struct compound_hdr *hdr) | ||
1908 | { | ||
1909 | __be32 *p; | ||
1910 | |||
1911 | p = reserve_space(xdr, 20); | ||
1912 | *p++ = cpu_to_be32(OP_LAYOUTRETURN); | ||
1913 | *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */ | ||
1914 | *p++ = cpu_to_be32(args->layout_type); | ||
1915 | *p++ = cpu_to_be32(IOMODE_ANY); | ||
1916 | *p = cpu_to_be32(RETURN_FILE); | ||
1917 | p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE); | ||
1918 | p = xdr_encode_hyper(p, 0); | ||
1919 | p = xdr_encode_hyper(p, NFS4_MAX_UINT64); | ||
1920 | spin_lock(&args->inode->i_lock); | ||
1921 | xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE); | ||
1922 | spin_unlock(&args->inode->i_lock); | ||
1923 | p = reserve_space(xdr, 4); | ||
1924 | *p = cpu_to_be32(0); | ||
1925 | hdr->nops++; | ||
1926 | hdr->replen += decode_layoutreturn_maxsz; | ||
1927 | } | ||
1892 | #endif /* CONFIG_NFS_V4_1 */ | 1928 | #endif /* CONFIG_NFS_V4_1 */ |
1893 | 1929 | ||
1894 | /* | 1930 | /* |
@@ -2706,9 +2742,9 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, | |||
2706 | /* | 2742 | /* |
2707 | * Encode LAYOUTCOMMIT request | 2743 | * Encode LAYOUTCOMMIT request |
2708 | */ | 2744 | */ |
2709 | static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, | 2745 | static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, |
2710 | struct xdr_stream *xdr, | 2746 | struct xdr_stream *xdr, |
2711 | struct nfs4_layoutcommit_args *args) | 2747 | struct nfs4_layoutcommit_args *args) |
2712 | { | 2748 | { |
2713 | struct compound_hdr hdr = { | 2749 | struct compound_hdr hdr = { |
2714 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | 2750 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), |
@@ -2720,7 +2756,24 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, | |||
2720 | encode_layoutcommit(xdr, args, &hdr); | 2756 | encode_layoutcommit(xdr, args, &hdr); |
2721 | encode_getfattr(xdr, args->bitmask, &hdr); | 2757 | encode_getfattr(xdr, args->bitmask, &hdr); |
2722 | encode_nops(&hdr); | 2758 | encode_nops(&hdr); |
2723 | return 0; | 2759 | } |
2760 | |||
2761 | /* | ||
2762 | * Encode LAYOUTRETURN request | ||
2763 | */ | ||
2764 | static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, | ||
2765 | struct xdr_stream *xdr, | ||
2766 | struct nfs4_layoutreturn_args *args) | ||
2767 | { | ||
2768 | struct compound_hdr hdr = { | ||
2769 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2770 | }; | ||
2771 | |||
2772 | encode_compound_hdr(xdr, req, &hdr); | ||
2773 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2774 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); | ||
2775 | encode_layoutreturn(xdr, args, &hdr); | ||
2776 | encode_nops(&hdr); | ||
2724 | } | 2777 | } |
2725 | #endif /* CONFIG_NFS_V4_1 */ | 2778 | #endif /* CONFIG_NFS_V4_1 */ |
2726 | 2779 | ||
@@ -5203,6 +5256,27 @@ out_overflow: | |||
5203 | return -EIO; | 5256 | return -EIO; |
5204 | } | 5257 | } |
5205 | 5258 | ||
5259 | static int decode_layoutreturn(struct xdr_stream *xdr, | ||
5260 | struct nfs4_layoutreturn_res *res) | ||
5261 | { | ||
5262 | __be32 *p; | ||
5263 | int status; | ||
5264 | |||
5265 | status = decode_op_hdr(xdr, OP_LAYOUTRETURN); | ||
5266 | if (status) | ||
5267 | return status; | ||
5268 | p = xdr_inline_decode(xdr, 4); | ||
5269 | if (unlikely(!p)) | ||
5270 | goto out_overflow; | ||
5271 | res->lrs_present = be32_to_cpup(p); | ||
5272 | if (res->lrs_present) | ||
5273 | status = decode_stateid(xdr, &res->stateid); | ||
5274 | return status; | ||
5275 | out_overflow: | ||
5276 | print_overflow_msg(__func__, xdr); | ||
5277 | return -EIO; | ||
5278 | } | ||
5279 | |||
5206 | static int decode_layoutcommit(struct xdr_stream *xdr, | 5280 | static int decode_layoutcommit(struct xdr_stream *xdr, |
5207 | struct rpc_rqst *req, | 5281 | struct rpc_rqst *req, |
5208 | struct nfs4_layoutcommit_res *res) | 5282 | struct nfs4_layoutcommit_res *res) |
@@ -6320,6 +6394,30 @@ out: | |||
6320 | } | 6394 | } |
6321 | 6395 | ||
6322 | /* | 6396 | /* |
6397 | * Decode LAYOUTRETURN response | ||
6398 | */ | ||
6399 | static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp, | ||
6400 | struct xdr_stream *xdr, | ||
6401 | struct nfs4_layoutreturn_res *res) | ||
6402 | { | ||
6403 | struct compound_hdr hdr; | ||
6404 | int status; | ||
6405 | |||
6406 | status = decode_compound_hdr(xdr, &hdr); | ||
6407 | if (status) | ||
6408 | goto out; | ||
6409 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6410 | if (status) | ||
6411 | goto out; | ||
6412 | status = decode_putfh(xdr); | ||
6413 | if (status) | ||
6414 | goto out; | ||
6415 | status = decode_layoutreturn(xdr, res); | ||
6416 | out: | ||
6417 | return status; | ||
6418 | } | ||
6419 | |||
6420 | /* | ||
6323 | * Decode LAYOUTCOMMIT response | 6421 | * Decode LAYOUTCOMMIT response |
6324 | */ | 6422 | */ |
6325 | static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, | 6423 | static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, |
@@ -6547,6 +6645,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6547 | PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), | 6645 | PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), |
6548 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), | 6646 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), |
6549 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), | 6647 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), |
6648 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), | ||
6550 | #endif /* CONFIG_NFS_V4_1 */ | 6649 | #endif /* CONFIG_NFS_V4_1 */ |
6551 | }; | 6650 | }; |
6552 | 6651 | ||