Skip to content

Commit 48cf06b

Browse files
mauelshasnitm
authored andcommitted
dm raid: add discard support for RAID levels 4, 5 and 6
In case of RAID levels 4, 5 and 6 we have to verify each RAID members' ability to zero data on discards to avoid stripe data corruption -- if discard_zeroes_data is not set for each RAID member discard support must be disabled. But given the uncertainty of whether or not a RAID member properly supports zeroing data on discard we require the user to explicitly allow discard support on RAID levels 4, 5, and 6 by setting a dm-raid module paramter, e.g.: dm-raid.devices_handle_discard_safely=Y Otherwise, discards could cause data corruption on RAID4/5/6. Signed-off-by: Heinz Mauelshagen <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 75b8e04 commit 48cf06b

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

drivers/md/dm-raid.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#define DM_MSG_PREFIX "raid"
2020

21+
static bool devices_handle_discard_safely = false;
22+
2123
/*
2224
* The following flags are used by dm-raid.c to set up the array state.
2325
* They must be cleared before md_run is called.
@@ -475,6 +477,8 @@ static int validate_raid_redundancy(struct raid_set *rs)
475477
* will form the "stripe"
476478
* [[no]sync] Force or prevent recovery of the
477479
* entire array
480+
* [devices_handle_discard_safely] Allow discards on RAID4/5/6; useful if RAID
481+
* member device(s) properly support TRIM/UNMAP
478482
* [rebuild <idx>] Rebuild the drive indicated by the index
479483
* [daemon_sleep <ms>] Time between bitmap daemon work to
480484
* clear bits
@@ -1150,23 +1154,45 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
11501154
}
11511155

11521156
/*
1153-
* Enable/disable discard support on RAID set depending on RAID level.
1157+
* Enable/disable discard support on RAID set depending on
1158+
* RAID level and discard properties of underlying RAID members.
11541159
*/
11551160
static void configure_discard_support(struct dm_target *ti, struct raid_set *rs)
11561161
{
1162+
int i;
1163+
bool raid456;
1164+
11571165
/* Assume discards not supported until after checks below. */
11581166
ti->discards_supported = false;
11591167

11601168
/* RAID level 4,5,6 require discard_zeroes_data for data integrity! */
1161-
if (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6)
1162-
return; /* discard_zeroes_data cannot be trusted as reliable */
1169+
raid456 = (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6);
11631170

1171+
for (i = 0; i < rs->md.raid_disks; i++) {
1172+
struct request_queue *q = bdev_get_queue(rs->dev[i].rdev.bdev);
1173+
1174+
if (!q || !blk_queue_discard(q))
1175+
return;
1176+
1177+
if (raid456) {
1178+
if (!q->limits.discard_zeroes_data)
1179+
return;
1180+
if (!devices_handle_discard_safely) {
1181+
DMERR("raid456 discard support disabled due to discard_zeroes_data uncertainty.");
1182+
DMERR("Set dm-raid.devices_handle_discard_safely=Y to override.");
1183+
return;
1184+
}
1185+
}
1186+
}
1187+
1188+
/* All RAID members properly support discards */
11641189
ti->discards_supported = true;
11651190

11661191
/*
11671192
* RAID1 and RAID10 personalities require bio splitting,
1193+
* RAID0/4/5/6 don't and process large discard bios properly.
11681194
*/
1169-
ti->split_discard_bios = true;
1195+
ti->split_discard_bios = !!(rs->md.level == 1 || rs->md.level == 10);
11701196
ti->num_discard_bios = 1;
11711197
}
11721198

@@ -1709,6 +1735,10 @@ static void __exit dm_raid_exit(void)
17091735
module_init(dm_raid_init);
17101736
module_exit(dm_raid_exit);
17111737

1738+
module_param(devices_handle_discard_safely, bool, 0644);
1739+
MODULE_PARM_DESC(devices_handle_discard_safely,
1740+
"Set to Y if all devices in each array reliably return zeroes on reads from discarded regions");
1741+
17121742
MODULE_DESCRIPTION(DM_NAME " raid4/5/6 target");
17131743
MODULE_ALIAS("dm-raid1");
17141744
MODULE_ALIAS("dm-raid10");

0 commit comments

Comments
 (0)