[pnfs] [PATCH 3/3] pnfs server 2.6-latest simulate layoutreturn on nomatching_layouts error

andros at umich.edu andros at umich.edu
Wed Sep 26 08:53:46 EDT 2007


From: Andy Adamson <andros at ibmcl7.citi.umich.edu>

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        |   43 ++++++++++++++++++++++++++++++-------------
 include/linux/nfsd/pnfsd.h |    2 +-
 3 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 3bf1262..6de991e 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -389,7 +389,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);
 #endif /* CONFIG_PNFS */
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 293b9f3..2730ba0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4871,12 +4871,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;
@@ -4949,6 +4973,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);
                 }
 
@@ -4962,7 +4988,8 @@ 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;
@@ -5010,23 +5037,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 8311d2d..373fc90 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 *,
-- 
1.5.0.2



More information about the pNFS mailing list