[pnfs] [PATCH 4/4] pnfsd: simulate layoutreturn on nomatching_layouts error

Benny Halevy bhalevy at panasas.com
Thu Sep 20 17:33:06 EDT 2007


when cb_layoutrecall is replied with NFS4ERR_NOMATCHING_LAYOUTS
simulate a return_layout call into the file system and
release all layouts in the range as if a respective LAYOUTRETURN
was received.

Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
 fs/nfsd/export.c           |    2 +-
 fs/nfsd/nfs4state.c        |   44 ++++++++++++++++++++++++++++++--------------
 include/linux/nfsd/pnfsd.h |    2 +-
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index b5ea034..f4fc5af 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -376,7 +376,7 @@ void *p)
 
 	dprintk("cb_layout_recall lr %p\n", lr);
 
-	return nfsd_layout_recall_cb(inode, lr);
+	return nfsd_layout_recall_cb(sb, inode, lr);
 }
 EXPORT_SYMBOL(cb_layout_recall);
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 14c77de..29c8f05 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4793,12 +4793,36 @@ doit:
 }
 #endif
 
+static void
+nomatching_layout(struct super_block *sb, struct nfs4_layoutrecall *clr)
+{
+	struct nfsd4_pnfs_layoutreturn lr;
+
+	printk("%s: clp %p fp %p: "
+	       "simulating layout_return\n", __FUNCTION__,
+	        clr->clr_client,
+	        clr->clr_file);
+	lr.lr_return_type = clr->cb.cbl_recall_type;
+	lr.lr_seg = clr->cb.cbl_seg;
+	lr.lr_reclaim = 0;
+	lr.lr_flags = LR_FLAG_INTERN;
+	if (sb->s_export_op->layout_return)
+		sb->s_export_op->layout_return(clr->clr_file ?
+		            clr->clr_file->fi_inode : NULL, &lr);
+
+	if (clr->cb.cbl_recall_type == RECALL_FILE)
+		pnfs_return_file_layouts(clr->clr_client, clr->clr_file, &lr);
+	else
+		pnfs_return_client_layouts(clr->clr_client, &lr,
+		                           clr->cb.cbl_fsid.major);
+}
+
 /*
  * Recall a layout synchronously
  * must be called under the state lock
  */
 static int
-sync_layout_recall(struct nfs4_layoutrecall *clr)
+sync_layout_recall(struct super_block *sb, struct nfs4_layoutrecall *clr)
 {
 	struct nfs4_layoutrecall *pending;
 	struct nfs4_client *clp = NULL;
@@ -4871,6 +4895,8 @@ doit:
 				        pending->clr_client->cl_callback.cb_client,
 				        pending->clr_file,
 				        status);
+			if (status == -NFSERR_NOMATCHING_LAYOUT)
+				nomatching_layout(sb, pending);
 			layoutrecall_done(pending);
 		}
 
@@ -4884,11 +4910,11 @@ doit:
  * Spawn a thread to perform a recall layout
  *
  */
-int nfsd_layout_recall_cb(struct inode *inode, struct nfsd4_pnfs_cb_layout *cbl)
+int nfsd_layout_recall_cb(struct super_block *sb, struct inode *inode,
+                          struct nfsd4_pnfs_cb_layout *cbl)
 {
 	int status, did_lock;
 	struct nfs4_layoutrecall *clr = NULL;
-	struct task_struct *t;
 
 	dprintk("NFSD nfsd_layout_recall_cb: inode %p cbl %p\n", inode, cbl);
 	BUG_ON(!cbl);
@@ -4933,23 +4959,13 @@ int nfsd_layout_recall_cb(struct inode *inode, struct nfsd4_pnfs_cb_layout *cbl)
 			clr->cb.cbl_fsid = clr->clr_file->fi_fsid;
 	}
 
-	status = sync_layout_recall(clr);
+	status = sync_layout_recall(sb, clr);
 	if (!status) {
 		if (did_lock)
 			nfs4_unlock_state();
 		return 0;
 	}
 
-#if 0
-	t = kthread_run(do_layout_recall, clr, "%s", "nfs4_cb_recall");
-	dprintk("NFSD %s: kthread_run done error %ld\n", __FUNCTION__,
-	        IS_ERR(t) ? PTR_ERR(t) : 0L);
-	if (!IS_ERR(t))
-		return 0;	/* Success!, refcounts handled by kthread */
-
-	status = PTR_ERR(t);
-	did_lock = nfs4_lock_state_nested();
-#endif
 err:
 	put_layoutrecall(clr);
 	if (did_lock)
diff --git a/include/linux/nfsd/pnfsd.h b/include/linux/nfsd/pnfsd.h
index 67c32be..560e374 100644
--- a/include/linux/nfsd/pnfsd.h
+++ b/include/linux/nfsd/pnfsd.h
@@ -78,7 +78,7 @@ struct pnfs_mds_id {
 	time_t			di_mdsboot;	/* mds boot time */
 };
 
-int nfsd_layout_recall_cb(struct inode *inode, struct nfsd4_pnfs_cb_layout *);
+int nfsd_layout_recall_cb(struct super_block *, struct inode *, struct nfsd4_pnfs_cb_layout *);
 int nfs4_pnfs_cb_get_state(struct pnfs_get_state *);
 void nfs4_pnfs_state_init(void);
 int nfs4_pnfs_get_layout(struct super_block *, struct svc_fh *,


More information about the pNFS mailing list