[pnfs] [PATCH 38/38] [v1] pnfs: client layout cache: return_layout: use pnfs_free_layout

Benny Halevy bhalevy at panasas.com
Fri Jan 4 05:53:05 EST 2008


LD's free_layout method is being called now only to free the pnfs_layout_type
structure while individual segments are being freed via pnfs_free_layout
by calling the LD's free_lseg method.

put_unlock_current_layout decrements the overall layout reference counts
and frees it when its segments list is empty, then it sets nfsi->current_layout
to null.

Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
 fs/nfs/nfs4filelayout.c   |    8 +-------
 fs/nfs/pnfs.c             |   13 ++++++++++---
 include/linux/nfs4_pnfs.h |    2 +-
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 588c3a2..f67613b 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -420,16 +420,10 @@ filelayout_alloc_layout(struct pnfs_mount_type *mountid, struct inode *inode)
 /* Free a filelayout layout structure
  */
 void
-filelayout_free_layout(struct pnfs_layout_type **layoutidp,
-		       struct nfs4_pnfs_layout_segment *range)
+filelayout_free_layout(struct pnfs_layout_type *layoutid)
 {
-	struct pnfs_layout_type *layoutid;
-
 	dprintk("NFS_FILELAYOUT: freeing layout\n");
-
-	layoutid = *layoutidp;
 	kfree(layoutid);
-	*layoutidp = NULL;
 }
 
 /* Decode layout and store in layoutid.  Overwrite any existing layout
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 710619a..576166f 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -343,7 +343,15 @@ put_unlock_current_layout(struct nfs_inode *nfsi,
 	BUG_ON_UNLOCKED_LO(lo);
 	BUG_ON(lo->refcount <= 0);
 
-	--lo->refcount;
+	if (--lo->refcount == 0 && list_empty(&lo->segs)) {
+		struct layoutdriver_io_operations *io_ops =
+			PNFS_LD_IO_OPS(lo);
+
+		dprintk("%s: freeing layout %p\n", __FUNCTION__, lo);
+		io_ops->free_layout(lo);
+
+		nfsi->current_layout = NULL;
+	}
 	spin_unlock(&nfsi->lo_lock);
 }
 
@@ -515,8 +523,7 @@ pnfs_return_layout(struct inode *ino, struct nfs4_pnfs_layout_segment *range)
 	if (lo == NULL)
 		return 0;
 
-	server->pnfs_curr_ld->ld_io_ops->free_layout(
-		&nfsi->current_layout, &arg.lseg);
+	pnfs_free_layout(lo, &arg.lseg);
 	put_unlock_current_layout(nfsi, lo);
 
 	arg.reclaim = 0;
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index 7a0c3dc..8537b0c 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -127,7 +127,7 @@ struct layoutdriver_io_operations {
 	 * inode specific layout structure.  Each subsequent layoutget operation results in
 	 * a set_layout call to set the opaque layout in the layout driver.*/
 	struct pnfs_layout_type * (*alloc_layout) (struct pnfs_mount_type *mountid, struct inode *inode);
-	void (*free_layout) (struct pnfs_layout_type **layoutidp, struct nfs4_pnfs_layout_segment *range);
+	void (*free_layout) (struct pnfs_layout_type *layoutid);
 	struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_type *layoutid, struct nfs4_pnfs_layoutget_res *lgr);
 	void (*free_lseg) (struct pnfs_layout_type *layoutid, struct pnfs_layout_segment *lseg);
 
-- 
1.5.3.3



More information about the pNFS mailing list