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

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
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -1219,6 +1219,36 @@ static void nfs_destroy_inodecache(void)
	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
 */
@@ -1226,6 +1256,10 @@ static int __init init_nfs_fs(void)
{
	int err;

	err = nfsiod_start();
	if (err)
		goto out6;

	err = nfs_fs_proc_init();
	if (err)
		goto out5;
@@ -1272,6 +1306,8 @@ out3:
out4:
	nfs_fs_proc_exit();
out5:
	nfsiod_stop();
out6:
	return err;
}

@@ -1287,6 +1323,7 @@ static void __exit exit_nfs_fs(void)
#endif
	unregister_nfs_fs();
	nfs_fs_proc_exit();
	nfsiod_stop();
}

/* Not quite true; I just maintain it */
+1 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ extern struct rpc_procinfo nfs4_procedures[];
extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask);

/* inode.c */
extern struct workqueue_struct *nfsiod_workqueue;
extern struct inode *nfs_alloc_inode(struct super_block *sb);
extern void nfs_destroy_inode(struct inode *);
extern int nfs_write_inode(struct inode *,int);