nfs4.1: fix several problems with _pnfs_return_layout
_pnfs_return_layout had the following problems:
- it did not call pnfs_free_lseg_list on all paths
- it unintentionally did a forgetful return when there was no outstanding io
- it raced with concurrent LAYOUTGETS
Signed-off-by: Fred Isaman <iisaman@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 8c1309d..25de6b2 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -634,12 +634,14 @@
spin_lock(&ino->i_lock);
lo = nfsi->layout;
- if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) {
+ if (!lo) {
spin_unlock(&ino->i_lock);
- dprintk("%s: no layout segments to return\n", __func__);
- goto out;
+ dprintk("%s: no layout to return\n", __func__);
+ return status;
}
stateid = nfsi->layout->plh_stateid;
+ mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
+ lo->plh_block_lgets++;
/* Reference matched in nfs4_layoutreturn_release */
get_layout_hdr(lo);
spin_unlock(&ino->i_lock);