diff options
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r-- | drivers/md/dm-ioctl.c | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 4cacdad2270a..2e9a3ca37bdd 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -128,6 +128,24 @@ static struct hash_cell *__get_uuid_cell(const char *str) | |||
128 | return NULL; | 128 | return NULL; |
129 | } | 129 | } |
130 | 130 | ||
131 | static struct hash_cell *__get_dev_cell(uint64_t dev) | ||
132 | { | ||
133 | struct mapped_device *md; | ||
134 | struct hash_cell *hc; | ||
135 | |||
136 | md = dm_get_md(huge_decode_dev(dev)); | ||
137 | if (!md) | ||
138 | return NULL; | ||
139 | |||
140 | hc = dm_get_mdptr(md); | ||
141 | if (!hc) { | ||
142 | dm_put(md); | ||
143 | return NULL; | ||
144 | } | ||
145 | |||
146 | return hc; | ||
147 | } | ||
148 | |||
131 | /*----------------------------------------------------------------- | 149 | /*----------------------------------------------------------------- |
132 | * Inserting, removing and renaming a device. | 150 | * Inserting, removing and renaming a device. |
133 | *---------------------------------------------------------------*/ | 151 | *---------------------------------------------------------------*/ |
@@ -718,25 +736,45 @@ static int dev_create(struct dm_ioctl *param, size_t param_size) | |||
718 | */ | 736 | */ |
719 | static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) | 737 | static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) |
720 | { | 738 | { |
721 | struct mapped_device *md; | 739 | struct hash_cell *hc = NULL; |
722 | void *mdptr = NULL; | ||
723 | 740 | ||
724 | if (*param->uuid) | 741 | if (*param->uuid) { |
725 | return __get_uuid_cell(param->uuid); | 742 | if (*param->name || param->dev) |
743 | return NULL; | ||
726 | 744 | ||
727 | if (*param->name) | 745 | hc = __get_uuid_cell(param->uuid); |
728 | return __get_name_cell(param->name); | 746 | if (!hc) |
747 | return NULL; | ||
748 | } else if (*param->name) { | ||
749 | if (param->dev) | ||
750 | return NULL; | ||
729 | 751 | ||
730 | md = dm_get_md(huge_decode_dev(param->dev)); | 752 | hc = __get_name_cell(param->name); |
731 | if (!md) | 753 | if (!hc) |
732 | goto out; | 754 | return NULL; |
755 | } else if (param->dev) { | ||
756 | hc = __get_dev_cell(param->dev); | ||
757 | if (!hc) | ||
758 | return NULL; | ||
759 | } else | ||
760 | return NULL; | ||
733 | 761 | ||
734 | mdptr = dm_get_mdptr(md); | 762 | /* |
735 | if (!mdptr) | 763 | * Sneakily write in both the name and the uuid |
736 | dm_put(md); | 764 | * while we have the cell. |
765 | */ | ||
766 | strlcpy(param->name, hc->name, sizeof(param->name)); | ||
767 | if (hc->uuid) | ||
768 | strlcpy(param->uuid, hc->uuid, sizeof(param->uuid)); | ||
769 | else | ||
770 | param->uuid[0] = '\0'; | ||
737 | 771 | ||
738 | out: | 772 | if (hc->new_map) |
739 | return mdptr; | 773 | param->flags |= DM_INACTIVE_PRESENT_FLAG; |
774 | else | ||
775 | param->flags &= ~DM_INACTIVE_PRESENT_FLAG; | ||
776 | |||
777 | return hc; | ||
740 | } | 778 | } |
741 | 779 | ||
742 | static struct mapped_device *find_device(struct dm_ioctl *param) | 780 | static struct mapped_device *find_device(struct dm_ioctl *param) |
@@ -746,24 +784,8 @@ static struct mapped_device *find_device(struct dm_ioctl *param) | |||
746 | 784 | ||
747 | down_read(&_hash_lock); | 785 | down_read(&_hash_lock); |
748 | hc = __find_device_hash_cell(param); | 786 | hc = __find_device_hash_cell(param); |
749 | if (hc) { | 787 | if (hc) |
750 | md = hc->md; | 788 | md = hc->md; |
751 | |||
752 | /* | ||
753 | * Sneakily write in both the name and the uuid | ||
754 | * while we have the cell. | ||
755 | */ | ||
756 | strlcpy(param->name, hc->name, sizeof(param->name)); | ||
757 | if (hc->uuid) | ||
758 | strlcpy(param->uuid, hc->uuid, sizeof(param->uuid)); | ||
759 | else | ||
760 | param->uuid[0] = '\0'; | ||
761 | |||
762 | if (hc->new_map) | ||
763 | param->flags |= DM_INACTIVE_PRESENT_FLAG; | ||
764 | else | ||
765 | param->flags &= ~DM_INACTIVE_PRESENT_FLAG; | ||
766 | } | ||
767 | up_read(&_hash_lock); | 789 | up_read(&_hash_lock); |
768 | 790 | ||
769 | return md; | 791 | return md; |
@@ -1402,6 +1424,11 @@ static int target_message(struct dm_ioctl *param, size_t param_size) | |||
1402 | goto out; | 1424 | goto out; |
1403 | } | 1425 | } |
1404 | 1426 | ||
1427 | if (!argc) { | ||
1428 | DMWARN("Empty message received."); | ||
1429 | goto out; | ||
1430 | } | ||
1431 | |||
1405 | table = dm_get_live_table(md); | 1432 | table = dm_get_live_table(md); |
1406 | if (!table) | 1433 | if (!table) |
1407 | goto out_argv; | 1434 | goto out_argv; |