diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-09-24 13:07:16 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-09-28 16:03:10 -0400 |
commit | 3e6212149304eaf9289d5bc56e003068660f3476 (patch) | |
tree | e1b9f72afd21b68e3a8c76a6b341183fe2001a5a /fs | |
parent | 830ffb565760234eb984e4343ad82575e96728de (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.c | 40 |
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 | ||
249 | static void | 249 | static void |
250 | pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode) | 250 | pnfs_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 | |||
257 | static void | ||
258 | pnfs_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 | |||
264 | static void | ||
265 | pnfs_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 | |||
259 | pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode) | 277 | pnfs_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 | } |
500 | EXPORT_SYMBOL_GPL(pnfs_destroy_layout); | 524 | EXPORT_SYMBOL_GPL(pnfs_destroy_layout); |
501 | 525 | ||