pNFS: Do not free layout segments that are marked for return
We may want to process and transmit layout stat information for the
layout segments that are being returned, so we should defer freeing
them until after the layoutreturn has completed.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 917a6db..561b21e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8572,21 +8572,12 @@
{
struct nfs4_layoutreturn *lrp = calldata;
struct pnfs_layout_hdr *lo = lrp->args.layout;
- LIST_HEAD(freeme);
dprintk("--> %s\n", __func__);
- spin_lock(&lo->plh_inode->i_lock);
- if (lrp->res.lrs_present) {
- pnfs_mark_matching_lsegs_invalid(lo, &freeme,
- &lrp->args.range,
- be32_to_cpu(lrp->args.stateid.seqid));
- pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
- } else
- pnfs_mark_layout_stateid_invalid(lo, &freeme);
- pnfs_clear_layoutreturn_waitbit(lo);
- spin_unlock(&lo->plh_inode->i_lock);
+ pnfs_layoutreturn_free_lsegs(lo, &lrp->args.range,
+ be32_to_cpu(lrp->args.stateid.seqid),
+ lrp->res.lrs_present ? &lrp->res.stateid : NULL);
nfs4_sequence_free_slot(&lrp->res.seq_res);
- pnfs_free_lseg_list(&freeme);
pnfs_put_layout_hdr(lrp->args.layout);
nfs_iput_and_deactive(lrp->inode);
kfree(calldata);