Skip to content

Commit 27bc344

Browse files
committed
Merge tag 'for-4.12/dm-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: - dm thinp fix for crash that will occur when metadata device failure races with discard passdown to the underlying data device. - dm raid fix to not access the superblock's >= 1.9.0 'sectors' member unconditionally. * tag 'for-4.12/dm-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm thin: do not queue freed thin mapping for next stage processing dm raid: fix oops on upgrading to extended superblock format
2 parents 374bf88 + 00a0ea3 commit 27bc344

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

drivers/md/dm-raid.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,7 +1927,7 @@ struct dm_raid_superblock {
19271927
/********************************************************************
19281928
* BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
19291929
*
1930-
* FEATURE_FLAG_SUPPORTS_V190 in the features member indicates that those exist
1930+
* FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
19311931
*/
19321932

19331933
__le32 flags; /* Flags defining array states for reshaping */
@@ -2092,6 +2092,11 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
20922092
sb->layout = cpu_to_le32(mddev->layout);
20932093
sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors);
20942094

2095+
/********************************************************************
2096+
* BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
2097+
*
2098+
* FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
2099+
*/
20952100
sb->new_level = cpu_to_le32(mddev->new_level);
20962101
sb->new_layout = cpu_to_le32(mddev->new_layout);
20972102
sb->new_stripe_sectors = cpu_to_le32(mddev->new_chunk_sectors);
@@ -2438,8 +2443,14 @@ static int super_validate(struct raid_set *rs, struct md_rdev *rdev)
24382443
mddev->bitmap_info.default_offset = mddev->bitmap_info.offset;
24392444

24402445
if (!test_and_clear_bit(FirstUse, &rdev->flags)) {
2441-
/* Retrieve device size stored in superblock to be prepared for shrink */
2442-
rdev->sectors = le64_to_cpu(sb->sectors);
2446+
/*
2447+
* Retrieve rdev size stored in superblock to be prepared for shrink.
2448+
* Check extended superblock members are present otherwise the size
2449+
* will not be set!
2450+
*/
2451+
if (le32_to_cpu(sb->compat_features) & FEATURE_FLAG_SUPPORTS_V190)
2452+
rdev->sectors = le64_to_cpu(sb->sectors);
2453+
24432454
rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset);
24442455
if (rdev->recovery_offset == MaxSector)
24452456
set_bit(In_sync, &rdev->flags);

drivers/md/dm-thin.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,19 @@ static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m)
10941094
return;
10951095
}
10961096

1097+
/*
1098+
* Increment the unmapped blocks. This prevents a race between the
1099+
* passdown io and reallocation of freed blocks.
1100+
*/
1101+
r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
1102+
if (r) {
1103+
metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
1104+
bio_io_error(m->bio);
1105+
cell_defer_no_holder(tc, m->cell);
1106+
mempool_free(m, pool->mapping_pool);
1107+
return;
1108+
}
1109+
10971110
discard_parent = bio_alloc(GFP_NOIO, 1);
10981111
if (!discard_parent) {
10991112
DMWARN("%s: unable to allocate top level discard bio for passdown. Skipping passdown.",
@@ -1114,19 +1127,6 @@ static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m)
11141127
end_discard(&op, r);
11151128
}
11161129
}
1117-
1118-
/*
1119-
* Increment the unmapped blocks. This prevents a race between the
1120-
* passdown io and reallocation of freed blocks.
1121-
*/
1122-
r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
1123-
if (r) {
1124-
metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
1125-
bio_io_error(m->bio);
1126-
cell_defer_no_holder(tc, m->cell);
1127-
mempool_free(m, pool->mapping_pool);
1128-
return;
1129-
}
11301130
}
11311131

11321132
static void process_prepared_discard_passdown_pt2(struct dm_thin_new_mapping *m)

0 commit comments

Comments
 (0)