From f4c6775682ee40b6f40277dc92528e2879d54af6 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Wed, 30 Mar 2011 23:33:56 -0400 Subject: [PATCH 2/5] . re-implemented core of dm_table_get_integrity() . added blk_integrity_is_initialized() --- drivers/md/dm-table.c | 30 ++++++++++++++++-------------- include/linux/blkdev.h | 6 ++++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index f3f70d6..5ec729f 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -928,33 +928,35 @@ static int dm_table_build_index(struct dm_table *t) /* * Get the integrity profile for the table. - * If %compare is true, all devices' profiles must match. - * If %compare is false, all devices must at least have an - * allocated integrity profile. - * FIXME: add a new integrity method: blk_integrity_initialized() to - * skip comparisons with uninitialized profiles during table load. + * If %match_all is true, all devices' profiles must match. + * If %match_all is false, all devices must at least have an + * allocated integrity profile; but uninitialized is ok. */ -static struct blk_integrity *dm_table_get_integrity(struct dm_table *t, bool compare) +static struct blk_integrity *dm_table_get_integrity(struct dm_table *t, bool match_all) { struct list_head *devices = dm_table_get_devices(t); struct dm_dev_internal *prev = NULL, *dd = NULL; + struct blk_integrity *bi = NULL; list_for_each_entry(dd, devices, list) { - if (compare && prev && - blk_integrity_compare(prev->dm_dev.bdev->bd_disk, - dd->dm_dev.bdev->bd_disk) < 0) { + bi = bdev_get_integrity(dd->dm_dev.bdev); + if (!bi) + goto no_integrity; + if (!match_all && !blk_integrity_is_initialized(bi)) + continue; /* skip uninitialized profiles */ + else if (prev && + blk_integrity_compare(prev->dm_dev.bdev->bd_disk, + dd->dm_dev.bdev->bd_disk) < 0) { DMWARN("%s: integrity not set: %s and %s mismatch", dm_device_name(t->md), prev->dm_dev.bdev->bd_disk->disk_name, dd->dm_dev.bdev->bd_disk->disk_name); goto no_integrity; - } else if (!bdev_get_integrity(dd->dm_dev.bdev)) - goto no_integrity; + } prev = dd; } - if (prev) - return bdev_get_integrity(prev->dm_dev.bdev); + return bi; no_integrity: return NULL; @@ -988,7 +990,7 @@ static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device /* * Avoid clearing a previously established integrity profile */ - if (bdev_get_integrity(dm_disk(md))) + if (blk_get_integrity(dm_disk(md))) return 0; return blk_integrity_register(dm_disk(md), NULL); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 16a902f..90b1436 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1248,6 +1248,11 @@ queue_max_integrity_segments(struct request_queue *q) return q->limits.max_integrity_segments; } +static inline bool blk_integrity_is_initialized(struct blk_integrity *bi) +{ + return (bi && bi->name && strcmp(bi->name, "unsupported") != 0); +} + #else /* CONFIG_BLK_DEV_INTEGRITY */ #define blk_integrity_rq(rq) (0) @@ -1262,6 +1267,7 @@ queue_max_integrity_segments(struct request_queue *q) #define queue_max_integrity_segments(a) (0) #define blk_integrity_merge_rq(a, b, c) (0) #define blk_integrity_merge_bio(a, b, c) (0) +#define blk_integrity_is_initialized(a) (0) #endif /* CONFIG_BLK_DEV_INTEGRITY */ -- 1.7.3.4