aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-11-16 20:30:41 -0500
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:50 -0500
commit193e3aa2ccfb5a53acf7a690b80a1e415b74dbd7 (patch)
treefd805d0a879441054ee99252d0e1767a08b331a3 /fs/nfs
parent6c16605d6ef0dfb2e154119700d58b85c6b4dc71 (diff)
nfs41: introduce NFS_LAYOUT_RETURN_BEFORE_CLOSE
When it is set, generic pnfs would try to send layoutreturn right before last close/delegation_return regard less NFS_LAYOUT_ROC is set or not. LD can then make sure layoutreturn is always sent rather than being omitted. The difference against NFS_LAYOUT_RETURN is that NFS_LAYOUT_RETURN_BEFORE_CLOSE does not block usage of the layout so LD can set it and expect generic layer to try pnfs path at the same time. Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Tom Haynes <loghyr@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--fs/nfs/pnfs.c40
-rw-r--r--fs/nfs/pnfs.h1
3 files changed, 36 insertions, 7 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2397c0f080d3..7e1a97a54f99 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -7797,6 +7797,8 @@ static void nfs4_layoutreturn_release(void *calldata)
7797 if (lrp->res.lrs_present) 7797 if (lrp->res.lrs_present)
7798 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); 7798 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
7799 clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); 7799 clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
7800 clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags);
7801 rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
7800 lo->plh_block_lgets--; 7802 lo->plh_block_lgets--;
7801 spin_unlock(&lo->plh_inode->i_lock); 7803 spin_unlock(&lo->plh_inode->i_lock);
7802 pnfs_put_layout_hdr(lrp->args.layout); 7804 pnfs_put_layout_hdr(lrp->args.layout);
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 0a0e209e8262..d3c2ca71a76d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -909,6 +909,7 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid,
909 status = -ENOMEM; 909 status = -ENOMEM;
910 spin_lock(&ino->i_lock); 910 spin_lock(&ino->i_lock);
911 lo->plh_block_lgets--; 911 lo->plh_block_lgets--;
912 rpc_wake_up(&NFS_SERVER(ino)->roc_rpcwaitq);
912 spin_unlock(&ino->i_lock); 913 spin_unlock(&ino->i_lock);
913 pnfs_put_layout_hdr(lo); 914 pnfs_put_layout_hdr(lo);
914 goto out; 915 goto out;
@@ -926,11 +927,6 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid,
926 927
927 status = nfs4_proc_layoutreturn(lrp, sync); 928 status = nfs4_proc_layoutreturn(lrp, sync);
928out: 929out:
929 if (status) {
930 spin_lock(&ino->i_lock);
931 clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
932 spin_unlock(&ino->i_lock);
933 }
934 dprintk("<-- %s status: %d\n", __func__, status); 930 dprintk("<-- %s status: %d\n", __func__, status);
935 return status; 931 return status;
936} 932}
@@ -1028,8 +1024,9 @@ bool pnfs_roc(struct inode *ino)
1028{ 1024{
1029 struct pnfs_layout_hdr *lo; 1025 struct pnfs_layout_hdr *lo;
1030 struct pnfs_layout_segment *lseg, *tmp; 1026 struct pnfs_layout_segment *lseg, *tmp;
1027 nfs4_stateid stateid;
1031 LIST_HEAD(tmp_list); 1028 LIST_HEAD(tmp_list);
1032 bool found = false; 1029 bool found = false, layoutreturn = false;
1033 1030
1034 spin_lock(&ino->i_lock); 1031 spin_lock(&ino->i_lock);
1035 lo = NFS_I(ino)->layout; 1032 lo = NFS_I(ino)->layout;
@@ -1050,7 +1047,20 @@ bool pnfs_roc(struct inode *ino)
1050 return true; 1047 return true;
1051 1048
1052out_nolayout: 1049out_nolayout:
1050 if (lo) {
1051 stateid = lo->plh_stateid;
1052 layoutreturn =
1053 test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
1054 &lo->plh_flags);
1055 if (layoutreturn) {
1056 lo->plh_block_lgets++;
1057 pnfs_get_layout_hdr(lo);
1058 }
1059 }
1053 spin_unlock(&ino->i_lock); 1060 spin_unlock(&ino->i_lock);
1061 if (layoutreturn)
1062 pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, 0,
1063 NFS4_MAX_UINT64, true);
1054 return false; 1064 return false;
1055} 1065}
1056 1066
@@ -1085,8 +1095,9 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
1085 struct nfs_inode *nfsi = NFS_I(ino); 1095 struct nfs_inode *nfsi = NFS_I(ino);
1086 struct pnfs_layout_hdr *lo; 1096 struct pnfs_layout_hdr *lo;
1087 struct pnfs_layout_segment *lseg; 1097 struct pnfs_layout_segment *lseg;
1098 nfs4_stateid stateid;
1088 u32 current_seqid; 1099 u32 current_seqid;
1089 bool found = false; 1100 bool found = false, layoutreturn = false;
1090 1101
1091 spin_lock(&ino->i_lock); 1102 spin_lock(&ino->i_lock);
1092 list_for_each_entry(lseg, &nfsi->layout->plh_segs, pls_list) 1103 list_for_each_entry(lseg, &nfsi->layout->plh_segs, pls_list)
@@ -1103,7 +1114,22 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
1103 */ 1114 */
1104 *barrier = current_seqid + atomic_read(&lo->plh_outstanding); 1115 *barrier = current_seqid + atomic_read(&lo->plh_outstanding);
1105out: 1116out:
1117 if (!found) {
1118 stateid = lo->plh_stateid;
1119 layoutreturn =
1120 test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
1121 &lo->plh_flags);
1122 if (layoutreturn) {
1123 lo->plh_block_lgets++;
1124 pnfs_get_layout_hdr(lo);
1125 }
1126 }
1106 spin_unlock(&ino->i_lock); 1127 spin_unlock(&ino->i_lock);
1128 if (layoutreturn) {
1129 rpc_sleep_on(&NFS_SERVER(ino)->roc_rpcwaitq, task, NULL);
1130 pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, 0,
1131 NFS4_MAX_UINT64, false);
1132 }
1107 return found; 1133 return found;
1108} 1134}
1109 1135
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index b79f494d59ac..080bf90498d4 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -96,6 +96,7 @@ enum {
96 NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ 96 NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
97 NFS_LAYOUT_ROC, /* some lseg had roc bit set */ 97 NFS_LAYOUT_ROC, /* some lseg had roc bit set */
98 NFS_LAYOUT_RETURN, /* Return this layout ASAP */ 98 NFS_LAYOUT_RETURN, /* Return this layout ASAP */
99 NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
99 NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ 100 NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
100 NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ 101 NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
101}; 102};