diff options
author | Mike Snitzer <snitzer@redhat.com> | 2012-03-07 14:09:41 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-03-07 14:09:41 -0500 |
commit | 1f3db25d8be4ac50b897b39609802183ea68a514 (patch) | |
tree | b8e140111ba62062d309ae0dec90543f35e28172 | |
parent | 1212268fd9816e3b8801e57b896fceaec71969ad (diff) |
dm thin metadata: remove incorrect close_device on creation error paths
The __open_device() error paths in __create_thin() and __create_snap()
incorrectly call __close_device() even if td was not initialized by
__open_device(). Remove this.
Also document __open_device() return values, remove a redundant
td->changed = 1 in __create_thin(), and insert an additional
safeguard against creating an already-existing device.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Cc: stable@kernel.org
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r-- | drivers/md/dm-thin-metadata.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 59c4f0446ffa..13d964636d57 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -789,6 +789,11 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd) | |||
789 | return 0; | 789 | return 0; |
790 | } | 790 | } |
791 | 791 | ||
792 | /* | ||
793 | * __open_device: Returns @td corresponding to device with id @dev, | ||
794 | * creating it if @create is set and incrementing @td->open_count. | ||
795 | * On failure, @td is undefined. | ||
796 | */ | ||
792 | static int __open_device(struct dm_pool_metadata *pmd, | 797 | static int __open_device(struct dm_pool_metadata *pmd, |
793 | dm_thin_id dev, int create, | 798 | dm_thin_id dev, int create, |
794 | struct dm_thin_device **td) | 799 | struct dm_thin_device **td) |
@@ -799,10 +804,16 @@ static int __open_device(struct dm_pool_metadata *pmd, | |||
799 | struct disk_device_details details_le; | 804 | struct disk_device_details details_le; |
800 | 805 | ||
801 | /* | 806 | /* |
802 | * Check the device isn't already open. | 807 | * If the device is already open, return it. |
803 | */ | 808 | */ |
804 | list_for_each_entry(td2, &pmd->thin_devices, list) | 809 | list_for_each_entry(td2, &pmd->thin_devices, list) |
805 | if (td2->id == dev) { | 810 | if (td2->id == dev) { |
811 | /* | ||
812 | * May not create an already-open device. | ||
813 | */ | ||
814 | if (create) | ||
815 | return -EEXIST; | ||
816 | |||
806 | td2->open_count++; | 817 | td2->open_count++; |
807 | *td = td2; | 818 | *td = td2; |
808 | return 0; | 819 | return 0; |
@@ -817,6 +828,9 @@ static int __open_device(struct dm_pool_metadata *pmd, | |||
817 | if (r != -ENODATA || !create) | 828 | if (r != -ENODATA || !create) |
818 | return r; | 829 | return r; |
819 | 830 | ||
831 | /* | ||
832 | * Create new device. | ||
833 | */ | ||
820 | changed = 1; | 834 | changed = 1; |
821 | details_le.mapped_blocks = 0; | 835 | details_le.mapped_blocks = 0; |
822 | details_le.transaction_id = cpu_to_le64(pmd->trans_id); | 836 | details_le.transaction_id = cpu_to_le64(pmd->trans_id); |
@@ -882,12 +896,10 @@ static int __create_thin(struct dm_pool_metadata *pmd, | |||
882 | 896 | ||
883 | r = __open_device(pmd, dev, 1, &td); | 897 | r = __open_device(pmd, dev, 1, &td); |
884 | if (r) { | 898 | if (r) { |
885 | __close_device(td); | ||
886 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); | 899 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); |
887 | dm_btree_del(&pmd->bl_info, dev_root); | 900 | dm_btree_del(&pmd->bl_info, dev_root); |
888 | return r; | 901 | return r; |
889 | } | 902 | } |
890 | td->changed = 1; | ||
891 | __close_device(td); | 903 | __close_device(td); |
892 | 904 | ||
893 | return r; | 905 | return r; |
@@ -967,14 +979,14 @@ static int __create_snap(struct dm_pool_metadata *pmd, | |||
967 | goto bad; | 979 | goto bad; |
968 | 980 | ||
969 | r = __set_snapshot_details(pmd, td, origin, pmd->time); | 981 | r = __set_snapshot_details(pmd, td, origin, pmd->time); |
982 | __close_device(td); | ||
983 | |||
970 | if (r) | 984 | if (r) |
971 | goto bad; | 985 | goto bad; |
972 | 986 | ||
973 | __close_device(td); | ||
974 | return 0; | 987 | return 0; |
975 | 988 | ||
976 | bad: | 989 | bad: |
977 | __close_device(td); | ||
978 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); | 990 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); |
979 | dm_btree_remove(&pmd->details_info, pmd->details_root, | 991 | dm_btree_remove(&pmd->details_info, pmd->details_root, |
980 | &key, &pmd->details_root); | 992 | &key, &pmd->details_root); |