[pnfs] [PATCH] when nfsd is stopped tell fs when layout is destroyed.
Marc Eshel
eshel at almaden.ibm.com
Thu Jul 26 16:12:49 EDT 2007
From: Marc Eshel <eshel at almaden.ibm.com>
---
fs/nfsd/nfs4state.c | 32 ++++++++++++++++++++++++++++++++
include/linux/nfsd/nfsd4_pnfs.h | 3 ++-
2 files changed, 34 insertions(+), 1 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b73c928..7cb5e14 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -91,6 +91,7 @@ #if defined(CONFIG_PNFS)
*/
static kmem_cache_t *pnfs_layout_slab = NULL;
static kmem_cache_t *pnfs_layoutrecall_slab = NULL;
+static int expire_layout(struct nfs4_layout *lp);
static void destroy_layout(struct nfs4_layout *lp);
static inline void layoutrecall_done(struct nfs4_layoutrecall *clr);
static void release_pnfs_ds_dev_list(struct nfs4_stateid *stp);
@@ -627,6 +628,7 @@ #if defined(CONFIG_PNFS)
dprintk("NFSD: expire client. lp %p, fp %p\n", lp,
lp->lo_file);
BUG_ON(lp->lo_client != clp);
+ expire_layout(lp);
destroy_layout(lp);
}
while (!list_empty(&clp->cl_layoutrecalls)) {
@@ -4067,6 +4069,33 @@ destroy_layout(struct nfs4_layout *lp)
put_nfs4_file(fp);
}
+static int
+expire_layout(struct nfs4_layout *lp)
+{
+ struct nfs4_client *clp;
+ struct nfs4_file *fp;
+ struct nfsd4_pnfs_layoutreturn lr;
+
+ clp = lp->lo_client;
+ fp = lp->lo_file;
+ dprintk("pNFS %s: lp %p clp %p fp %p ino %p\n", __FUNCTION__,
+ lp, clp, fp, fp->fi_inode);
+
+ /* call exported filesystem layout_return */
+ if (!fp->fi_inode->i_sb->s_export_op->layout_return)
+ return 0;
+
+ lr.lr_return_type = RETURN_FILE;
+ lr.lr_reclaim = 0;
+ lr.lr_flags = LR_FLAG_EXPIRE;
+ lr.lr_seg.clientid = lp->lo_seg.clientid;
+ lr.lr_seg.layout_type = lp->lo_seg.layout_type;
+ lr.lr_seg.iomode = IOMODE_ANY;
+ lr.lr_seg.offset = 0;
+ lr.lr_seg.length = NFS4_LENGTH_EOF;
+ return fp->fi_inode->i_sb->s_export_op->layout_return(fp->fi_inode, &lr);
+}
+
/*
* Create a layoutrecall structure
* An optional layoutrecall can be cloned (except for the layoutrecall lists)
@@ -4810,6 +4839,9 @@ int nfsd_layout_recall_cb(struct inode *
cbl->cbl_seg.iomode != IOMODE_RW &&
cbl->cbl_seg.iomode != IOMODE_ANY);
+ if (nfsd_serv == NULL)
+ return -ENOENT;
+
clr = alloc_init_layoutrecall(NULL);
if (!clr)
return -ENOMEM;
diff --git a/include/linux/nfsd/nfsd4_pnfs.h b/include/linux/nfsd/nfsd4_pnfs.h
index e051916..0d119f3 100644
--- a/include/linux/nfsd/nfsd4_pnfs.h
+++ b/include/linux/nfsd/nfsd4_pnfs.h
@@ -104,7 +104,8 @@ struct nfsd4_pnfs_layoutcommit {
};
enum layoutreturn_flags {
- LR_FLAG_INTERN = 1 << 0
+ LR_FLAG_INTERN = 1 << 0, /* internal return */
+ LR_FLAG_EXPIRE = 1 << 1, /* return on client expiration */
};
struct nfsd4_pnfs_layoutreturn {
More information about the pNFS
mailing list