diff options
author | Peng Tao <tao.peng@primarydata.com> | 2014-11-16 20:30:41 -0500 |
---|---|---|
committer | Tom Haynes <loghyr@primarydata.com> | 2015-02-03 14:06:50 -0500 |
commit | 193e3aa2ccfb5a53acf7a690b80a1e415b74dbd7 (patch) | |
tree | fd805d0a879441054ee99252d0e1767a08b331a3 /fs/nfs | |
parent | 6c16605d6ef0dfb2e154119700d58b85c6b4dc71 (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.c | 2 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 40 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 1 |
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); |
928 | out: | 929 | out: |
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 | ||
1052 | out_nolayout: | 1049 | out_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); |
1105 | out: | 1116 | out: |
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 | }; |