diff options
| -rw-r--r-- | fs/nfs/inode.c | 3 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 82 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 111 | ||||
| -rw-r--r-- | fs/nfs/pnfs.c | 45 | ||||
| -rw-r--r-- | fs/nfs/pnfs.h | 18 | ||||
| -rw-r--r-- | include/linux/nfs4.h | 1 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 21 |
7 files changed, 274 insertions, 7 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 57bb31ad7a5e..e9c6d9f8f7e8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -1424,9 +1424,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
| 1424 | */ | 1424 | */ |
| 1425 | void nfs4_evict_inode(struct inode *inode) | 1425 | void nfs4_evict_inode(struct inode *inode) |
| 1426 | { | 1426 | { |
| 1427 | pnfs_destroy_layout(NFS_I(inode)); | ||
| 1428 | truncate_inode_pages(&inode->i_data, 0); | 1427 | truncate_inode_pages(&inode->i_data, 0); |
| 1429 | end_writeback(inode); | 1428 | end_writeback(inode); |
| 1429 | pnfs_return_layout(inode); | ||
| 1430 | pnfs_destroy_layout(NFS_I(inode)); | ||
| 1430 | /* If we are holding a delegation, return it! */ | 1431 | /* If we are holding a delegation, return it! */ |
| 1431 | nfs_inode_return_delegation_noreclaim(inode); | 1432 | nfs_inode_return_delegation_noreclaim(inode); |
| 1432 | /* First call standard NFS clear_inode() code */ | 1433 | /* First call standard NFS clear_inode() code */ |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92c8bc4b5f97..5b4124e4c22f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -5673,6 +5673,88 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
| 5673 | return status; | 5673 | return status; |
| 5674 | } | 5674 | } |
| 5675 | 5675 | ||
| 5676 | static void | ||
| 5677 | nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata) | ||
| 5678 | { | ||
| 5679 | struct nfs4_layoutreturn *lrp = calldata; | ||
| 5680 | |||
| 5681 | dprintk("--> %s\n", __func__); | ||
| 5682 | if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args, | ||
| 5683 | &lrp->res.seq_res, 0, task)) | ||
| 5684 | return; | ||
| 5685 | rpc_call_start(task); | ||
| 5686 | } | ||
| 5687 | |||
| 5688 | static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | ||
| 5689 | { | ||
| 5690 | struct nfs4_layoutreturn *lrp = calldata; | ||
| 5691 | struct nfs_server *server; | ||
| 5692 | |||
| 5693 | dprintk("--> %s\n", __func__); | ||
| 5694 | |||
| 5695 | if (!nfs4_sequence_done(task, &lrp->res.seq_res)) | ||
| 5696 | return; | ||
| 5697 | |||
| 5698 | server = NFS_SERVER(lrp->args.inode); | ||
| 5699 | if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { | ||
| 5700 | nfs_restart_rpc(task, lrp->clp); | ||
| 5701 | return; | ||
| 5702 | } | ||
| 5703 | if (task->tk_status == 0) { | ||
| 5704 | struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; | ||
| 5705 | |||
| 5706 | if (lrp->res.lrs_present) { | ||
| 5707 | spin_lock(&lo->plh_inode->i_lock); | ||
| 5708 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | ||
| 5709 | spin_unlock(&lo->plh_inode->i_lock); | ||
| 5710 | } else | ||
| 5711 | BUG_ON(!list_empty(&lo->plh_segs)); | ||
| 5712 | } | ||
| 5713 | dprintk("<-- %s\n", __func__); | ||
| 5714 | } | ||
| 5715 | |||
| 5716 | static void nfs4_layoutreturn_release(void *calldata) | ||
| 5717 | { | ||
| 5718 | struct nfs4_layoutreturn *lrp = calldata; | ||
| 5719 | |||
| 5720 | dprintk("--> %s\n", __func__); | ||
| 5721 | put_layout_hdr(NFS_I(lrp->args.inode)->layout); | ||
| 5722 | kfree(calldata); | ||
| 5723 | dprintk("<-- %s\n", __func__); | ||
| 5724 | } | ||
| 5725 | |||
| 5726 | static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { | ||
| 5727 | .rpc_call_prepare = nfs4_layoutreturn_prepare, | ||
| 5728 | .rpc_call_done = nfs4_layoutreturn_done, | ||
| 5729 | .rpc_release = nfs4_layoutreturn_release, | ||
| 5730 | }; | ||
| 5731 | |||
| 5732 | int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) | ||
| 5733 | { | ||
| 5734 | struct rpc_task *task; | ||
| 5735 | struct rpc_message msg = { | ||
| 5736 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN], | ||
| 5737 | .rpc_argp = &lrp->args, | ||
| 5738 | .rpc_resp = &lrp->res, | ||
| 5739 | }; | ||
| 5740 | struct rpc_task_setup task_setup_data = { | ||
| 5741 | .rpc_client = lrp->clp->cl_rpcclient, | ||
| 5742 | .rpc_message = &msg, | ||
| 5743 | .callback_ops = &nfs4_layoutreturn_call_ops, | ||
| 5744 | .callback_data = lrp, | ||
| 5745 | }; | ||
| 5746 | int status; | ||
| 5747 | |||
| 5748 | dprintk("--> %s\n", __func__); | ||
| 5749 | task = rpc_run_task(&task_setup_data); | ||
| 5750 | if (IS_ERR(task)) | ||
| 5751 | return PTR_ERR(task); | ||
| 5752 | status = task->tk_status; | ||
| 5753 | dprintk("<-- %s status=%d\n", __func__, status); | ||
| 5754 | rpc_put_task(task); | ||
| 5755 | return status; | ||
| 5756 | } | ||
| 5757 | |||
| 5676 | static int | 5758 | static int |
| 5677 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) | 5759 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) |
| 5678 | { | 5760 | { |
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 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 171662114fdd..00b128241746 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
| @@ -619,6 +619,51 @@ out_err_free: | |||
| 619 | return NULL; | 619 | return NULL; |
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | /* Initiates a LAYOUTRETURN(FILE) */ | ||
| 623 | int | ||
| 624 | _pnfs_return_layout(struct inode *ino) | ||
| 625 | { | ||
| 626 | struct pnfs_layout_hdr *lo = NULL; | ||
| 627 | struct nfs_inode *nfsi = NFS_I(ino); | ||
| 628 | LIST_HEAD(tmp_list); | ||
| 629 | struct nfs4_layoutreturn *lrp; | ||
| 630 | nfs4_stateid stateid; | ||
| 631 | int status = 0; | ||
| 632 | |||
| 633 | dprintk("--> %s\n", __func__); | ||
| 634 | |||
| 635 | spin_lock(&ino->i_lock); | ||
| 636 | lo = nfsi->layout; | ||
| 637 | if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) { | ||
| 638 | spin_unlock(&ino->i_lock); | ||
| 639 | dprintk("%s: no layout segments to return\n", __func__); | ||
| 640 | goto out; | ||
| 641 | } | ||
| 642 | stateid = nfsi->layout->plh_stateid; | ||
| 643 | /* Reference matched in nfs4_layoutreturn_release */ | ||
| 644 | get_layout_hdr(lo); | ||
| 645 | spin_unlock(&ino->i_lock); | ||
| 646 | pnfs_free_lseg_list(&tmp_list); | ||
| 647 | |||
| 648 | WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)); | ||
| 649 | |||
| 650 | lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); | ||
| 651 | if (unlikely(lrp == NULL)) { | ||
| 652 | status = -ENOMEM; | ||
| 653 | goto out; | ||
| 654 | } | ||
| 655 | |||
| 656 | lrp->args.stateid = stateid; | ||
| 657 | lrp->args.layout_type = NFS_SERVER(ino)->pnfs_curr_ld->id; | ||
| 658 | lrp->args.inode = ino; | ||
| 659 | lrp->clp = NFS_SERVER(ino)->nfs_client; | ||
| 660 | |||
| 661 | status = nfs4_proc_layoutreturn(lrp); | ||
| 662 | out: | ||
| 663 | dprintk("<-- %s status: %d\n", __func__, status); | ||
| 664 | return status; | ||
| 665 | } | ||
| 666 | |||
| 622 | bool pnfs_roc(struct inode *ino) | 667 | bool pnfs_roc(struct inode *ino) |
| 623 | { | 668 | { |
| 624 | struct pnfs_layout_hdr *lo; | 669 | struct pnfs_layout_hdr *lo; |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 0383e66e71f0..c34f7a0e3bc2 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
| @@ -129,6 +129,7 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); | |||
| 129 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, | 129 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, |
| 130 | struct pnfs_device *dev); | 130 | struct pnfs_device *dev); |
| 131 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | 131 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); |
| 132 | extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); | ||
| 132 | 133 | ||
| 133 | /* pnfs.c */ | 134 | /* pnfs.c */ |
| 134 | void get_layout_hdr(struct pnfs_layout_hdr *lo); | 135 | void get_layout_hdr(struct pnfs_layout_hdr *lo); |
| @@ -165,6 +166,7 @@ void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); | |||
| 165 | bool pnfs_roc_drain(struct inode *ino, u32 *barrier); | 166 | bool pnfs_roc_drain(struct inode *ino, u32 *barrier); |
| 166 | void pnfs_set_layoutcommit(struct nfs_write_data *wdata); | 167 | void pnfs_set_layoutcommit(struct nfs_write_data *wdata); |
| 167 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); | 168 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); |
| 169 | int _pnfs_return_layout(struct inode *); | ||
| 168 | int pnfs_ld_write_done(struct nfs_write_data *); | 170 | int pnfs_ld_write_done(struct nfs_write_data *); |
| 169 | int pnfs_ld_read_done(struct nfs_read_data *); | 171 | int pnfs_ld_read_done(struct nfs_read_data *); |
| 170 | 172 | ||
| @@ -256,6 +258,17 @@ static inline void pnfs_clear_request_commit(struct nfs_page *req) | |||
| 256 | put_lseg(req->wb_commit_lseg); | 258 | put_lseg(req->wb_commit_lseg); |
| 257 | } | 259 | } |
| 258 | 260 | ||
| 261 | static inline int pnfs_return_layout(struct inode *ino) | ||
| 262 | { | ||
| 263 | struct nfs_inode *nfsi = NFS_I(ino); | ||
| 264 | struct nfs_server *nfss = NFS_SERVER(ino); | ||
| 265 | |||
| 266 | if (pnfs_enabled_sb(nfss) && nfsi->layout) | ||
| 267 | return _pnfs_return_layout(ino); | ||
| 268 | |||
| 269 | return 0; | ||
| 270 | } | ||
| 271 | |||
| 259 | #else /* CONFIG_NFS_V4_1 */ | 272 | #else /* CONFIG_NFS_V4_1 */ |
| 260 | 273 | ||
| 261 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) | 274 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) |
| @@ -298,6 +311,11 @@ pnfs_try_to_write_data(struct nfs_write_data *data, | |||
| 298 | return PNFS_NOT_ATTEMPTED; | 311 | return PNFS_NOT_ATTEMPTED; |
| 299 | } | 312 | } |
| 300 | 313 | ||
| 314 | static inline int pnfs_return_layout(struct inode *ino) | ||
| 315 | { | ||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 301 | static inline bool | 319 | static inline bool |
| 302 | pnfs_roc(struct inode *ino) | 320 | pnfs_roc(struct inode *ino) |
| 303 | { | 321 | { |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 178fafe0ff93..9376eaf26e15 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
| @@ -562,6 +562,7 @@ enum { | |||
| 562 | NFSPROC4_CLNT_LAYOUTGET, | 562 | NFSPROC4_CLNT_LAYOUTGET, |
| 563 | NFSPROC4_CLNT_GETDEVICEINFO, | 563 | NFSPROC4_CLNT_GETDEVICEINFO, |
| 564 | NFSPROC4_CLNT_LAYOUTCOMMIT, | 564 | NFSPROC4_CLNT_LAYOUTCOMMIT, |
| 565 | NFSPROC4_CLNT_LAYOUTRETURN, | ||
| 565 | }; | 566 | }; |
| 566 | 567 | ||
| 567 | /* nfs41 types */ | 568 | /* nfs41 types */ |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7c8ff0984a84..5e8444a11adf 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -269,6 +269,27 @@ struct nfs4_layoutcommit_data { | |||
| 269 | struct nfs4_layoutcommit_res res; | 269 | struct nfs4_layoutcommit_res res; |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | struct nfs4_layoutreturn_args { | ||
| 273 | __u32 layout_type; | ||
| 274 | struct inode *inode; | ||
| 275 | nfs4_stateid stateid; | ||
| 276 | struct nfs4_sequence_args seq_args; | ||
| 277 | }; | ||
| 278 | |||
| 279 | struct nfs4_layoutreturn_res { | ||
| 280 | struct nfs4_sequence_res seq_res; | ||
| 281 | u32 lrs_present; | ||
| 282 | nfs4_stateid stateid; | ||
| 283 | }; | ||
| 284 | |||
| 285 | struct nfs4_layoutreturn { | ||
| 286 | struct nfs4_layoutreturn_args args; | ||
| 287 | struct nfs4_layoutreturn_res res; | ||
| 288 | struct rpc_cred *cred; | ||
| 289 | struct nfs_client *clp; | ||
| 290 | int rpc_status; | ||
| 291 | }; | ||
| 292 | |||
| 272 | /* | 293 | /* |
| 273 | * Arguments to the open call. | 294 | * Arguments to the open call. |
| 274 | */ | 295 | */ |
