aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-09-24 13:07:16 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-09-28 16:03:10 -0400
commit3e6212149304eaf9289d5bc56e003068660f3476 (patch)
treee1b9f72afd21b68e3a8c76a6b341183fe2001a5a /fs
parent830ffb565760234eb984e4343ad82575e96728de (diff)
NFSv4.1: Don't drop the pnfs_layout_hdr after a layoutget failure
We want to cache the pnfs_layout_hdr after a layoutget or i/o failure so that pnfs_update_layout() can find it and know when it is time to retry. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/pnfs.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index d7a8f03e729..6834fa1be57 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -247,10 +247,28 @@ pnfs_iomode_to_fail_bit(u32 iomode)
247} 247}
248 248
249static void 249static void
250pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode) 250pnfs_layout_set_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
251{ 251{
252 lo->plh_retry_timestamp = jiffies; 252 lo->plh_retry_timestamp = jiffies;
253 set_bit(pnfs_iomode_to_fail_bit(iomode), &lo->plh_flags); 253 if (test_and_set_bit(fail_bit, &lo->plh_flags))
254 atomic_inc(&lo->plh_refcount);
255}
256
257static void
258pnfs_layout_clear_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
259{
260 if (test_and_clear_bit(fail_bit, &lo->plh_flags))
261 atomic_dec(&lo->plh_refcount);
262}
263
264static void
265pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
266{
267 struct inode *inode = lo->plh_inode;
268
269 spin_lock(&inode->i_lock);
270 pnfs_layout_set_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
271 spin_unlock(&inode->i_lock);
254 dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__, 272 dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__,
255 iomode == IOMODE_RW ? "RW" : "READ"); 273 iomode == IOMODE_RW ? "RW" : "READ");
256} 274}
@@ -259,14 +277,15 @@ static bool
259pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode) 277pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode)
260{ 278{
261 unsigned long start, end; 279 unsigned long start, end;
262 if (test_bit(pnfs_iomode_to_fail_bit(iomode), &lo->plh_flags) == 0) 280 int fail_bit = pnfs_iomode_to_fail_bit(iomode);
281
282 if (test_bit(fail_bit, &lo->plh_flags) == 0)
263 return false; 283 return false;
264 end = jiffies; 284 end = jiffies;
265 start = end - PNFS_LAYOUTGET_RETRY_TIMEOUT; 285 start = end - PNFS_LAYOUTGET_RETRY_TIMEOUT;
266 if (!time_in_range(lo->plh_retry_timestamp, start, end)) { 286 if (!time_in_range(lo->plh_retry_timestamp, start, end)) {
267 /* It is time to retry the failed layoutgets */ 287 /* It is time to retry the failed layoutgets */
268 clear_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags); 288 pnfs_layout_clear_fail_bit(lo, fail_bit);
269 clear_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags);
270 return false; 289 return false;
271 } 290 }
272 return true; 291 return true;
@@ -493,9 +512,14 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)
493 if (lo) { 512 if (lo) {
494 lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ 513 lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */
495 pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL); 514 pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
496 } 515 pnfs_get_layout_hdr(lo);
497 spin_unlock(&nfsi->vfs_inode.i_lock); 516 pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
498 pnfs_free_lseg_list(&tmp_list); 517 pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
518 spin_unlock(&nfsi->vfs_inode.i_lock);
519 pnfs_free_lseg_list(&tmp_list);
520 pnfs_put_layout_hdr(lo);
521 } else
522 spin_unlock(&nfsi->vfs_inode.i_lock);
499} 523}
500EXPORT_SYMBOL_GPL(pnfs_destroy_layout); 524EXPORT_SYMBOL_GPL(pnfs_destroy_layout);
501 525