aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-ioctl.c
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2009-12-10 18:52:22 -0500
committerAlasdair G Kergon <agk@redhat.com>2009-12-10 18:52:22 -0500
commit1d0f3ce83200edc5d43723c77c62b09ad6560294 (patch)
treedd7f0306c14334d8cb2fbcabe18243c94da4b869 /drivers/md/dm-ioctl.c
parent12fc0f49dc994d8d90dcf3df13f5b1ee5441288d (diff)
dm ioctl: retrieve status from inactive table
Add the flag DM_QUERY_INACTIVE_TABLE_FLAG to the ioctls to return infomation about the loaded-but-not-yet-active table instead of the live table. Prior to this patch it was impossible to obtain this information until the device had been 'resumed'. Userspace dmsetup and libdevmapper support the flag as of version 1.02.40. e.g. dmsetup info --inactive vg1-lv1 Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r--drivers/md/dm-ioctl.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index d06dd39856f3..a3d20265ffc1 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -523,8 +523,6 @@ static int list_versions(struct dm_ioctl *param, size_t param_size)
523 return 0; 523 return 0;
524} 524}
525 525
526
527
528static int check_name(const char *name) 526static int check_name(const char *name)
529{ 527{
530 if (strchr(name, '/')) { 528 if (strchr(name, '/')) {
@@ -536,6 +534,40 @@ static int check_name(const char *name)
536} 534}
537 535
538/* 536/*
537 * On successful return, the caller must not attempt to acquire
538 * _hash_lock without first calling dm_table_put, because dm_table_destroy
539 * waits for this dm_table_put and could be called under this lock.
540 */
541static struct dm_table *dm_get_inactive_table(struct mapped_device *md)
542{
543 struct hash_cell *hc;
544 struct dm_table *table = NULL;
545
546 down_read(&_hash_lock);
547 hc = dm_get_mdptr(md);
548 if (!hc || hc->md != md) {
549 DMWARN("device has been removed from the dev hash table.");
550 goto out;
551 }
552
553 table = hc->new_map;
554 if (table)
555 dm_table_get(table);
556
557out:
558 up_read(&_hash_lock);
559
560 return table;
561}
562
563static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md,
564 struct dm_ioctl *param)
565{
566 return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ?
567 dm_get_inactive_table(md) : dm_get_live_table(md);
568}
569
570/*
539 * Fills in a dm_ioctl structure, ready for sending back to 571 * Fills in a dm_ioctl structure, ready for sending back to
540 * userland. 572 * userland.
541 */ 573 */
@@ -559,18 +591,30 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
559 */ 591 */
560 param->open_count = dm_open_count(md); 592 param->open_count = dm_open_count(md);
561 593
562 if (get_disk_ro(disk))
563 param->flags |= DM_READONLY_FLAG;
564
565 param->event_nr = dm_get_event_nr(md); 594 param->event_nr = dm_get_event_nr(md);
595 param->target_count = 0;
566 596
567 table = dm_get_live_table(md); 597 table = dm_get_live_table(md);
568 if (table) { 598 if (table) {
569 param->flags |= DM_ACTIVE_PRESENT_FLAG; 599 if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) {
570 param->target_count = dm_table_get_num_targets(table); 600 if (get_disk_ro(disk))
601 param->flags |= DM_READONLY_FLAG;
602 param->target_count = dm_table_get_num_targets(table);
603 }
571 dm_table_put(table); 604 dm_table_put(table);
572 } else 605
573 param->target_count = 0; 606 param->flags |= DM_ACTIVE_PRESENT_FLAG;
607 }
608
609 if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) {
610 table = dm_get_inactive_table(md);
611 if (table) {
612 if (!(dm_table_get_mode(table) & FMODE_WRITE))
613 param->flags |= DM_READONLY_FLAG;
614 param->target_count = dm_table_get_num_targets(table);
615 dm_table_put(table);
616 }
617 }
574 618
575 return 0; 619 return 0;
576} 620}
@@ -993,7 +1037,7 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
993 if (r) 1037 if (r)
994 goto out; 1038 goto out;
995 1039
996 table = dm_get_live_table(md); 1040 table = dm_get_live_or_inactive_table(md, param);
997 if (table) { 1041 if (table) {
998 retrieve_status(table, param, param_size); 1042 retrieve_status(table, param, param_size);
999 dm_table_put(table); 1043 dm_table_put(table);
@@ -1226,7 +1270,7 @@ static int table_deps(struct dm_ioctl *param, size_t param_size)
1226 if (r) 1270 if (r)
1227 goto out; 1271 goto out;
1228 1272
1229 table = dm_get_live_table(md); 1273 table = dm_get_live_or_inactive_table(md, param);
1230 if (table) { 1274 if (table) {
1231 retrieve_deps(table, param, param_size); 1275 retrieve_deps(table, param, param_size);
1232 dm_table_put(table); 1276 dm_table_put(table);
@@ -1255,13 +1299,13 @@ static int table_status(struct dm_ioctl *param, size_t param_size)
1255 if (r) 1299 if (r)
1256 goto out; 1300 goto out;
1257 1301
1258 table = dm_get_live_table(md); 1302 table = dm_get_live_or_inactive_table(md, param);
1259 if (table) { 1303 if (table) {
1260 retrieve_status(table, param, param_size); 1304 retrieve_status(table, param, param_size);
1261 dm_table_put(table); 1305 dm_table_put(table);
1262 } 1306 }
1263 1307
1264 out: 1308out:
1265 dm_put(md); 1309 dm_put(md);
1266 return r; 1310 return r;
1267} 1311}