Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 273318
b: refs/heads/master
c: 36a0456
h: refs/heads/master
v: v3
  • Loading branch information
Alasdair G Kergon committed Oct 31, 2011
1 parent 4297d27 commit 28b64a0
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cc6cbe141a20f6d876b161b60af38d93935bfa85
refs/heads/master: 36a0456fbf2d9680bf9af81b39daf4a8e22cb1b8
11 changes: 11 additions & 0 deletions trunk/drivers/md/dm-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
struct hash_cell *hc;
struct dm_table *t;
struct mapped_device *md;
struct target_type *immutable_target_type;

md = find_device(param);
if (!md)
Expand All @@ -1230,6 +1231,16 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
goto out;
}

immutable_target_type = dm_get_immutable_target_type(md);
if (immutable_target_type &&
(immutable_target_type != dm_table_get_immutable_target_type(t))) {
DMWARN("can't replace immutable target type %s",
immutable_target_type->name);
dm_table_destroy(t);
r = -EINVAL;
goto out;
}

/* Protect md->type and md->queue against concurrent table loads. */
dm_lock_md_type(md);
if (dm_get_md_type(md) == DM_TYPE_NONE)
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/md/dm-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct dm_table {
sector_t *highs;
struct dm_target *targets;

struct target_type *immutable_target_type;
unsigned integrity_supported:1;
unsigned singleton:1;

Expand Down Expand Up @@ -780,6 +781,21 @@ int dm_table_add_target(struct dm_table *t, const char *type,
return -EINVAL;
}

if (t->immutable_target_type) {
if (t->immutable_target_type != tgt->type) {
DMERR("%s: immutable target type %s cannot be mixed with other target types",
dm_device_name(t->md), t->immutable_target_type->name);
return -EINVAL;
}
} else if (dm_target_is_immutable(tgt->type)) {
if (t->num_targets) {
DMERR("%s: immutable target type %s cannot be mixed with other target types",
dm_device_name(t->md), tgt->type->name);
return -EINVAL;
}
t->immutable_target_type = tgt->type;
}

tgt->table = t;
tgt->begin = start;
tgt->len = len;
Expand Down Expand Up @@ -937,6 +953,11 @@ unsigned dm_table_get_type(struct dm_table *t)
return t->type;
}

struct target_type *dm_table_get_immutable_target_type(struct dm_table *t)
{
return t->immutable_target_type;
}

bool dm_table_request_based(struct dm_table *t)
{
return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED;
Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ struct mapped_device {
/* Protect queue and type against concurrent access. */
struct mutex type_lock;

struct target_type *immutable_target_type;

struct gendisk *disk;
char name[16];

Expand Down Expand Up @@ -2096,6 +2098,8 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
write_lock_irqsave(&md->map_lock, flags);
old_map = md->map;
md->map = t;
md->immutable_target_type = dm_table_get_immutable_target_type(t);

dm_table_set_restrictions(t, q, limits);
if (merge_is_optional)
set_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
Expand Down Expand Up @@ -2166,6 +2170,11 @@ unsigned dm_get_md_type(struct mapped_device *md)
return md->type;
}

struct target_type *dm_get_immutable_target_type(struct mapped_device *md)
{
return md->immutable_target_type;
}

/*
* Fully initialize a request-based queue (->elevator, ->request_fn, etc).
*/
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/md/dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ int dm_table_resume_targets(struct dm_table *t);
int dm_table_any_congested(struct dm_table *t, int bdi_bits);
int dm_table_any_busy_target(struct dm_table *t);
unsigned dm_table_get_type(struct dm_table *t);
struct target_type *dm_table_get_immutable_target_type(struct dm_table *t);
bool dm_table_request_based(struct dm_table *t);
bool dm_table_supports_discards(struct dm_table *t);
int dm_table_alloc_md_mempools(struct dm_table *t);
Expand All @@ -72,6 +73,7 @@ void dm_lock_md_type(struct mapped_device *md);
void dm_unlock_md_type(struct mapped_device *md);
void dm_set_md_type(struct mapped_device *md, unsigned type);
unsigned dm_get_md_type(struct mapped_device *md);
struct target_type *dm_get_immutable_target_type(struct mapped_device *md);

int dm_setup_md_queue(struct mapped_device *md);

Expand Down
7 changes: 7 additions & 0 deletions trunk/include/linux/device-mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ struct target_type {
#define dm_target_always_writeable(type) \
((type)->features & DM_TARGET_ALWAYS_WRITEABLE)

/*
* Any device that contains a table with an instance of this target may never
* have tables containing any different target type.
*/
#define DM_TARGET_IMMUTABLE 0x00000004
#define dm_target_is_immutable(type) ((type)->features & DM_TARGET_IMMUTABLE)

struct dm_target {
struct dm_table *table;
struct target_type *type;
Expand Down
4 changes: 2 additions & 2 deletions trunk/include/linux/dm-ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@ enum {
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)

#define DM_VERSION_MAJOR 4
#define DM_VERSION_MINOR 21
#define DM_VERSION_MINOR 22
#define DM_VERSION_PATCHLEVEL 0
#define DM_VERSION_EXTRA "-ioctl (2011-07-06)"
#define DM_VERSION_EXTRA "-ioctl (2011-10-19)"

/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
Expand Down

0 comments on commit 28b64a0

Please sign in to comment.