Commit 3cb6ce4f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] dm: Repair persistent minors

From: Joe Thornber <thornber@sistina.com>

Split the dm_create() function into two variants, depending on whether you
want the device to have a specific minor number.  This avoids the broken
overloading of the minor argument to the old dm_create().
parent 9cde68fc
...@@ -560,7 +560,6 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -560,7 +560,6 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
int r; int r;
struct dm_table *t; struct dm_table *t;
struct mapped_device *md; struct mapped_device *md;
unsigned int minor = 0;
r = check_name(param->name); r = check_name(param->name);
if (r) if (r)
...@@ -577,9 +576,10 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -577,9 +576,10 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
} }
if (param->flags & DM_PERSISTENT_DEV_FLAG) if (param->flags & DM_PERSISTENT_DEV_FLAG)
minor = minor(to_kdev_t(param->dev)); r = dm_create_with_minor(minor(to_kdev_t(param->dev)), t, &md);
else
r = dm_create(t, &md);
r = dm_create(minor, t, &md);
if (r) { if (r) {
dm_table_put(t); dm_table_put(t);
return r; return r;
......
...@@ -569,7 +569,7 @@ static int next_free_minor(unsigned int *minor) ...@@ -569,7 +569,7 @@ static int next_free_minor(unsigned int *minor)
/* /*
* Allocate and initialise a blank device with a given minor. * Allocate and initialise a blank device with a given minor.
*/ */
static struct mapped_device *alloc_dev(unsigned int minor) static struct mapped_device *alloc_dev(unsigned int minor, int persistent)
{ {
int r; int r;
struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL);
...@@ -580,7 +580,7 @@ static struct mapped_device *alloc_dev(unsigned int minor) ...@@ -580,7 +580,7 @@ static struct mapped_device *alloc_dev(unsigned int minor)
} }
/* get a minor number for the dev */ /* get a minor number for the dev */
r = (minor < 0) ? next_free_minor(&minor) : specific_minor(minor); r = persistent ? specific_minor(minor) : next_free_minor(&minor);
if (r < 0) { if (r < 0) {
kfree(md); kfree(md);
return NULL; return NULL;
...@@ -660,13 +660,13 @@ static void __unbind(struct mapped_device *md) ...@@ -660,13 +660,13 @@ static void __unbind(struct mapped_device *md)
/* /*
* Constructor for a new device. * Constructor for a new device.
*/ */
int dm_create(unsigned int minor, struct dm_table *table, static int create_aux(unsigned int minor, int persistent,
struct mapped_device **result) struct dm_table *table, struct mapped_device **result)
{ {
int r; int r;
struct mapped_device *md; struct mapped_device *md;
md = alloc_dev(minor); md = alloc_dev(minor, persistent);
if (!md) if (!md)
return -ENXIO; return -ENXIO;
...@@ -681,6 +681,17 @@ int dm_create(unsigned int minor, struct dm_table *table, ...@@ -681,6 +681,17 @@ int dm_create(unsigned int minor, struct dm_table *table,
return 0; return 0;
} }
int dm_create(struct dm_table *table, struct mapped_device **result)
{
return create_aux(0, 0, table, result);
}
int dm_create_with_minor(unsigned int minor,
struct dm_table *table, struct mapped_device **result)
{
return create_aux(minor, 1, table, result);
}
void dm_get(struct mapped_device *md) void dm_get(struct mapped_device *md)
{ {
atomic_inc(&md->holders); atomic_inc(&md->holders);
......
...@@ -51,8 +51,9 @@ struct mapped_device; ...@@ -51,8 +51,9 @@ struct mapped_device;
* Functions for manipulating a struct mapped_device. * Functions for manipulating a struct mapped_device.
* Drop the reference with dm_put when you finish with the object. * Drop the reference with dm_put when you finish with the object.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
int dm_create(unsigned int minor, struct dm_table *table, int dm_create(struct dm_table *table, struct mapped_device **md);
struct mapped_device **md); int dm_create_with_minor(unsigned int minor, struct dm_table *table,
struct mapped_device **md);
/* /*
* Reference counting for md. * Reference counting for md.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment