Add a list to the struct dm_dev structure to store the associated targets, while also allowing differentiation between different target types. Signed-off-by: Yang Yang <yang.yang@xxxxxxxx> --- drivers/md/dm-table.c | 36 +++++++++++++++++++++++++++++++++++ include/linux/device-mapper.h | 3 +++ 2 files changed, 39 insertions(+) diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index bd68af10afed..f6554590b7af 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -741,6 +741,8 @@ int dm_table_add_target(struct dm_table *t, const char *type, if (ti->flush_pass_around == 0) t->flush_pass_around = 0; + INIT_LIST_HEAD(&ti->list); + return 0; bad: @@ -2134,6 +2136,25 @@ void dm_table_postsuspend_targets(struct dm_table *t) suspend_targets(t, POSTSUSPEND); } +static int dm_link_dev_to_target(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) +{ + struct list_head *targets = &dev->targets; + struct dm_target *pti; + + if (!list_empty(targets)) { + list_for_each_entry(pti, targets, list) { + if (pti->type == ti->type) + return 0; + } + } + + if (list_empty(&ti->list)) + list_add_tail(&ti->list, targets); + + return 0; +} + int dm_table_resume_targets(struct dm_table *t) { unsigned int i; @@ -2162,6 +2183,21 @@ int dm_table_resume_targets(struct dm_table *t) ti->type->resume(ti); } + if (t->flush_pass_around) { + struct list_head *devices = &t->devices; + struct dm_dev_internal *dd; + + list_for_each_entry(dd, devices, list) + INIT_LIST_HEAD(&dd->dm_dev->targets); + + for (i = 0; i < t->num_targets; i++) { + struct dm_target *ti = dm_table_get_target(t, i); + + if (ti->type->iterate_devices) + ti->type->iterate_devices(ti, dm_link_dev_to_target, NULL); + } + } + return 0; } diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 0893ff8c01b6..19e03f9b2589 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -169,6 +169,7 @@ struct dm_dev { struct dax_device *dax_dev; blk_mode_t mode; char name[16]; + struct list_head targets; }; /* @@ -298,6 +299,8 @@ struct dm_target { struct dm_table *table; struct target_type *type; + struct list_head list; + /* target limits */ sector_t begin; sector_t len; -- 2.34.1