Commit 5746006f authored by Trond Myklebust's avatar Trond Myklebust

NFS: Add an nfsiod workqueue

NFS post-rpciod cleanups often involve tasks that cannot be safely
performed within the rpciod context (due to deadlock concerns). We
therefore add a dedicated NFS workqueue that can perform tasks like
cleaning up state after an interrupted NFSv4 open() call, or calling
put_nfs_open_context() after an asynchronous read or write call.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 32bfb5c0
...@@ -1219,6 +1219,36 @@ static void nfs_destroy_inodecache(void) ...@@ -1219,6 +1219,36 @@ static void nfs_destroy_inodecache(void)
kmem_cache_destroy(nfs_inode_cachep); kmem_cache_destroy(nfs_inode_cachep);
} }
struct workqueue_struct *nfsiod_workqueue;
/*
* start up the nfsiod workqueue
*/
static int nfsiod_start(void)
{
struct workqueue_struct *wq;
dprintk("RPC: creating workqueue nfsiod\n");
wq = create_singlethread_workqueue("nfsiod");
if (wq == NULL)
return -ENOMEM;
nfsiod_workqueue = wq;
return 0;
}
/*
* Destroy the nfsiod workqueue
*/
static void nfsiod_stop(void)
{
struct workqueue_struct *wq;
wq = nfsiod_workqueue;
if (wq == NULL)
return;
nfsiod_workqueue = NULL;
destroy_workqueue(wq);
}
/* /*
* Initialize NFS * Initialize NFS
*/ */
...@@ -1226,6 +1256,10 @@ static int __init init_nfs_fs(void) ...@@ -1226,6 +1256,10 @@ static int __init init_nfs_fs(void)
{ {
int err; int err;
err = nfsiod_start();
if (err)
goto out6;
err = nfs_fs_proc_init(); err = nfs_fs_proc_init();
if (err) if (err)
goto out5; goto out5;
...@@ -1272,6 +1306,8 @@ static int __init init_nfs_fs(void) ...@@ -1272,6 +1306,8 @@ static int __init init_nfs_fs(void)
out4: out4:
nfs_fs_proc_exit(); nfs_fs_proc_exit();
out5: out5:
nfsiod_stop();
out6:
return err; return err;
} }
...@@ -1287,6 +1323,7 @@ static void __exit exit_nfs_fs(void) ...@@ -1287,6 +1323,7 @@ static void __exit exit_nfs_fs(void)
#endif #endif
unregister_nfs_fs(); unregister_nfs_fs();
nfs_fs_proc_exit(); nfs_fs_proc_exit();
nfsiod_stop();
} }
/* Not quite true; I just maintain it */ /* Not quite true; I just maintain it */
......
...@@ -143,6 +143,7 @@ extern struct rpc_procinfo nfs4_procedures[]; ...@@ -143,6 +143,7 @@ extern struct rpc_procinfo nfs4_procedures[];
extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask);
/* inode.c */ /* inode.c */
extern struct workqueue_struct *nfsiod_workqueue;
extern struct inode *nfs_alloc_inode(struct super_block *sb); extern struct inode *nfs_alloc_inode(struct super_block *sb);
extern void nfs_destroy_inode(struct inode *); extern void nfs_destroy_inode(struct inode *);
extern int nfs_write_inode(struct inode *,int); extern int nfs_write_inode(struct inode *,int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment