History

dm: add WRITE SAME support

WRITE SAME bios have a payload that contain a single page. When cloning WRITE SAME bios DM has no need to modify the bi_io_vec attributes (and doing so would be detrimental). DM need only alter the start and end of the WRITE SAME bio accordingly. Rather than duplicate __clone_and_map_discard, factor out a common function that is also used by __clone_and_map_write_same.

Mike Snitzer committed 13 years ago

Commit 23508a91 parent d54eaa51 file · +39 −5Browse files

Unified · Split

drivers/md/dm.c+39−5
@@ -1174,7 +1174,28 @@ static void __clone_and_map_simple(struct clone_info *ci, struct dm_target *ti) · 1173 unmodified lines
11741174 ci->sector_count = 0;
11751175 }
11761176
1177−static int __clone_and_map_discard(struct clone_info *ci)
1177+typedef unsigned (*get_num_requests_fn)(struct dm_target *ti);
1178+
1179+static unsigned get_num_discard_requests(struct dm_target *ti)
1180+{
1181+ return ti->num_discard_requests;
1182+}
1183+
1184+static unsigned get_num_write_same_requests(struct dm_target *ti)
1185+{
1186+ return ti->num_write_same_requests;
1187+}
1188+
1189+typedef bool (*is_split_required_fn)(struct dm_target *ti);
1190+
1191+static bool is_split_required_for_discard(struct dm_target *ti)
1192+{
1193+ return ti->split_discard_requests;
1194+}
1195+
1196+static int __clone_and_map_changing_extent_only(struct clone_info *ci,
1197+ get_num_requests_fn get_num_requests,
1198+ is_split_required_fn is_split_required)
11781199 {
11791200 struct dm_target *ti;
11801201 sector_t len;
@@ -1185,15 +1206,15 @@ static int __clone_and_map_discard(struct clone_info *ci) · 4 unmodified lines
11851206 return -EIO;
11861207
11871208 /*
1188− * Even though the device advertised discard support,
1189− * that does not mean every target supports it, and
1209+ * Even though the device advertised support for this type of
1210+ * request, that does not mean every target supports it, and
11901211 * reconfiguration might also have changed that since the
11911212 * check was performed.
11921213 */
1193− if (!ti->num_discard_requests)
1214+ if (!get_num_requests || !get_num_requests(ti))
11941215 return -EOPNOTSUPP;
11951216
1196− if (!ti->split_discard_requests)
1217+ if (is_split_required && !is_split_required(ti))
11971218 len = min(ci->sector_count, max_io_len_target_boundary(ci->sector, ti));
11981219 else
11991220 len = min(ci->sector_count, max_io_len(ci->sector, ti));
@@ -1206,6 +1227,17 @@ static int __clone_and_map_discard(struct clone_info *ci) · 6 unmodified lines
12061227 return 0;
12071228 }
12081229
1230+static int __clone_and_map_discard(struct clone_info *ci)
1231+{
1232+ return __clone_and_map_changing_extent_only(ci, get_num_discard_requests,
1233+ is_split_required_for_discard);
1234+}
1235+
1236+static int __clone_and_map_write_same(struct clone_info *ci)
1237+{
1238+ return __clone_and_map_changing_extent_only(ci, get_num_write_same_requests, NULL);
1239+}
1240+
12091241 static int __clone_and_map(struct clone_info *ci)
12101242 {
12111243 struct bio *bio = ci->bio;
@@ -1215,6 +1247,8 @@ static int __clone_and_map(struct clone_info *ci) · 3 unmodified lines
12151247
12161248 if (unlikely(bio->bi_rw & REQ_DISCARD))
12171249 return __clone_and_map_discard(ci);
1250+ else if (unlikely(bio->bi_rw & REQ_WRITE_SAME))
1251+ return __clone_and_map_write_same(ci);
12181252
12191253 ti = dm_table_find_target(ci->map, ci->sector);
12201254 if (!dm_target_is_valid(ti))