Commit 3982a6a2 authored by Jeff Layton's avatar Jeff Layton Committed by Anna Schumaker

pnfs: keep track of the return sequence number in pnfs_layout_hdr

When we want to selectively do a LAYOUTRETURN, we need to specify a
stateid that represents most recent layout acquisition that is to be
returned.

When we mark a layout stateid to be returned, we update the return
sequence number in the layout header with that value, if it's newer
than the existing one. Then, when we go to do a LAYOUTRETURN on
layout header put, we overwrite the seqid in the stateid with the
saved one, and then zero it out.
Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 66755283
...@@ -899,6 +899,7 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo) ...@@ -899,6 +899,7 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo)
if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
return false; return false;
lo->plh_return_iomode = 0; lo->plh_return_iomode = 0;
lo->plh_return_seq = 0;
pnfs_get_layout_hdr(lo); pnfs_get_layout_hdr(lo);
clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
return true; return true;
...@@ -969,6 +970,7 @@ static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo) ...@@ -969,6 +970,7 @@ static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo)
bool send; bool send;
nfs4_stateid_copy(&stateid, &lo->plh_stateid); nfs4_stateid_copy(&stateid, &lo->plh_stateid);
stateid.seqid = cpu_to_be32(lo->plh_return_seq);
iomode = lo->plh_return_iomode; iomode = lo->plh_return_iomode;
send = pnfs_prepare_layoutreturn(lo); send = pnfs_prepare_layoutreturn(lo);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
...@@ -1747,7 +1749,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1747,7 +1749,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
} }
static void static void
pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode) pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode,
u32 seq)
{ {
if (lo->plh_return_iomode == iomode) if (lo->plh_return_iomode == iomode)
return; return;
...@@ -1755,6 +1758,8 @@ pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode) ...@@ -1755,6 +1758,8 @@ pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode)
iomode = IOMODE_ANY; iomode = IOMODE_ANY;
lo->plh_return_iomode = iomode; lo->plh_return_iomode = iomode;
set_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); set_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
if (!lo->plh_return_seq || pnfs_seqid_is_newer(seq, lo->plh_return_seq))
lo->plh_return_seq = seq;
} }
/** /**
...@@ -1793,7 +1798,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, ...@@ -1793,7 +1798,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
continue; continue;
remaining++; remaining++;
set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags); set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
pnfs_set_plh_return_iomode(lo, return_range->iomode); pnfs_set_plh_return_info(lo, return_range->iomode, lseg->pls_seq);
} }
return remaining; return remaining;
} }
...@@ -1811,7 +1816,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, ...@@ -1811,7 +1816,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
bool return_now = false; bool return_now = false;
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
pnfs_set_plh_return_iomode(lo, range.iomode); pnfs_set_plh_return_info(lo, range.iomode, lseg->pls_seq);
/* /*
* mark all matching lsegs so that we are sure to have no live * mark all matching lsegs so that we are sure to have no live
* segments at hand when sending layoutreturn. See pnfs_put_lseg() * segments at hand when sending layoutreturn. See pnfs_put_lseg()
......
...@@ -195,6 +195,7 @@ struct pnfs_layout_hdr { ...@@ -195,6 +195,7 @@ struct pnfs_layout_hdr {
unsigned long plh_flags; unsigned long plh_flags;
nfs4_stateid plh_stateid; nfs4_stateid plh_stateid;
u32 plh_barrier; /* ignore lower seqids */ u32 plh_barrier; /* ignore lower seqids */
u32 plh_return_seq;
enum pnfs_iomode plh_return_iomode; enum pnfs_iomode plh_return_iomode;
loff_t plh_lwb; /* last write byte for layoutcommit */ loff_t plh_lwb; /* last write byte for layoutcommit */
struct rpc_cred *plh_lc_cred; /* layoutcommit cred */ struct rpc_cred *plh_lc_cred; /* layoutcommit cred */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment