diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 20:02:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 20:02:37 -0400 |
commit | 43672a0784707d795556b1f93925da8b8e797d03 (patch) | |
tree | 5c92aabd211281300f89fc2e69e9ee7e58bcc449 /drivers/md/dm-table.c | |
parent | 2380078cdb7e6d520e33dcf834e0be979d542e48 (diff) | |
parent | 2e727c3ca1beff05f27b6207a795790f222bf8d8 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/linux-dm
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/linux-dm:
dm: raid fix device status indicator when array initializing
dm log userspace: add log device dependency
dm log userspace: fix comment hyphens
dm: add thin provisioning target
dm: add persistent data library
dm: add bufio
dm: export dm get md
dm table: add immutable feature
dm table: add always writeable feature
dm table: add singleton feature
dm kcopyd: add dm_kcopyd_zero to zero an area
dm: remove superfluous smp_mb
dm: use local printk ratelimit
dm table: propagate non rotational flag
Diffstat (limited to 'drivers/md/dm-table.c')
-rw-r--r-- | drivers/md/dm-table.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index bc04518e9d8..8e913213014 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -54,7 +54,9 @@ struct dm_table { | |||
54 | sector_t *highs; | 54 | sector_t *highs; |
55 | struct dm_target *targets; | 55 | struct dm_target *targets; |
56 | 56 | ||
57 | struct target_type *immutable_target_type; | ||
57 | unsigned integrity_supported:1; | 58 | unsigned integrity_supported:1; |
59 | unsigned singleton:1; | ||
58 | 60 | ||
59 | /* | 61 | /* |
60 | * Indicates the rw permissions for the new logical | 62 | * Indicates the rw permissions for the new logical |
@@ -740,6 +742,12 @@ int dm_table_add_target(struct dm_table *t, const char *type, | |||
740 | char **argv; | 742 | char **argv; |
741 | struct dm_target *tgt; | 743 | struct dm_target *tgt; |
742 | 744 | ||
745 | if (t->singleton) { | ||
746 | DMERR("%s: target type %s must appear alone in table", | ||
747 | dm_device_name(t->md), t->targets->type->name); | ||
748 | return -EINVAL; | ||
749 | } | ||
750 | |||
743 | if ((r = check_space(t))) | 751 | if ((r = check_space(t))) |
744 | return r; | 752 | return r; |
745 | 753 | ||
@@ -758,6 +766,36 @@ int dm_table_add_target(struct dm_table *t, const char *type, | |||
758 | return -EINVAL; | 766 | return -EINVAL; |
759 | } | 767 | } |
760 | 768 | ||
769 | if (dm_target_needs_singleton(tgt->type)) { | ||
770 | if (t->num_targets) { | ||
771 | DMERR("%s: target type %s must appear alone in table", | ||
772 | dm_device_name(t->md), type); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | t->singleton = 1; | ||
776 | } | ||
777 | |||
778 | if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) { | ||
779 | DMERR("%s: target type %s may not be included in read-only tables", | ||
780 | dm_device_name(t->md), type); | ||
781 | return -EINVAL; | ||
782 | } | ||
783 | |||
784 | if (t->immutable_target_type) { | ||
785 | if (t->immutable_target_type != tgt->type) { | ||
786 | DMERR("%s: immutable target type %s cannot be mixed with other target types", | ||
787 | dm_device_name(t->md), t->immutable_target_type->name); | ||
788 | return -EINVAL; | ||
789 | } | ||
790 | } else if (dm_target_is_immutable(tgt->type)) { | ||
791 | if (t->num_targets) { | ||
792 | DMERR("%s: immutable target type %s cannot be mixed with other target types", | ||
793 | dm_device_name(t->md), tgt->type->name); | ||
794 | return -EINVAL; | ||
795 | } | ||
796 | t->immutable_target_type = tgt->type; | ||
797 | } | ||
798 | |||
761 | tgt->table = t; | 799 | tgt->table = t; |
762 | tgt->begin = start; | 800 | tgt->begin = start; |
763 | tgt->len = len; | 801 | tgt->len = len; |
@@ -915,6 +953,11 @@ unsigned dm_table_get_type(struct dm_table *t) | |||
915 | return t->type; | 953 | return t->type; |
916 | } | 954 | } |
917 | 955 | ||
956 | struct target_type *dm_table_get_immutable_target_type(struct dm_table *t) | ||
957 | { | ||
958 | return t->immutable_target_type; | ||
959 | } | ||
960 | |||
918 | bool dm_table_request_based(struct dm_table *t) | 961 | bool dm_table_request_based(struct dm_table *t) |
919 | { | 962 | { |
920 | return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED; | 963 | return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED; |
@@ -1299,6 +1342,31 @@ static bool dm_table_discard_zeroes_data(struct dm_table *t) | |||
1299 | return 1; | 1342 | return 1; |
1300 | } | 1343 | } |
1301 | 1344 | ||
1345 | static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev, | ||
1346 | sector_t start, sector_t len, void *data) | ||
1347 | { | ||
1348 | struct request_queue *q = bdev_get_queue(dev->bdev); | ||
1349 | |||
1350 | return q && blk_queue_nonrot(q); | ||
1351 | } | ||
1352 | |||
1353 | static bool dm_table_is_nonrot(struct dm_table *t) | ||
1354 | { | ||
1355 | struct dm_target *ti; | ||
1356 | unsigned i = 0; | ||
1357 | |||
1358 | /* Ensure that all underlying device are non-rotational. */ | ||
1359 | while (i < dm_table_get_num_targets(t)) { | ||
1360 | ti = dm_table_get_target(t, i++); | ||
1361 | |||
1362 | if (!ti->type->iterate_devices || | ||
1363 | !ti->type->iterate_devices(ti, device_is_nonrot, NULL)) | ||
1364 | return 0; | ||
1365 | } | ||
1366 | |||
1367 | return 1; | ||
1368 | } | ||
1369 | |||
1302 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | 1370 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
1303 | struct queue_limits *limits) | 1371 | struct queue_limits *limits) |
1304 | { | 1372 | { |
@@ -1324,6 +1392,11 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
1324 | if (!dm_table_discard_zeroes_data(t)) | 1392 | if (!dm_table_discard_zeroes_data(t)) |
1325 | q->limits.discard_zeroes_data = 0; | 1393 | q->limits.discard_zeroes_data = 0; |
1326 | 1394 | ||
1395 | if (dm_table_is_nonrot(t)) | ||
1396 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); | ||
1397 | else | ||
1398 | queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); | ||
1399 | |||
1327 | dm_table_set_integrity(t); | 1400 | dm_table_set_integrity(t); |
1328 | 1401 | ||
1329 | /* | 1402 | /* |