diff options
author | Fred Isaman <iisaman@citi.umich.edu> | 2011-07-30 20:52:46 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-31 12:18:16 -0400 |
commit | 2f9fd182607e7b3bdca35f6ed7f2fae539f7c46b (patch) | |
tree | 9a61ca5ef63c4160c3b632fe333720d3927b627f /fs/nfs/blocklayout/blocklayout.c | |
parent | 03341d2cc91c700fc38883e572043a6a8f17dd5c (diff) |
pnfsblock: call and parse getdevicelist
Call GETDEVICELIST during mount, then call and parse GETDEVICEINFO
for each device returned.
[pnfsblock: get rid of deprecated xdr macros]
Signed-off-by: Jim Rees <rees@umich.edu>
[pnfsblock: fix pnfs_deviceid references]
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
[pnfsblock: fix print format warnings for sector_t and size_t]
[pnfs-block: #include <linux/vmalloc.h>]
[pnfsblock: no PNFS_NFS_SERVER]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfsblock: fix bug determining size of striped volume]
[pnfsblock: fix oops when using multiple devices]
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Benny Halevy <bhalevy@tonian.com>
[pnfsblock: get rid of vmap and deviceid->area structure]
Signed-off-by: Peng Tao <peng_tao@emc.com>
Signed-off-by: Jim Rees <rees@umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/blocklayout/blocklayout.c')
-rw-r--r-- | fs/nfs/blocklayout/blocklayout.c | 138 |
1 files changed, 137 insertions, 1 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index e7bc7a57b3bb..6cd7f4f3acdb 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c | |||
@@ -157,17 +157,153 @@ bl_cleanup_layoutcommit(struct nfs4_layoutcommit_data *lcdata) | |||
157 | { | 157 | { |
158 | } | 158 | } |
159 | 159 | ||
160 | static void free_blk_mountid(struct block_mount_id *mid) | ||
161 | { | ||
162 | if (mid) { | ||
163 | struct pnfs_block_dev *dev; | ||
164 | spin_lock(&mid->bm_lock); | ||
165 | while (!list_empty(&mid->bm_devlist)) { | ||
166 | dev = list_first_entry(&mid->bm_devlist, | ||
167 | struct pnfs_block_dev, | ||
168 | bm_node); | ||
169 | list_del(&dev->bm_node); | ||
170 | bl_free_block_dev(dev); | ||
171 | } | ||
172 | spin_unlock(&mid->bm_lock); | ||
173 | kfree(mid); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /* This is mostly copied from the filelayout's get_device_info function. | ||
178 | * It seems much of this should be at the generic pnfs level. | ||
179 | */ | ||
180 | static struct pnfs_block_dev * | ||
181 | nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh, | ||
182 | struct nfs4_deviceid *d_id) | ||
183 | { | ||
184 | struct pnfs_device *dev; | ||
185 | struct pnfs_block_dev *rv = NULL; | ||
186 | u32 max_resp_sz; | ||
187 | int max_pages; | ||
188 | struct page **pages = NULL; | ||
189 | int i, rc; | ||
190 | |||
191 | /* | ||
192 | * Use the session max response size as the basis for setting | ||
193 | * GETDEVICEINFO's maxcount | ||
194 | */ | ||
195 | max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; | ||
196 | max_pages = max_resp_sz >> PAGE_SHIFT; | ||
197 | dprintk("%s max_resp_sz %u max_pages %d\n", | ||
198 | __func__, max_resp_sz, max_pages); | ||
199 | |||
200 | dev = kmalloc(sizeof(*dev), GFP_NOFS); | ||
201 | if (!dev) { | ||
202 | dprintk("%s kmalloc failed\n", __func__); | ||
203 | return NULL; | ||
204 | } | ||
205 | |||
206 | pages = kzalloc(max_pages * sizeof(struct page *), GFP_NOFS); | ||
207 | if (pages == NULL) { | ||
208 | kfree(dev); | ||
209 | return NULL; | ||
210 | } | ||
211 | for (i = 0; i < max_pages; i++) { | ||
212 | pages[i] = alloc_page(GFP_NOFS); | ||
213 | if (!pages[i]) | ||
214 | goto out_free; | ||
215 | } | ||
216 | |||
217 | memcpy(&dev->dev_id, d_id, sizeof(*d_id)); | ||
218 | dev->layout_type = LAYOUT_BLOCK_VOLUME; | ||
219 | dev->pages = pages; | ||
220 | dev->pgbase = 0; | ||
221 | dev->pglen = PAGE_SIZE * max_pages; | ||
222 | dev->mincount = 0; | ||
223 | |||
224 | dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data); | ||
225 | rc = nfs4_proc_getdeviceinfo(server, dev); | ||
226 | dprintk("%s getdevice info returns %d\n", __func__, rc); | ||
227 | if (rc) | ||
228 | goto out_free; | ||
229 | |||
230 | rv = nfs4_blk_decode_device(server, dev); | ||
231 | out_free: | ||
232 | for (i = 0; i < max_pages; i++) | ||
233 | __free_page(pages[i]); | ||
234 | kfree(pages); | ||
235 | kfree(dev); | ||
236 | return rv; | ||
237 | } | ||
238 | |||
160 | static int | 239 | static int |
161 | bl_set_layoutdriver(struct nfs_server *server, const struct nfs_fh *fh) | 240 | bl_set_layoutdriver(struct nfs_server *server, const struct nfs_fh *fh) |
162 | { | 241 | { |
242 | struct block_mount_id *b_mt_id = NULL; | ||
243 | struct pnfs_devicelist *dlist = NULL; | ||
244 | struct pnfs_block_dev *bdev; | ||
245 | LIST_HEAD(block_disklist); | ||
246 | int status = 0, i; | ||
247 | |||
163 | dprintk("%s enter\n", __func__); | 248 | dprintk("%s enter\n", __func__); |
164 | return 0; | 249 | |
250 | if (server->pnfs_blksize == 0) { | ||
251 | dprintk("%s Server did not return blksize\n", __func__); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | b_mt_id = kzalloc(sizeof(struct block_mount_id), GFP_NOFS); | ||
255 | if (!b_mt_id) { | ||
256 | status = -ENOMEM; | ||
257 | goto out_error; | ||
258 | } | ||
259 | /* Initialize nfs4 block layout mount id */ | ||
260 | spin_lock_init(&b_mt_id->bm_lock); | ||
261 | INIT_LIST_HEAD(&b_mt_id->bm_devlist); | ||
262 | |||
263 | dlist = kmalloc(sizeof(struct pnfs_devicelist), GFP_NOFS); | ||
264 | if (!dlist) { | ||
265 | status = -ENOMEM; | ||
266 | goto out_error; | ||
267 | } | ||
268 | dlist->eof = 0; | ||
269 | while (!dlist->eof) { | ||
270 | status = nfs4_proc_getdevicelist(server, fh, dlist); | ||
271 | if (status) | ||
272 | goto out_error; | ||
273 | dprintk("%s GETDEVICELIST numdevs=%i, eof=%i\n", | ||
274 | __func__, dlist->num_devs, dlist->eof); | ||
275 | for (i = 0; i < dlist->num_devs; i++) { | ||
276 | bdev = nfs4_blk_get_deviceinfo(server, fh, | ||
277 | &dlist->dev_id[i]); | ||
278 | if (!bdev) { | ||
279 | status = -ENODEV; | ||
280 | goto out_error; | ||
281 | } | ||
282 | spin_lock(&b_mt_id->bm_lock); | ||
283 | list_add(&bdev->bm_node, &b_mt_id->bm_devlist); | ||
284 | spin_unlock(&b_mt_id->bm_lock); | ||
285 | } | ||
286 | } | ||
287 | dprintk("%s SUCCESS\n", __func__); | ||
288 | server->pnfs_ld_data = b_mt_id; | ||
289 | |||
290 | out_return: | ||
291 | kfree(dlist); | ||
292 | return status; | ||
293 | |||
294 | out_error: | ||
295 | free_blk_mountid(b_mt_id); | ||
296 | goto out_return; | ||
165 | } | 297 | } |
166 | 298 | ||
167 | static int | 299 | static int |
168 | bl_clear_layoutdriver(struct nfs_server *server) | 300 | bl_clear_layoutdriver(struct nfs_server *server) |
169 | { | 301 | { |
302 | struct block_mount_id *b_mt_id = server->pnfs_ld_data; | ||
303 | |||
170 | dprintk("%s enter\n", __func__); | 304 | dprintk("%s enter\n", __func__); |
305 | free_blk_mountid(b_mt_id); | ||
306 | dprintk("%s RETURNS\n", __func__); | ||
171 | return 0; | 307 | return 0; |
172 | } | 308 | } |
173 | 309 | ||