diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-14 22:07:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-14 22:07:45 -0400 |
commit | 63a1281b651b8ebc04c829254c62bd6fbaf83eb0 (patch) | |
tree | f639dd846e758e1a30c972e3feda79be092e2a1d | |
parent | 0a3f5af188c4f7df44517e50bee4dbf87c256813 (diff) | |
parent | 9567366fefddeaea4ed1d713270535d93a3b3c76 (diff) |
Merge tag 'dm-4.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer:
- fix a 4.6-rc1 bio-based DM 'struct dm_target_io' leak in an error
path
- stable@ fix for DM cache metadata's READ_LOCK macros that were
incorrectly returning error if the block manager was in read-only
mode; also cleanup multi-statement macros to use do {} while(0)
* tag 'dm-4.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm cache metadata: fix READ_LOCK macros and cleanup WRITE_LOCK macros
dm: fix dm_target_io leak if clone_bio() returns an error
-rw-r--r-- | drivers/md/dm-cache-metadata.c | 64 | ||||
-rw-r--r-- | drivers/md/dm.c | 4 |
2 files changed, 43 insertions, 25 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 27f2ef300f8b..65ce6985f87a 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c | |||
@@ -867,39 +867,55 @@ static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd, | |||
867 | return 0; | 867 | return 0; |
868 | } | 868 | } |
869 | 869 | ||
870 | #define WRITE_LOCK(cmd) \ | 870 | static bool cmd_write_lock(struct dm_cache_metadata *cmd) |
871 | down_write(&cmd->root_lock); \ | 871 | { |
872 | if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | 872 | down_write(&cmd->root_lock); |
873 | up_write(&cmd->root_lock); \ | 873 | if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { |
874 | return -EINVAL; \ | 874 | up_write(&cmd->root_lock); |
875 | return false; | ||
875 | } | 876 | } |
877 | return true; | ||
878 | } | ||
876 | 879 | ||
877 | #define WRITE_LOCK_VOID(cmd) \ | 880 | #define WRITE_LOCK(cmd) \ |
878 | down_write(&cmd->root_lock); \ | 881 | do { \ |
879 | if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | 882 | if (!cmd_write_lock((cmd))) \ |
880 | up_write(&cmd->root_lock); \ | 883 | return -EINVAL; \ |
881 | return; \ | 884 | } while(0) |
882 | } | 885 | |
886 | #define WRITE_LOCK_VOID(cmd) \ | ||
887 | do { \ | ||
888 | if (!cmd_write_lock((cmd))) \ | ||
889 | return; \ | ||
890 | } while(0) | ||
883 | 891 | ||
884 | #define WRITE_UNLOCK(cmd) \ | 892 | #define WRITE_UNLOCK(cmd) \ |
885 | up_write(&cmd->root_lock) | 893 | up_write(&(cmd)->root_lock) |
886 | 894 | ||
887 | #define READ_LOCK(cmd) \ | 895 | static bool cmd_read_lock(struct dm_cache_metadata *cmd) |
888 | down_read(&cmd->root_lock); \ | 896 | { |
889 | if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | 897 | down_write(&cmd->root_lock); |
890 | up_read(&cmd->root_lock); \ | 898 | if (cmd->fail_io) { |
891 | return -EINVAL; \ | 899 | up_write(&cmd->root_lock); |
900 | return false; | ||
892 | } | 901 | } |
902 | return true; | ||
903 | } | ||
893 | 904 | ||
894 | #define READ_LOCK_VOID(cmd) \ | 905 | #define READ_LOCK(cmd) \ |
895 | down_read(&cmd->root_lock); \ | 906 | do { \ |
896 | if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | 907 | if (!cmd_read_lock((cmd))) \ |
897 | up_read(&cmd->root_lock); \ | 908 | return -EINVAL; \ |
898 | return; \ | 909 | } while(0) |
899 | } | 910 | |
911 | #define READ_LOCK_VOID(cmd) \ | ||
912 | do { \ | ||
913 | if (!cmd_read_lock((cmd))) \ | ||
914 | return; \ | ||
915 | } while(0) | ||
900 | 916 | ||
901 | #define READ_UNLOCK(cmd) \ | 917 | #define READ_UNLOCK(cmd) \ |
902 | up_read(&cmd->root_lock) | 918 | up_read(&(cmd)->root_lock) |
903 | 919 | ||
904 | int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size) | 920 | int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size) |
905 | { | 921 | { |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index be4905769a45..3d3ac13287a4 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1662,8 +1662,10 @@ static int __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti, | |||
1662 | tio = alloc_tio(ci, ti, target_bio_nr); | 1662 | tio = alloc_tio(ci, ti, target_bio_nr); |
1663 | tio->len_ptr = len; | 1663 | tio->len_ptr = len; |
1664 | r = clone_bio(tio, bio, sector, *len); | 1664 | r = clone_bio(tio, bio, sector, *len); |
1665 | if (r < 0) | 1665 | if (r < 0) { |
1666 | free_tio(ci->md, tio); | ||
1666 | break; | 1667 | break; |
1668 | } | ||
1667 | __map_bio(tio); | 1669 | __map_bio(tio); |
1668 | } | 1670 | } |
1669 | 1671 | ||