Update __clone_and_map_discard to loop across all targets in a DM
device's table when it processes a discard bio. If a discard crosses a
target boundary it must be split accordingly.
Update __issue_target_requests and __issue_target_request to allow a
cloned discard bio to have a custom start sector and size.
- ti = dm_table_find_target(ci->map, ci->sector);
- if (!dm_target_is_valid(ti))
- return -EIO;
+ do {
+ ti = dm_table_find_target(ci->map, ci->sector);
+ if (!dm_target_is_valid(ti))
+ return -EIO;
- if (!ti->num_discard_requests)
- return -EOPNOTSUPP;
+ if (!ti->num_discard_requests)
+ return -EOPNOTSUPP;
- max = max_io_len(ci->sector, ti);
+ max = max_io_len_target_boundary(ci->sector, ti, NULL);
+ len = min(remaining, max);
- if (ci->sector_count > max)
- /*
- * FIXME: Handle a discard that spans two or more targets.
- */
- return -EOPNOTSUPP;
+ __issue_target_requests(ci, ti, ti->num_discard_requests, len);
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
07-24-2010, 04:09 PM
Mike Snitzer
dm: split discard requests on target boundaries
Update __clone_and_map_discard to loop across all targets in a DM
device's table when it processes a discard bio. If a discard crosses a
target boundary it must be split accordingly.
Update __issue_target_requests and __issue_target_request to allow a
cloned discard bio to have a custom start sector and size.
@@ -1251,30 +1255,31 @@ static void __clone_and_map_simple(struc
static int __clone_and_map_discard(struct clone_info *ci)
{
struct dm_target *ti;
- sector_t max;
-
- ti = dm_table_find_target(ci->map, ci->sector);
- if (!dm_target_is_valid(ti))
- return -EIO;
-
- /*
- * Even though the device advertised discard support,
- * reconfiguration might have changed that since the
- * check was performed.
- */
-
- if (!ti->num_discard_requests)
- return -EOPNOTSUPP;
+ sector_t max, len, remaining = ci->sector_count;
+ unsigned offset = 0;
- max = max_io_len(ci->sector, ti);
+ do {
+ ti = dm_table_find_target(ci->map, ci->sector);
+ if (!dm_target_is_valid(ti))
+ return -EIO;
- if (ci->sector_count > max)
/*
- * FIXME: Handle a discard that spans two or more targets.
+ * Even though the device advertised discard support,
+ * reconfiguration might have changed that since the
+ * check was performed.
*/
- return -EOPNOTSUPP;
+ if (!ti->num_discard_requests)
+ return -EOPNOTSUPP;
+
+ max = max_io_len_target_boundary(ci->sector, ti, NULL);
+ len = min(remaining, max);
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
07-26-2010, 09:41 PM
Mike Snitzer
dm: split discard requests on target boundaries
Update __clone_and_map_discard to loop across all targets in a DM
device's table when it processes a discard bio. If a discard crosses a
target boundary it must be split accordingly.
Update __issue_target_requests and __issue_target_request to allow a
cloned discard bio to have a custom start sector and size.
@@ -1248,30 +1252,31 @@ static void __clone_and_map_simple(struc
static int __clone_and_map_discard(struct clone_info *ci)
{
struct dm_target *ti;
- sector_t max;
-
- ti = dm_table_find_target(ci->map, ci->sector);
- if (!dm_target_is_valid(ti))
- return -EIO;
-
- /*
- * Even though the device advertised discard support,
- * reconfiguration might have changed that since the
- * check was performed.
- */
-
- if (!ti->num_discard_requests)
- return -EOPNOTSUPP;
+ sector_t max, len, remaining = ci->sector_count;
+ unsigned offset = 0;
- max = max_io_len(ci->sector, ti);
+ do {
+ ti = dm_table_find_target(ci->map, ci->sector);
+ if (!dm_target_is_valid(ti))
+ return -EIO;
- if (ci->sector_count > max)
/*
- * FIXME: Handle a discard that spans two or more targets.
+ * Even though the device advertised discard support,
+ * reconfiguration might have changed that since the
+ * check was performed.
*/
- return -EOPNOTSUPP;
+ if (!ti->num_discard_requests)
+ return -EOPNOTSUPP;
+
+ max = max_io_len_target_boundary(ci->sector, ti);
+ len = min(remaining, max);