[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