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.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}