aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r--drivers/md/dm-raid.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 4880b69e2e9e..4857fa4a5484 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2010-2011 Neil Brown 2 * Copyright (C) 2010-2011 Neil Brown
3 * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2010-2014 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This file is released under the GPL. 5 * This file is released under the GPL.
6 */ 6 */
@@ -18,6 +18,8 @@
18 18
19#define DM_MSG_PREFIX "raid" 19#define DM_MSG_PREFIX "raid"
20 20
21static bool devices_handle_discard_safely = false;
22
21/* 23/*
22 * The following flags are used by dm-raid.c to set up the array state. 24 * The following flags are used by dm-raid.c to set up the array state.
23 * They must be cleared before md_run is called. 25 * They must be cleared before md_run is called.
@@ -475,6 +477,8 @@ too_many:
475 * will form the "stripe" 477 * will form the "stripe"
476 * [[no]sync] Force or prevent recovery of the 478 * [[no]sync] Force or prevent recovery of the
477 * entire array 479 * entire array
480 * [devices_handle_discard_safely] Allow discards on RAID4/5/6; useful if RAID
481 * member device(s) properly support TRIM/UNMAP
478 * [rebuild <idx>] Rebuild the drive indicated by the index 482 * [rebuild <idx>] Rebuild the drive indicated by the index
479 * [daemon_sleep <ms>] Time between bitmap daemon work to 483 * [daemon_sleep <ms>] Time between bitmap daemon work to
480 * clear bits 484 * clear bits
@@ -1150,6 +1154,49 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
1150} 1154}
1151 1155
1152/* 1156/*
1157 * Enable/disable discard support on RAID set depending on
1158 * RAID level and discard properties of underlying RAID members.
1159 */
1160static void configure_discard_support(struct dm_target *ti, struct raid_set *rs)
1161{
1162 int i;
1163 bool raid456;
1164
1165 /* Assume discards not supported until after checks below. */
1166 ti->discards_supported = false;
1167
1168 /* RAID level 4,5,6 require discard_zeroes_data for data integrity! */
1169 raid456 = (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6);
1170
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 */
1189 ti->discards_supported = true;
1190
1191 /*
1192 * RAID1 and RAID10 personalities require bio splitting,
1193 * RAID0/4/5/6 don't and process large discard bios properly.
1194 */
1195 ti->split_discard_bios = !!(rs->md.level == 1 || rs->md.level == 10);
1196 ti->num_discard_bios = 1;
1197}
1198
1199/*
1153 * Construct a RAID4/5/6 mapping: 1200 * Construct a RAID4/5/6 mapping:
1154 * Args: 1201 * Args:
1155 * <raid_type> <#raid_params> <raid_params> \ 1202 * <raid_type> <#raid_params> <raid_params> \
@@ -1231,6 +1278,11 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
1231 ti->private = rs; 1278 ti->private = rs;
1232 ti->num_flush_bios = 1; 1279 ti->num_flush_bios = 1;
1233 1280
1281 /*
1282 * Disable/enable discard support on RAID set.
1283 */
1284 configure_discard_support(ti, rs);
1285
1234 mutex_lock(&rs->md.reconfig_mutex); 1286 mutex_lock(&rs->md.reconfig_mutex);
1235 ret = md_run(&rs->md); 1287 ret = md_run(&rs->md);
1236 rs->md.in_sync = 0; /* Assume already marked dirty */ 1288 rs->md.in_sync = 0; /* Assume already marked dirty */
@@ -1652,7 +1704,7 @@ static void raid_resume(struct dm_target *ti)
1652 1704
1653static struct target_type raid_target = { 1705static struct target_type raid_target = {
1654 .name = "raid", 1706 .name = "raid",
1655 .version = {1, 5, 2}, 1707 .version = {1, 6, 0},
1656 .module = THIS_MODULE, 1708 .module = THIS_MODULE,
1657 .ctr = raid_ctr, 1709 .ctr = raid_ctr,
1658 .dtr = raid_dtr, 1710 .dtr = raid_dtr,
@@ -1683,6 +1735,10 @@ static void __exit dm_raid_exit(void)
1683module_init(dm_raid_init); 1735module_init(dm_raid_init);
1684module_exit(dm_raid_exit); 1736module_exit(dm_raid_exit);
1685 1737
1738module_param(devices_handle_discard_safely, bool, 0644);
1739MODULE_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
1686MODULE_DESCRIPTION(DM_NAME " raid4/5/6 target"); 1742MODULE_DESCRIPTION(DM_NAME " raid4/5/6 target");
1687MODULE_ALIAS("dm-raid1"); 1743MODULE_ALIAS("dm-raid1");
1688MODULE_ALIAS("dm-raid10"); 1744MODULE_ALIAS("dm-raid10");