Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e036f464 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

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: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 2d6cf5ab
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -486,15 +486,6 @@ pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1,
	       (end2 == NFS4_MAX_UINT64 || end2 > start1);
}

static bool
should_free_lseg(const struct pnfs_layout_range *lseg_range,
		 const struct pnfs_layout_range *recall_range)
{
	return (recall_range->iomode == IOMODE_ANY ||
		lseg_range->iomode == recall_range->iomode) &&
	       pnfs_lseg_range_intersecting(lseg_range, recall_range);
}

static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
		struct list_head *tmp_list)
{
@@ -533,6 +524,27 @@ static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
	return (s32)(s1 - s2) > 0;
}

static bool
pnfs_should_free_range(const struct pnfs_layout_range *lseg_range,
		 const struct pnfs_layout_range *recall_range)
{
	return (recall_range->iomode == IOMODE_ANY ||
		lseg_range->iomode == recall_range->iomode) &&
	       pnfs_lseg_range_intersecting(lseg_range, recall_range);
}

static bool
pnfs_match_lseg_recall(const struct pnfs_layout_segment *lseg,
		const struct pnfs_layout_range *recall_range,
		u32 seq)
{
	if (seq != 0 && pnfs_seqid_is_newer(lseg->pls_seq, seq))
		return false;
	if (recall_range == NULL)
		return true;
	return pnfs_should_free_range(&lseg->pls_range, recall_range);
}

/**
 * pnfs_mark_matching_lsegs_invalid - tear down lsegs or mark them for later
 * @lo: layout header containing the lsegs
@@ -562,10 +574,7 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
	if (list_empty(&lo->plh_segs))
		return 0;
	list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
		if (!recall_range ||
		    should_free_lseg(&lseg->pls_range, recall_range)) {
			if (seq && pnfs_seqid_is_newer(lseg->pls_seq, seq))
				continue;
		if (pnfs_match_lseg_recall(lseg, recall_range, seq)) {
			dprintk("%s: freeing lseg %p iomode %d seq %u"
				"offset %llu length %llu\n", __func__,
				lseg, lseg->pls_range.iomode, lseg->pls_seq,
@@ -1845,7 +1854,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
	assert_spin_locked(&lo->plh_inode->i_lock);

	list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
		if (should_free_lseg(&lseg->pls_range, return_range)) {
		if (pnfs_match_lseg_recall(lseg, return_range, seq)) {
			dprintk("%s: marking lseg %p iomode %d "
				"offset %llu length %llu\n", __func__,
				lseg, lseg->pls_range.iomode,