diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2009-04-08 19:27:12 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-04-08 19:27:12 -0400 |
commit | 9c47008d13add50ec4597a8b9eee200c515282c8 (patch) | |
tree | debd8ebb2fef2687d4548a177505ec30bda95503 /drivers/md/dm-table.c | |
parent | 577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff) |
dm: add integrity support
This patch provides support for data integrity passthrough in the device
mapper.
- If one or more component devices support integrity an integrity
profile is preallocated for the DM device.
- If all component devices have compatible profiles the DM device is
flagged as capable.
- Handle integrity metadata when splitting and cloning bios.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-table.c')
-rw-r--r-- | drivers/md/dm-table.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index e8361b191b9b..02d0b489fad6 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -879,6 +879,45 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector) | |||
879 | return &t->targets[(KEYS_PER_NODE * n) + k]; | 879 | return &t->targets[(KEYS_PER_NODE * n) + k]; |
880 | } | 880 | } |
881 | 881 | ||
882 | /* | ||
883 | * Set the integrity profile for this device if all devices used have | ||
884 | * matching profiles. | ||
885 | */ | ||
886 | static void dm_table_set_integrity(struct dm_table *t) | ||
887 | { | ||
888 | struct list_head *devices = dm_table_get_devices(t); | ||
889 | struct dm_dev_internal *prev = NULL, *dd = NULL; | ||
890 | |||
891 | if (!blk_get_integrity(dm_disk(t->md))) | ||
892 | return; | ||
893 | |||
894 | list_for_each_entry(dd, devices, list) { | ||
895 | if (prev && | ||
896 | blk_integrity_compare(prev->dm_dev.bdev->bd_disk, | ||
897 | dd->dm_dev.bdev->bd_disk) < 0) { | ||
898 | DMWARN("%s: integrity not set: %s and %s mismatch", | ||
899 | dm_device_name(t->md), | ||
900 | prev->dm_dev.bdev->bd_disk->disk_name, | ||
901 | dd->dm_dev.bdev->bd_disk->disk_name); | ||
902 | goto no_integrity; | ||
903 | } | ||
904 | prev = dd; | ||
905 | } | ||
906 | |||
907 | if (!prev || !bdev_get_integrity(prev->dm_dev.bdev)) | ||
908 | goto no_integrity; | ||
909 | |||
910 | blk_integrity_register(dm_disk(t->md), | ||
911 | bdev_get_integrity(prev->dm_dev.bdev)); | ||
912 | |||
913 | return; | ||
914 | |||
915 | no_integrity: | ||
916 | blk_integrity_register(dm_disk(t->md), NULL); | ||
917 | |||
918 | return; | ||
919 | } | ||
920 | |||
882 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) | 921 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) |
883 | { | 922 | { |
884 | /* | 923 | /* |
@@ -899,6 +938,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) | |||
899 | else | 938 | else |
900 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q); | 939 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q); |
901 | 940 | ||
941 | dm_table_set_integrity(t); | ||
902 | } | 942 | } |
903 | 943 | ||
904 | unsigned int dm_table_get_num_targets(struct dm_table *t) | 944 | unsigned int dm_table_get_num_targets(struct dm_table *t) |