aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-03-11 10:20:31 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-11 10:57:35 -0400
commit5ffaf8554163d9f3873988ce2f9977f6c6f408d2 (patch)
treeed026242a8580c8df03c9383ef32e6e7fb90f949
parentcb9c1c4a880bc734c2848f8647be2cfa336ee346 (diff)
NFS: replace global bl_wq with per-net one
This queue is used for sleeping in kernel and it have to be per-net since we don't want to wake any other waiters except in out network nemespace. BTW, move wq to per-net data is easy. But some way to handle upcall timeouts have to be provided. On message destroy in case of timeout, tasks, waiting for message to be delivered, should be awakened. Thus, some data required to located the right wait queue. Chosen solution replaces rpc_pipe_msg object with new introduced bl_pipe_msg object, containing rpc_pipe_msg and proper wq. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/blocklayout/blocklayout.c4
-rw-r--r--fs/nfs/blocklayout/blocklayout.h7
-rw-r--r--fs/nfs/blocklayout/blocklayoutdev.c32
-rw-r--r--fs/nfs/blocklayout/blocklayoutdm.c26
-rw-r--r--fs/nfs/netns.h1
5 files changed, 39 insertions, 31 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 783ebd51bd5f..61501346324e 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -46,8 +46,6 @@ MODULE_LICENSE("GPL");
46MODULE_AUTHOR("Andy Adamson <andros@citi.umich.edu>"); 46MODULE_AUTHOR("Andy Adamson <andros@citi.umich.edu>");
47MODULE_DESCRIPTION("The NFSv4.1 pNFS Block layout driver"); 47MODULE_DESCRIPTION("The NFSv4.1 pNFS Block layout driver");
48 48
49wait_queue_head_t bl_wq;
50
51static void print_page(struct page *page) 49static void print_page(struct page *page)
52{ 50{
53 dprintk("PRINTPAGE page %p\n", page); 51 dprintk("PRINTPAGE page %p\n", page);
@@ -1117,6 +1115,7 @@ static int nfs4blocklayout_net_init(struct net *net)
1117 struct nfs_net *nn = net_generic(net, nfs_net_id); 1115 struct nfs_net *nn = net_generic(net, nfs_net_id);
1118 struct dentry *dentry; 1116 struct dentry *dentry;
1119 1117
1118 init_waitqueue_head(&nn->bl_wq);
1120 nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0); 1119 nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0);
1121 if (IS_ERR(nn->bl_device_pipe)) 1120 if (IS_ERR(nn->bl_device_pipe))
1122 return PTR_ERR(nn->bl_device_pipe); 1121 return PTR_ERR(nn->bl_device_pipe);
@@ -1153,7 +1152,6 @@ static int __init nfs4blocklayout_init(void)
1153 if (ret) 1152 if (ret)
1154 goto out; 1153 goto out;
1155 1154
1156 init_waitqueue_head(&bl_wq);
1157 ret = rpc_pipefs_notifier_register(&nfs4blocklayout_block); 1155 ret = rpc_pipefs_notifier_register(&nfs4blocklayout_block);
1158 if (ret) 1156 if (ret)
1159 goto out_remove; 1157 goto out_remove;
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index 58ac8614c4c4..03350690118e 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -153,13 +153,16 @@ BLK_LSEG2EXT(struct pnfs_layout_segment *lseg)
153 return BLK_LO2EXT(lseg->pls_layout); 153 return BLK_LO2EXT(lseg->pls_layout);
154} 154}
155 155
156struct bl_pipe_msg {
157 struct rpc_pipe_msg msg;
158 wait_queue_head_t *bl_wq;
159};
160
156struct bl_msg_hdr { 161struct bl_msg_hdr {
157 u8 type; 162 u8 type;
158 u16 totallen; /* length of entire message, including hdr itself */ 163 u16 totallen; /* length of entire message, including hdr itself */
159}; 164};
160 165
161extern wait_queue_head_t bl_wq;
162
163#define BL_DEVICE_UMOUNT 0x0 /* Umount--delete devices */ 166#define BL_DEVICE_UMOUNT 0x0 /* Umount--delete devices */
164#define BL_DEVICE_MOUNT 0x1 /* Mount--create devices*/ 167#define BL_DEVICE_MOUNT 0x1 /* Mount--create devices*/
165#define BL_DEVICE_REQUEST_INIT 0x0 /* Start request */ 168#define BL_DEVICE_REQUEST_INIT 0x0 /* Start request */
diff --git a/fs/nfs/blocklayout/blocklayoutdev.c b/fs/nfs/blocklayout/blocklayoutdev.c
index 1d58642b1530..a5c88a554d92 100644
--- a/fs/nfs/blocklayout/blocklayoutdev.c
+++ b/fs/nfs/blocklayout/blocklayoutdev.c
@@ -91,16 +91,18 @@ ssize_t bl_pipe_downcall(struct file *filp, const char __user *src,
91 if (copy_from_user(&nn->bl_mount_reply, src, mlen) != 0) 91 if (copy_from_user(&nn->bl_mount_reply, src, mlen) != 0)
92 return -EFAULT; 92 return -EFAULT;
93 93
94 wake_up(&bl_wq); 94 wake_up(&nn->bl_wq);
95 95
96 return mlen; 96 return mlen;
97} 97}
98 98
99void bl_pipe_destroy_msg(struct rpc_pipe_msg *msg) 99void bl_pipe_destroy_msg(struct rpc_pipe_msg *msg)
100{ 100{
101 struct bl_pipe_msg *bl_pipe_msg = container_of(msg, struct bl_pipe_msg, msg);
102
101 if (msg->errno >= 0) 103 if (msg->errno >= 0)
102 return; 104 return;
103 wake_up(&bl_wq); 105 wake_up(bl_pipe_msg->bl_wq);
104} 106}
105 107
106/* 108/*
@@ -112,7 +114,8 @@ nfs4_blk_decode_device(struct nfs_server *server,
112{ 114{
113 struct pnfs_block_dev *rv; 115 struct pnfs_block_dev *rv;
114 struct block_device *bd = NULL; 116 struct block_device *bd = NULL;
115 struct rpc_pipe_msg msg; 117 struct bl_pipe_msg bl_pipe_msg;
118 struct rpc_pipe_msg *msg = &bl_pipe_msg.msg;
116 struct bl_msg_hdr bl_msg = { 119 struct bl_msg_hdr bl_msg = {
117 .type = BL_DEVICE_MOUNT, 120 .type = BL_DEVICE_MOUNT,
118 .totallen = dev->mincount, 121 .totallen = dev->mincount,
@@ -128,15 +131,16 @@ nfs4_blk_decode_device(struct nfs_server *server,
128 dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data, 131 dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data,
129 dev->mincount); 132 dev->mincount);
130 133
131 memset(&msg, 0, sizeof(msg)); 134 bl_pipe_msg.bl_wq = &nn->bl_wq;
132 msg.data = kzalloc(sizeof(bl_msg) + dev->mincount, GFP_NOFS); 135 memset(msg, 0, sizeof(*msg));
133 if (!msg.data) { 136 msg->data = kzalloc(sizeof(bl_msg) + dev->mincount, GFP_NOFS);
137 if (!msg->data) {
134 rv = ERR_PTR(-ENOMEM); 138 rv = ERR_PTR(-ENOMEM);
135 goto out; 139 goto out;
136 } 140 }
137 141
138 memcpy(msg.data, &bl_msg, sizeof(bl_msg)); 142 memcpy(msg->data, &bl_msg, sizeof(bl_msg));
139 dataptr = (uint8_t *) msg.data; 143 dataptr = (uint8_t *) msg->data;
140 len = dev->mincount; 144 len = dev->mincount;
141 offset = sizeof(bl_msg); 145 offset = sizeof(bl_msg);
142 for (i = 0; len > 0; i++) { 146 for (i = 0; len > 0; i++) {
@@ -145,13 +149,13 @@ nfs4_blk_decode_device(struct nfs_server *server,
145 len -= PAGE_CACHE_SIZE; 149 len -= PAGE_CACHE_SIZE;
146 offset += PAGE_CACHE_SIZE; 150 offset += PAGE_CACHE_SIZE;
147 } 151 }
148 msg.len = sizeof(bl_msg) + dev->mincount; 152 msg->len = sizeof(bl_msg) + dev->mincount;
149 153
150 dprintk("%s CALLING USERSPACE DAEMON\n", __func__); 154 dprintk("%s CALLING USERSPACE DAEMON\n", __func__);
151 add_wait_queue(&bl_wq, &wq); 155 add_wait_queue(&nn->bl_wq, &wq);
152 rc = rpc_queue_upcall(nn->bl_device_pipe, &msg); 156 rc = rpc_queue_upcall(nn->bl_device_pipe, msg);
153 if (rc < 0) { 157 if (rc < 0) {
154 remove_wait_queue(&bl_wq, &wq); 158 remove_wait_queue(&nn->bl_wq, &wq);
155 rv = ERR_PTR(rc); 159 rv = ERR_PTR(rc);
156 goto out; 160 goto out;
157 } 161 }
@@ -159,7 +163,7 @@ nfs4_blk_decode_device(struct nfs_server *server,
159 set_current_state(TASK_UNINTERRUPTIBLE); 163 set_current_state(TASK_UNINTERRUPTIBLE);
160 schedule(); 164 schedule();
161 __set_current_state(TASK_RUNNING); 165 __set_current_state(TASK_RUNNING);
162 remove_wait_queue(&bl_wq, &wq); 166 remove_wait_queue(&nn->bl_wq, &wq);
163 167
164 if (reply->status != BL_DEVICE_REQUEST_PROC) { 168 if (reply->status != BL_DEVICE_REQUEST_PROC) {
165 dprintk("%s failed to open device: %d\n", 169 dprintk("%s failed to open device: %d\n",
@@ -191,7 +195,7 @@ nfs4_blk_decode_device(struct nfs_server *server,
191 bd->bd_block_size); 195 bd->bd_block_size);
192 196
193out: 197out:
194 kfree(msg.data); 198 kfree(msg->data);
195 return rv; 199 return rv;
196} 200}
197 201
diff --git a/fs/nfs/blocklayout/blocklayoutdm.c b/fs/nfs/blocklayout/blocklayoutdm.c
index a0f588fa49c1..30fc22af7bbb 100644
--- a/fs/nfs/blocklayout/blocklayoutdm.c
+++ b/fs/nfs/blocklayout/blocklayoutdm.c
@@ -40,7 +40,8 @@
40 40
41static void dev_remove(struct net *net, dev_t dev) 41static void dev_remove(struct net *net, dev_t dev)
42{ 42{
43 struct rpc_pipe_msg msg; 43 struct bl_pipe_msg bl_pipe_msg;
44 struct rpc_pipe_msg *msg = &bl_pipe_msg.msg;
44 struct bl_dev_msg bl_umount_request; 45 struct bl_dev_msg bl_umount_request;
45 struct bl_msg_hdr bl_msg = { 46 struct bl_msg_hdr bl_msg = {
46 .type = BL_DEVICE_UMOUNT, 47 .type = BL_DEVICE_UMOUNT,
@@ -52,33 +53,34 @@ static void dev_remove(struct net *net, dev_t dev)
52 53
53 dprintk("Entering %s\n", __func__); 54 dprintk("Entering %s\n", __func__);
54 55
55 memset(&msg, 0, sizeof(msg)); 56 bl_pipe_msg.bl_wq = &nn->bl_wq;
56 msg.data = kzalloc(1 + sizeof(bl_umount_request), GFP_NOFS); 57 memset(&msg, 0, sizeof(*msg));
57 if (!msg.data) 58 msg->data = kzalloc(1 + sizeof(bl_umount_request), GFP_NOFS);
59 if (!msg->data)
58 goto out; 60 goto out;
59 61
60 memset(&bl_umount_request, 0, sizeof(bl_umount_request)); 62 memset(&bl_umount_request, 0, sizeof(bl_umount_request));
61 bl_umount_request.major = MAJOR(dev); 63 bl_umount_request.major = MAJOR(dev);
62 bl_umount_request.minor = MINOR(dev); 64 bl_umount_request.minor = MINOR(dev);
63 65
64 memcpy(msg.data, &bl_msg, sizeof(bl_msg)); 66 memcpy(msg->data, &bl_msg, sizeof(bl_msg));
65 dataptr = (uint8_t *) msg.data; 67 dataptr = (uint8_t *) msg->data;
66 memcpy(&dataptr[sizeof(bl_msg)], &bl_umount_request, sizeof(bl_umount_request)); 68 memcpy(&dataptr[sizeof(bl_msg)], &bl_umount_request, sizeof(bl_umount_request));
67 msg.len = sizeof(bl_msg) + bl_msg.totallen; 69 msg->len = sizeof(bl_msg) + bl_msg.totallen;
68 70
69 add_wait_queue(&bl_wq, &wq); 71 add_wait_queue(&nn->bl_wq, &wq);
70 if (rpc_queue_upcall(nn->bl_device_pipe, &msg) < 0) { 72 if (rpc_queue_upcall(nn->bl_device_pipe, msg) < 0) {
71 remove_wait_queue(&bl_wq, &wq); 73 remove_wait_queue(&nn->bl_wq, &wq);
72 goto out; 74 goto out;
73 } 75 }
74 76
75 set_current_state(TASK_UNINTERRUPTIBLE); 77 set_current_state(TASK_UNINTERRUPTIBLE);
76 schedule(); 78 schedule();
77 __set_current_state(TASK_RUNNING); 79 __set_current_state(TASK_RUNNING);
78 remove_wait_queue(&bl_wq, &wq); 80 remove_wait_queue(&nn->bl_wq, &wq);
79 81
80out: 82out:
81 kfree(msg.data); 83 kfree(msg->data);
82} 84}
83 85
84/* 86/*
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
index 73425f555cde..aa14ec303e94 100644
--- a/fs/nfs/netns.h
+++ b/fs/nfs/netns.h
@@ -13,6 +13,7 @@ struct nfs_net {
13 struct cache_detail *nfs_dns_resolve; 13 struct cache_detail *nfs_dns_resolve;
14 struct rpc_pipe *bl_device_pipe; 14 struct rpc_pipe *bl_device_pipe;
15 struct bl_dev_msg bl_mount_reply; 15 struct bl_dev_msg bl_mount_reply;
16 wait_queue_head_t bl_wq;
16 struct list_head nfs_client_list; 17 struct list_head nfs_client_list;
17 struct list_head nfs_volume_list; 18 struct list_head nfs_volume_list;
18#ifdef CONFIG_NFS_V4 19#ifdef CONFIG_NFS_V4