[pnfs] [PATCH 19/38] [v1] pnfs: client layout cache: introduce get_alloc_layout
Benny Halevy
bhalevy at panasas.com
Fri Jan 4 05:52:34 EST 2008
get_alloc_layout gets or allocates if needed the pnfs_layout_type structure
alloc_init_layout calls the layout driver's alloc_layout function
and initializes the allocated pnfs_layout_type struct.
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfs/pnfs.c | 79 ++++++++++++++++++++++++++++++++-------------
include/linux/nfs4_pnfs.h | 1 +
include/linux/nfs_fs.h | 2 +-
3 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 8c3c022..b91f5d7 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -412,38 +412,65 @@ out:
* the I/O module has its read/write methods called.
*/
static struct pnfs_layout_type *
-pnfs_inject_layout(struct nfs_inode *nfsi,
- struct layoutdriver_io_operations *io_ops,
+pnfs_inject_layout(struct pnfs_layout_type *layid,
struct nfs4_pnfs_layoutget_res *lgr)
{
- struct pnfs_layout_type *layid;
- struct inode *inode = &nfsi->vfs_inode;
- struct nfs_server *server = NFS_SERVER(inode);
+ struct layoutdriver_io_operations *io_ops = PNFS_LD_IO_OPS(layid);
dprintk("%s Begin\n", __FUNCTION__);
- if (!io_ops->alloc_layout || !io_ops->set_layout) {
+ if (!io_ops->set_layout) {
printk(KERN_ERR "%s ERROR! Layout driver lacking pNFS layout ops!!!\n", __FUNCTION__);
return NULL;
}
- if (nfsi->current_layout == NULL) {
- dprintk("%s Alloc'ing layout\n", __FUNCTION__);
- layid = io_ops->alloc_layout(server->pnfs_mountid, inode);
- if (layid)
- layid->inode = inode;
- } else {
- dprintk("%s Adding to current layout\n", __FUNCTION__);
- layid = nfsi->current_layout;
- }
+ dprintk("%s Calling set layout\n", __FUNCTION__);
+ return io_ops->set_layout(layid, lgr);
+}
- if (!layid) {
- printk(KERN_ERR "%s ERROR! Layout id non-existent!!!\n",
- __FUNCTION__);
+static struct pnfs_layout_type *
+alloc_init_layout(struct inode *ino, struct layoutdriver_io_operations *io_ops)
+{
+ struct pnfs_layout_type *lo;
+
+ lo = io_ops->alloc_layout(NFS_SERVER(ino)->pnfs_mountid, ino);
+ if (!lo) {
+ printk(KERN_ERR
+ "%s: out of memory: io_ops->alloc_layout failed\n",
+ __FUNCTION__);
return NULL;
}
- dprintk("%s Calling set layout\n", __FUNCTION__);
- return io_ops->set_layout(layid, lgr);
+
+ lo->roc_iomode = 0;
+ lo->inode = ino;
+ return lo;
+}
+
+/*
+ * get, possibly allocate current_layout
+ */
+static struct pnfs_layout_type *
+get_alloc_layout(struct inode *ino,
+ struct layoutdriver_io_operations *io_ops)
+{
+ struct nfs_inode *nfsi = NFS_I(ino);
+ struct pnfs_layout_type *lo;
+
+ dprintk("%s Begin\n", __FUNCTION__);
+
+ if ((lo = nfsi->current_layout) == NULL) {
+ lo = nfsi->current_layout = alloc_init_layout(ino, io_ops);
+ if (!lo)
+ lo = ERR_PTR(-ENOMEM);
+ }
+
+#ifdef NFS_DEBUG
+ if (!IS_ERR(lo))
+ dprintk("%s Return %p\n", __FUNCTION__, lo);
+ else
+ dprintk("%s Return error %ld\n", __FUNCTION__, PTR_ERR(lo));
+#endif
+ return lo;
}
/* Update the file's layout for the given range and iomode.
@@ -463,6 +490,12 @@ pnfs_update_layout(struct inode *ino,
struct pnfs_layout_type *layout_new;
int result = -EIO;
+ layout_new = get_alloc_layout(ino, nfss->pnfs_curr_ld->ld_io_ops);
+ if (IS_ERR(layout_new)) {
+ result = PTR_ERR(layout_new);
+ goto ret;
+ }
+
arg.lseg.iomode = iomode;
arg.lseg.offset = pos;
arg.lseg.length = count;
@@ -538,8 +571,7 @@ pnfs_update_layout(struct inode *ino,
}
/* Inject layout blob into I/O device driver */
- layout_new = pnfs_inject_layout(nfsi,
- nfss->pnfs_curr_ld->ld_io_ops,
+ layout_new = pnfs_inject_layout(nfsi->current_layout,
&res);
if (layout_new == NULL) {
printk(KERN_ERR "%s: ERROR! Could not inject layout (%d)\n",
@@ -564,7 +596,8 @@ out:
/* res.layout.buf kalloc'ed by the xdr decoder? */
kfree(res.layout.buf);
- dprintk("%s end (err:%d) state %d\n",
+ret:
+ dprintk("%s end (err:%d) state 0x%lx\n",
__FUNCTION__, result, nfsi->pnfs_layout_state);
return result;
}
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index d862aac..7ea5c33 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -37,6 +37,7 @@ struct pnfs_mount_type {
* A reference is stored in the nfs_inode structure.
*/
struct pnfs_layout_type {
+ int refcount;
int roc_iomode; /* iomode to return on close, 0=none */
struct inode *inode;
u8 ld_data[]; /* layout driver private data */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 548498d..3d6bfbf 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -176,7 +176,7 @@ struct nfs_inode {
/* pNFS layout information */
#if defined(CONFIG_PNFS)
- u32 pnfs_layout_state;
+ unsigned long pnfs_layout_state;
#define NFS_INO_LAYOUT_FAILED 0x0001 /* get layout failed, stop trying */
time_t pnfs_layout_suspend;
struct pnfs_layout_type *current_layout;
--
1.5.3.3
More information about the pNFS
mailing list