aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/user.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm/user.c')
-rw-r--r--fs/dlm/user.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 34f14a14fb4e..6542110c0da4 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. 2 * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
3 * 3 *
4 * This copyrighted material is made available to anyone wishing to use, 4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions 5 * modify, copy, or redistribute it subject to the terms and conditions
@@ -340,10 +340,15 @@ static int device_user_deadlock(struct dlm_user_proc *proc,
340 return error; 340 return error;
341} 341}
342 342
343static int create_misc_device(struct dlm_ls *ls, char *name) 343static int dlm_device_register(struct dlm_ls *ls, char *name)
344{ 344{
345 int error, len; 345 int error, len;
346 346
347 /* The device is already registered. This happens when the
348 lockspace is created multiple times from userspace. */
349 if (ls->ls_device.name)
350 return 0;
351
347 error = -ENOMEM; 352 error = -ENOMEM;
348 len = strlen(name) + strlen(name_prefix) + 2; 353 len = strlen(name) + strlen(name_prefix) + 2;
349 ls->ls_device.name = kzalloc(len, GFP_KERNEL); 354 ls->ls_device.name = kzalloc(len, GFP_KERNEL);
@@ -363,6 +368,22 @@ fail:
363 return error; 368 return error;
364} 369}
365 370
371int dlm_device_deregister(struct dlm_ls *ls)
372{
373 int error;
374
375 /* The device is not registered. This happens when the lockspace
376 was never used from userspace, or when device_create_lockspace()
377 calls dlm_release_lockspace() after the register fails. */
378 if (!ls->ls_device.name)
379 return 0;
380
381 error = misc_deregister(&ls->ls_device);
382 if (!error)
383 kfree(ls->ls_device.name);
384 return error;
385}
386
366static int device_user_purge(struct dlm_user_proc *proc, 387static int device_user_purge(struct dlm_user_proc *proc,
367 struct dlm_purge_params *params) 388 struct dlm_purge_params *params)
368{ 389{
@@ -397,7 +418,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
397 if (!ls) 418 if (!ls)
398 return -ENOENT; 419 return -ENOENT;
399 420
400 error = create_misc_device(ls, params->name); 421 error = dlm_device_register(ls, params->name);
401 dlm_put_lockspace(ls); 422 dlm_put_lockspace(ls);
402 423
403 if (error) 424 if (error)
@@ -421,31 +442,22 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
421 if (!ls) 442 if (!ls)
422 return -ENOENT; 443 return -ENOENT;
423 444
424 /* Deregister the misc device first, so we don't have
425 * a device that's not attached to a lockspace. If
426 * dlm_release_lockspace fails then we can recreate it
427 */
428 error = misc_deregister(&ls->ls_device);
429 if (error) {
430 dlm_put_lockspace(ls);
431 goto out;
432 }
433 kfree(ls->ls_device.name);
434
435 if (params->flags & DLM_USER_LSFLG_FORCEFREE) 445 if (params->flags & DLM_USER_LSFLG_FORCEFREE)
436 force = 2; 446 force = 2;
437 447
438 lockspace = ls->ls_local_handle; 448 lockspace = ls->ls_local_handle;
449 dlm_put_lockspace(ls);
439 450
440 /* dlm_release_lockspace waits for references to go to zero, 451 /* The final dlm_release_lockspace waits for references to go to
441 so all processes will need to close their device for the ls 452 zero, so all processes will need to close their device for the
442 before the release will procede */ 453 ls before the release will proceed. release also calls the
454 device_deregister above. Converting a positive return value
455 from release to zero means that userspace won't know when its
456 release was the final one, but it shouldn't need to know. */
443 457
444 dlm_put_lockspace(ls);
445 error = dlm_release_lockspace(lockspace, force); 458 error = dlm_release_lockspace(lockspace, force);
446 if (error) 459 if (error > 0)
447 create_misc_device(ls, ls->ls_name); 460 error = 0;
448 out:
449 return error; 461 return error;
450} 462}
451 463