[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