aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2015-12-06 20:55:09 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-12-28 09:57:08 -0500
commit68d264cf02b076a2457aa77c044f5e41b6fa8086 (patch)
treeed59d05a1c064ee8e7459c92077b1cf1375bfd02
parent361cad3c89070aeb37560860ea8bfc092d545adc (diff)
NFS42: handle layoutstats stateid error
When server returns layoutstats stateid error, we should invalidate client's layout so that next IO can trigger new layoutget. Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/nfs42proc.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index 6b1ce9825430..6e8174930a48 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -204,6 +204,8 @@ static void
204nfs42_layoutstat_done(struct rpc_task *task, void *calldata) 204nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
205{ 205{
206 struct nfs42_layoutstat_data *data = calldata; 206 struct nfs42_layoutstat_data *data = calldata;
207 struct inode *inode = data->inode;
208 struct pnfs_layout_hdr *lo;
207 209
208 if (!nfs4_sequence_done(task, &data->res.seq_res)) 210 if (!nfs4_sequence_done(task, &data->res.seq_res))
209 return; 211 return;
@@ -211,12 +213,35 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
211 switch (task->tk_status) { 213 switch (task->tk_status) {
212 case 0: 214 case 0:
213 break; 215 break;
216 case -NFS4ERR_EXPIRED:
217 case -NFS4ERR_STALE_STATEID:
218 case -NFS4ERR_OLD_STATEID:
219 case -NFS4ERR_BAD_STATEID:
220 spin_lock(&inode->i_lock);
221 lo = NFS_I(inode)->layout;
222 if (lo && nfs4_stateid_match(&data->args.stateid,
223 &lo->plh_stateid)) {
224 LIST_HEAD(head);
225
226 /*
227 * Mark the bad layout state as invalid, then retry
228 * with the current stateid.
229 */
230 set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
231 pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
232 spin_unlock(&inode->i_lock);
233 pnfs_free_lseg_list(&head);
234 } else
235 spin_unlock(&inode->i_lock);
236 break;
214 case -ENOTSUPP: 237 case -ENOTSUPP:
215 case -EOPNOTSUPP: 238 case -EOPNOTSUPP:
216 NFS_SERVER(data->inode)->caps &= ~NFS_CAP_LAYOUTSTATS; 239 NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS;
217 default: 240 default:
218 dprintk("%s server returns %d\n", __func__, task->tk_status); 241 break;
219 } 242 }
243
244 dprintk("%s server returns %d\n", __func__, task->tk_status);
220} 245}
221 246
222static void 247static void