aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-07-22 11:13:22 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-07-24 16:16:40 -0400
commite036f46453f252539cb62bf91d82c3d08e37e73c (patch)
tree0c44303a8033868001a83ba488a0c3c7571e8b06
parent2d6cf5ab0b5d13d06c4b7920d6a12dbedf003190 (diff)
NFS: pnfs_mark_matching_lsegs_return() should match the layout sequence id
When determining which layout segments to return, we do want pnfs_mark_matching_lsegs_return to check that they match the layout sequence id. This ensures that we don't waste time if the server is replaying a layout recall that has already been satisfied. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/pnfs.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index c57cbddca760..52b2a4dfdcb0 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -486,15 +486,6 @@ pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1,
486 (end2 == NFS4_MAX_UINT64 || end2 > start1); 486 (end2 == NFS4_MAX_UINT64 || end2 > start1);
487} 487}
488 488
489static bool
490should_free_lseg(const struct pnfs_layout_range *lseg_range,
491 const struct pnfs_layout_range *recall_range)
492{
493 return (recall_range->iomode == IOMODE_ANY ||
494 lseg_range->iomode == recall_range->iomode) &&
495 pnfs_lseg_range_intersecting(lseg_range, recall_range);
496}
497
498static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg, 489static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
499 struct list_head *tmp_list) 490 struct list_head *tmp_list)
500{ 491{
@@ -533,6 +524,27 @@ static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
533 return (s32)(s1 - s2) > 0; 524 return (s32)(s1 - s2) > 0;
534} 525}
535 526
527static bool
528pnfs_should_free_range(const struct pnfs_layout_range *lseg_range,
529 const struct pnfs_layout_range *recall_range)
530{
531 return (recall_range->iomode == IOMODE_ANY ||
532 lseg_range->iomode == recall_range->iomode) &&
533 pnfs_lseg_range_intersecting(lseg_range, recall_range);
534}
535
536static bool
537pnfs_match_lseg_recall(const struct pnfs_layout_segment *lseg,
538 const struct pnfs_layout_range *recall_range,
539 u32 seq)
540{
541 if (seq != 0 && pnfs_seqid_is_newer(lseg->pls_seq, seq))
542 return false;
543 if (recall_range == NULL)
544 return true;
545 return pnfs_should_free_range(&lseg->pls_range, recall_range);
546}
547
536/** 548/**
537 * pnfs_mark_matching_lsegs_invalid - tear down lsegs or mark them for later 549 * pnfs_mark_matching_lsegs_invalid - tear down lsegs or mark them for later
538 * @lo: layout header containing the lsegs 550 * @lo: layout header containing the lsegs
@@ -562,10 +574,7 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
562 if (list_empty(&lo->plh_segs)) 574 if (list_empty(&lo->plh_segs))
563 return 0; 575 return 0;
564 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) 576 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
565 if (!recall_range || 577 if (pnfs_match_lseg_recall(lseg, recall_range, seq)) {
566 should_free_lseg(&lseg->pls_range, recall_range)) {
567 if (seq && pnfs_seqid_is_newer(lseg->pls_seq, seq))
568 continue;
569 dprintk("%s: freeing lseg %p iomode %d seq %u" 578 dprintk("%s: freeing lseg %p iomode %d seq %u"
570 "offset %llu length %llu\n", __func__, 579 "offset %llu length %llu\n", __func__,
571 lseg, lseg->pls_range.iomode, lseg->pls_seq, 580 lseg, lseg->pls_range.iomode, lseg->pls_seq,
@@ -1845,7 +1854,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
1845 assert_spin_locked(&lo->plh_inode->i_lock); 1854 assert_spin_locked(&lo->plh_inode->i_lock);
1846 1855
1847 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) 1856 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
1848 if (should_free_lseg(&lseg->pls_range, return_range)) { 1857 if (pnfs_match_lseg_recall(lseg, return_range, seq)) {
1849 dprintk("%s: marking lseg %p iomode %d " 1858 dprintk("%s: marking lseg %p iomode %d "
1850 "offset %llu length %llu\n", __func__, 1859 "offset %llu length %llu\n", __func__,
1851 lseg, lseg->pls_range.iomode, 1860 lseg, lseg->pls_range.iomode,