[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