diff options
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r-- | drivers/md/dm-ioctl.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 1e03bc89e20f..ac83f5002ce5 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -601,17 +601,27 @@ static void list_version_get_info(struct target_type *tt, void *param) | |||
601 | info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1); | 601 | info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1); |
602 | } | 602 | } |
603 | 603 | ||
604 | static int list_versions(struct file *filp, struct dm_ioctl *param, size_t param_size) | 604 | static int __list_versions(struct dm_ioctl *param, size_t param_size, const char *name) |
605 | { | 605 | { |
606 | size_t len, needed = 0; | 606 | size_t len, needed = 0; |
607 | struct dm_target_versions *vers; | 607 | struct dm_target_versions *vers; |
608 | struct vers_iter iter_info; | 608 | struct vers_iter iter_info; |
609 | struct target_type *tt = NULL; | ||
610 | |||
611 | if (name) { | ||
612 | tt = dm_get_target_type(name); | ||
613 | if (!tt) | ||
614 | return -EINVAL; | ||
615 | } | ||
609 | 616 | ||
610 | /* | 617 | /* |
611 | * Loop through all the devices working out how much | 618 | * Loop through all the devices working out how much |
612 | * space we need. | 619 | * space we need. |
613 | */ | 620 | */ |
614 | dm_target_iterate(list_version_get_needed, &needed); | 621 | if (!tt) |
622 | dm_target_iterate(list_version_get_needed, &needed); | ||
623 | else | ||
624 | list_version_get_needed(tt, &needed); | ||
615 | 625 | ||
616 | /* | 626 | /* |
617 | * Grab our output buffer. | 627 | * Grab our output buffer. |
@@ -632,13 +642,28 @@ static int list_versions(struct file *filp, struct dm_ioctl *param, size_t param | |||
632 | /* | 642 | /* |
633 | * Now loop through filling out the names & versions. | 643 | * Now loop through filling out the names & versions. |
634 | */ | 644 | */ |
635 | dm_target_iterate(list_version_get_info, &iter_info); | 645 | if (!tt) |
646 | dm_target_iterate(list_version_get_info, &iter_info); | ||
647 | else | ||
648 | list_version_get_info(tt, &iter_info); | ||
636 | param->flags |= iter_info.flags; | 649 | param->flags |= iter_info.flags; |
637 | 650 | ||
638 | out: | 651 | out: |
652 | if (tt) | ||
653 | dm_put_target_type(tt); | ||
639 | return 0; | 654 | return 0; |
640 | } | 655 | } |
641 | 656 | ||
657 | static int list_versions(struct file *filp, struct dm_ioctl *param, size_t param_size) | ||
658 | { | ||
659 | return __list_versions(param, param_size, NULL); | ||
660 | } | ||
661 | |||
662 | static int get_target_version(struct file *filp, struct dm_ioctl *param, size_t param_size) | ||
663 | { | ||
664 | return __list_versions(param, param_size, param->name); | ||
665 | } | ||
666 | |||
642 | static int check_name(const char *name) | 667 | static int check_name(const char *name) |
643 | { | 668 | { |
644 | if (strchr(name, '/')) { | 669 | if (strchr(name, '/')) { |
@@ -1592,7 +1617,7 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para | |||
1592 | } | 1617 | } |
1593 | 1618 | ||
1594 | ti = dm_table_find_target(table, tmsg->sector); | 1619 | ti = dm_table_find_target(table, tmsg->sector); |
1595 | if (!dm_target_is_valid(ti)) { | 1620 | if (!ti) { |
1596 | DMWARN("Target message sector outside device."); | 1621 | DMWARN("Target message sector outside device."); |
1597 | r = -EINVAL; | 1622 | r = -EINVAL; |
1598 | } else if (ti->type->message) | 1623 | } else if (ti->type->message) |
@@ -1664,6 +1689,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags) | |||
1664 | {DM_TARGET_MSG_CMD, 0, target_message}, | 1689 | {DM_TARGET_MSG_CMD, 0, target_message}, |
1665 | {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}, | 1690 | {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}, |
1666 | {DM_DEV_ARM_POLL, IOCTL_FLAGS_NO_PARAMS, dev_arm_poll}, | 1691 | {DM_DEV_ARM_POLL, IOCTL_FLAGS_NO_PARAMS, dev_arm_poll}, |
1692 | {DM_GET_TARGET_VERSION, 0, get_target_version}, | ||
1667 | }; | 1693 | }; |
1668 | 1694 | ||
1669 | if (unlikely(cmd >= ARRAY_SIZE(_ioctls))) | 1695 | if (unlikely(cmd >= ARRAY_SIZE(_ioctls))) |