@@ -2394,6 +2394,7 @@ static void nfs_destroy_inodecache(void)
kmem_cache_destroy(nfs_inode_cachep);
}
+struct workqueue_struct *nfssync_workqueue;
struct workqueue_struct *nfsiod_workqueue;
EXPORT_SYMBOL_GPL(nfsiod_workqueue);
@@ -2404,9 +2405,17 @@ static int nfsiod_start(void)
{
struct workqueue_struct *wq;
dprintk("RPC: creating workqueue nfsiod\n");
+ wq = alloc_workqueue("nfs-sync", WQ_UNBOUND, 0);
+ if (wq == NULL)
+ return -ENOMEM;
+ nfssync_workqueue = wq;
wq = alloc_workqueue("nfsiod", WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
- if (wq == NULL)
+ if (wq == NULL) {
+ wq = nfssync_workqueue;
+ nfsiod_workqueue = NULL;
+ destroy_workqueue(wq);
return -ENOMEM;
+ }
nfsiod_workqueue = wq;
return 0;
}
@@ -2419,10 +2428,15 @@ static void nfsiod_stop(void)
struct workqueue_struct *wq;
wq = nfsiod_workqueue;
- if (wq == NULL)
- return;
- nfsiod_workqueue = NULL;
- destroy_workqueue(wq);
+ if (wq != NULL) {
+ nfsiod_workqueue = NULL;
+ destroy_workqueue(wq);
+ }
+ wq = nfssync_workqueue;
+ if (wq != NULL) {
+ nfssync_workqueue = NULL;
+ destroy_workqueue(wq);
+ }
}
unsigned int nfs_net_id;
@@ -446,6 +446,7 @@ int nfs_check_flags(int);
/* inode.c */
extern struct workqueue_struct *nfsiod_workqueue;
+extern struct workqueue_struct *nfssync_workqueue;
extern struct inode *nfs_alloc_inode(struct super_block *sb);
extern void nfs_free_inode(struct inode *);
extern int nfs_write_inode(struct inode *, struct writeback_control *);
@@ -511,7 +511,7 @@ static int nfs_do_local_read(struct nfs_pgio_header *hdr, struct file *filp,
args.done = &done;
INIT_WORK_ONSTACK(&args.work, nfs_local_call_read);
- queue_work(nfsiod_workqueue, &args.work);
+ queue_work(nfssync_workqueue, &args.work);
wait_for_completion(&done);
destroy_work_on_stack(&args.work);
return 0;
@@ -682,7 +682,7 @@ static int nfs_do_local_write(struct nfs_pgio_header *hdr, struct file *filp,
args.done = &done;
INIT_WORK_ONSTACK(&args.work, nfs_local_call_write);
- queue_work(nfsiod_workqueue, &args.work);
+ queue_work(nfssync_workqueue, &args.work);
wait_for_completion(&done);
destroy_work_on_stack(&args.work);
return 0;