aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
authorPatrick Caulfield <pcaulfie@redhat.com>2007-03-21 05:23:53 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-05-01 04:10:44 -0400
commit254da030dfb1b13d42d07e4292a4790d88c6874f (patch)
tree8c8f34d6b33232f8081fff6842930d55b2b41140 /fs/dlm
parent420d2a1028b906f24e836e37089a6ad55ab1848f (diff)
[DLM] Don't delete misc device if lockspace removal fails
Currently if the lockspace removal fails the misc device associated with a lockspace is left deleted. After that there is no way to access the orphaned lockspace from userland. This patch recreates the misc device if th dlm_release_lockspace fails. I believe this is better than attempting to remove the lockspace first because that leaves an unattached device lying around. The potential gap in which there is no access to the lockspace between removing the misc device and recreating it is acceptable ... after all the application is trying to remove it, and only new users of the lockspace will be affected. Signed-Off-By: Patrick Caulfield <pcaulfie@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/user.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 3870150b83a4..27a75ce571cf 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -286,11 +286,34 @@ static int device_user_unlock(struct dlm_user_proc *proc,
286 return error; 286 return error;
287} 287}
288 288
289static int create_misc_device(struct dlm_ls *ls, char *name)
290{
291 int error, len;
292
293 error = -ENOMEM;
294 len = strlen(name) + strlen(name_prefix) + 2;
295 ls->ls_device.name = kzalloc(len, GFP_KERNEL);
296 if (!ls->ls_device.name)
297 goto fail;
298
299 snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
300 name);
301 ls->ls_device.fops = &device_fops;
302 ls->ls_device.minor = MISC_DYNAMIC_MINOR;
303
304 error = misc_register(&ls->ls_device);
305 if (error) {
306 kfree(ls->ls_device.name);
307 }
308fail:
309 return error;
310}
311
289static int device_create_lockspace(struct dlm_lspace_params *params) 312static int device_create_lockspace(struct dlm_lspace_params *params)
290{ 313{
291 dlm_lockspace_t *lockspace; 314 dlm_lockspace_t *lockspace;
292 struct dlm_ls *ls; 315 struct dlm_ls *ls;
293 int error, len; 316 int error;
294 317
295 if (!capable(CAP_SYS_ADMIN)) 318 if (!capable(CAP_SYS_ADMIN))
296 return -EPERM; 319 return -EPERM;
@@ -304,29 +327,14 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
304 if (!ls) 327 if (!ls)
305 return -ENOENT; 328 return -ENOENT;
306 329
307 error = -ENOMEM; 330 error = create_misc_device(ls, params->name);
308 len = strlen(params->name) + strlen(name_prefix) + 2;
309 ls->ls_device.name = kzalloc(len, GFP_KERNEL);
310 if (!ls->ls_device.name)
311 goto fail;
312 snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
313 params->name);
314 ls->ls_device.fops = &device_fops;
315 ls->ls_device.minor = MISC_DYNAMIC_MINOR;
316
317 error = misc_register(&ls->ls_device);
318 if (error) {
319 kfree(ls->ls_device.name);
320 goto fail;
321 }
322
323 error = ls->ls_device.minor;
324 dlm_put_lockspace(ls); 331 dlm_put_lockspace(ls);
325 return error;
326 332
327 fail: 333 if (error)
328 dlm_put_lockspace(ls); 334 dlm_release_lockspace(lockspace, 0);
329 dlm_release_lockspace(lockspace, 0); 335 else
336 error = ls->ls_device.minor;
337
330 return error; 338 return error;
331} 339}
332 340
@@ -343,6 +351,10 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
343 if (!ls) 351 if (!ls)
344 return -ENOENT; 352 return -ENOENT;
345 353
354 /* Deregister the misc device first, so we don't have
355 * a device that's not attached to a lockspace. If
356 * dlm_release_lockspace fails then we can recreate it
357 */
346 error = misc_deregister(&ls->ls_device); 358 error = misc_deregister(&ls->ls_device);
347 if (error) { 359 if (error) {
348 dlm_put_lockspace(ls); 360 dlm_put_lockspace(ls);
@@ -361,6 +373,8 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
361 373
362 dlm_put_lockspace(ls); 374 dlm_put_lockspace(ls);
363 error = dlm_release_lockspace(lockspace, force); 375 error = dlm_release_lockspace(lockspace, force);
376 if (error)
377 create_misc_device(ls, ls->ls_name);
364 out: 378 out:
365 return error; 379 return error;
366} 380}