[pnfs] [PATCH 23/37] pnfs: client layout cache: filelayout: implement {alloc, free}_lseg

Benny Halevy bhalevy at panasas.com
Tue Jan 1 05:51:09 EST 2008


refactor struct nfs4_filelayout and put the per-segment specific
fields in nfs4_filelayout_segment.

One such segment per inode is allocated along with nfs4_filelayout
while filelayout_{alloc,free}_lseg just work on this single instance.

In the future several segment can be maintained by passing along
the lseg ptr given to the I/O functions down to the internal file layout
functions.

Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
 fs/nfs/nfs4filelayout.c    |   56 +++++++++++++++++++++++++++++++++-----------
 fs/nfs/nfs4filelayout.h    |   15 ++++++-----
 fs/nfs/nfs4filelayoutdev.c |    7 ++++-
 3 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 8bbad08..8fc8189 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -176,11 +176,15 @@ extern struct rpc_call_ops nfs_read_partial_ops;
  * layout type is STRIPE_DENSE or STRIPE_SPARSE
  */
 loff_t
-filelayout_get_dserver_offset(loff_t offset, struct nfs4_filelayout *layout)
+filelayout_get_dserver_offset(loff_t offset, struct nfs4_filelayout *flo)
 {
-	if (layout == NULL)
+	struct nfs4_filelayout_segment *layout;
+
+	if (flo == NULL)
 		return offset;
 
+	layout = LSEG_LD_DATA(&flo->pnfs_lseg);
+
 	switch (layout->stripe_type) {
 	case STRIPE_SPARSE:
 		return offset;
@@ -409,7 +413,8 @@ filelayout_alloc_layout(struct pnfs_mount_type *mountid, struct inode *inode)
 {
 	dprintk("NFS_FILELAYOUT: allocating layout\n");
 	return kzalloc(sizeof(struct pnfs_layout_type) +
-		       sizeof(struct nfs4_filelayout), GFP_KERNEL);
+		       sizeof(struct nfs4_filelayout) +
+		       sizeof(struct nfs4_filelayout_segment), GFP_KERNEL);
 }
 
 /* Free a filelayout layout structure
@@ -429,21 +434,18 @@ filelayout_free_layout(struct pnfs_layout_type **layoutidp,
 /* Decode layout and store in layoutid.  Overwrite any existing layout
  * information for this file.
  */
-struct pnfs_layout_type*
+static struct pnfs_layout_type*
 filelayout_set_layout(struct pnfs_layout_type *layoutid,
 			struct nfs4_pnfs_layoutget_res *lgr)
 {
-	struct nfs4_filelayout *fl = NULL;
+	struct nfs4_filelayout *flo = PNFS_LD_DATA(layoutid);
+	struct nfs4_filelayout_segment *fl = LSEG_LD_DATA(&flo->pnfs_lseg);
 	int i;
 	uint32_t *p = (uint32_t *)lgr->layout.buf;
 	uint32_t nfl_util;
 
 	dprintk("%s set_layout_map Begin\n", __FUNCTION__);
 
-	if (!layoutid)
-		goto nfserr;
-	fl = PNFS_LD_DATA(layoutid);
-
 	READ32(fl->dev_id);
 	READ32(nfl_util);
 	if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS)
@@ -470,8 +472,28 @@ filelayout_set_layout(struct pnfs_layout_type *layoutid,
 	}
 
 	return layoutid;
-nfserr:
-	return NULL;
+}
+
+static struct pnfs_layout_segment *
+filelayout_alloc_lseg(struct pnfs_layout_type *layoutid,
+		      struct nfs4_pnfs_layoutget_res *lgr)
+{
+	struct nfs4_filelayout *fl;
+
+	filelayout_set_layout(layoutid, lgr);
+
+	fl = PNFS_LD_DATA(layoutid);
+	return &fl->pnfs_lseg;
+}
+
+static void
+filelayout_free_lseg(struct pnfs_layout_type *layoutid,
+		     struct pnfs_layout_segment *lseg)
+{
+	struct nfs4_filelayout *flo = PNFS_LD_DATA(layoutid);
+	struct nfs4_filelayout_segment *fls = LSEG_LD_DATA(&flo->pnfs_lseg);
+
+	memset(fls, 0, sizeof(*fls));
 }
 
 /* TODO: Technically we would need to execute a COMMIT op to each
@@ -484,7 +506,8 @@ filelayout_commit(struct pnfs_layout_type *layoutid, struct list_head *pages,
 {
 	struct inode *ino = PNFS_INODE(layoutid);
 	struct nfs_write_data   *dsdata = NULL;
-	struct nfs4_filelayout *nfslay;
+	struct nfs4_filelayout *flo;
+	struct nfs4_filelayout_segment *nfslay;
 	struct nfs4_pnfs_dev_item *dev;
 	struct nfs4_pnfs_dev *fdev;
 	struct nfs4_pnfs_dserver dserver;
@@ -494,7 +517,8 @@ filelayout_commit(struct pnfs_layout_type *layoutid, struct list_head *pages,
 	struct list_head *pos, *tmp;
 	int i;
 
-	nfslay = PNFS_LD_DATA(layoutid);
+	flo = PNFS_LD_DATA(layoutid);
+	nfslay = LSEG_LD_DATA(&flo->pnfs_lseg);
 
 	dprintk("%s data %p pnfs_client %p nfslay %p\n",
 			__FUNCTION__, data, data->pnfs_client, nfslay);
@@ -578,7 +602,9 @@ out_bad:
 ssize_t
 filelayout_get_stripesize(struct pnfs_layout_type *layoutid)
 {
-	struct nfs4_filelayout *fl = PNFS_LD_DATA(layoutid);
+	struct nfs4_filelayout *flo = PNFS_LD_DATA(layoutid);
+	struct nfs4_filelayout_segment *fl = LSEG_LD_DATA(&flo->pnfs_lseg);
+
 	ssize_t stripesize = fl->stripe_unit;
 	return stripesize;
 }
@@ -632,6 +658,8 @@ struct layoutdriver_io_operations filelayout_io_operations = {
 	.set_layout              = filelayout_set_layout,
 	.alloc_layout            = filelayout_alloc_layout,
 	.free_layout             = filelayout_free_layout,
+	.alloc_lseg              = filelayout_alloc_lseg,
+	.free_lseg               = filelayout_free_lseg,
 	.initialize_mountpoint   = filelayout_initialize_mountpoint,
 	.uninitialize_mountpoint = filelayout_uninitialize_mountpoint,
 };
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index fd099c7..bd8164b 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -80,13 +80,7 @@ struct nfs4_pnfs_dserver {
 	u32 dev_id;
 };
 
-struct nfs4_filelayout {
-	int uncommitted_write;
-	loff_t last_commit_size;
-	u64 layout_id;
-	u64 offset;
-	u64 length;
-	u32 iomode;
+struct nfs4_filelayout_segment {
 	u32 stripe_type;
 	u32 commit_through_mds;
 	u64 stripe_unit;
@@ -96,6 +90,13 @@ struct nfs4_filelayout {
 	struct nfs_fh fh_array[NFS4_PNFS_MAX_STRIPE_CNT];
 };
 
+struct nfs4_filelayout {
+	int uncommitted_write;
+	loff_t last_commit_size;
+	u64 layout_id;
+	struct pnfs_layout_segment pnfs_lseg;
+};
+
 struct filelayout_mount_type {
 	struct super_block *fl_sb;
 	struct nfs4_pnfs_dev_hlist *hlist;
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 9d38cc8..940abf4 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -658,18 +658,21 @@ nfs4_pnfs_device_item_get(struct inode *inode, u32 dev_id)
  */
 int
 nfs4_pnfs_dserver_get(struct inode *inode,
-		      struct nfs4_filelayout *layout,
+		      struct nfs4_filelayout *flo,
 		      loff_t offset,
 		      size_t count,
 		      struct nfs4_pnfs_dserver *dserver)
 {
+	struct nfs4_filelayout_segment *layout;
 	struct nfs4_pnfs_dev_item *di;
 	u64 tmp;
 	u32 stripe_idx, end_idx;
 
-	if (!layout)
+	if (!flo)
 		return 1;
 
+	layout = LSEG_LD_DATA(&flo->pnfs_lseg);
+
 	di = nfs4_pnfs_device_item_get(inode, layout->dev_id);
 	if (di == NULL)
 		return 1;
-- 
1.5.3.3



More information about the pNFS mailing list