linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Block integrity patches for 2.6.28
@ 2008-10-01  7:38 Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 1/7] block: Introduce integrity data ownership flag Martin K. Petersen
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel


This patch series contains block layer integrity updates for 2.6.28.

There are a few fixes to the core bits, including a switch from
block_device to gendisk in the integrity compare function.  I also had
to add a helper to access a gendisk's integrity profile.  This is used
by MD.

The DM bits have been cleaned up and a separate dm_table_set_integrity
function has been introduced.  This allows us to avoid changing
dm_table_set_restrictions() and its callers.

The MD patch now correctly handles devices that come and go (as
requested by Neil).

The patches are against for-2.6.28 and depend on

    d7533ad0e132f92e75c1b2eb7c26387b25a583c1

being reverted.

--
Martin K. Petersen      Oracle Linux Engineering



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/7] block: Introduce integrity data ownership flag
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 2/7] block: Fix double put in blk_integrity_unregister Martin K. Petersen
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

A filesystem might supply its own integrity metadata.  Introduce a
flag that indicates whether the filesystem or the block layer owns the
integrity buffer.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 fs/bio-integrity.c  |    3 ++-
 include/linux/bio.h |    1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index c3e174b..8e409ff 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -107,7 +107,8 @@ void bio_integrity_free(struct bio *bio, struct bio_set *bs)
 	BUG_ON(bip == NULL);
 
 	/* A cloned bio doesn't own the integrity metadata */
-	if (!bio_flagged(bio, BIO_CLONED) && bip->bip_buf != NULL)
+	if (!bio_flagged(bio, BIO_CLONED) && !bio_flagged(bio, BIO_FS_INTEGRITY)
+	    && bip->bip_buf != NULL)
 		kfree(bip->bip_buf);
 
 	mempool_free(bip->bip_vec, bs->bvec_pools[bip->bip_pool]);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 6520ee1..6aba97d 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -109,6 +109,7 @@ struct bio {
 #define BIO_EOPNOTSUPP	7	/* not supported */
 #define BIO_CPU_AFFINE	8	/* complete bio on same CPU as submitted */
 #define BIO_NULL_MAPPED 9	/* contains invalid user pages */
+#define BIO_FS_INTEGRITY 10	/* fs owns integrity data, not block layer */
 #define bio_flagged(bio, flag)	((bio)->bi_flags & (1 << (flag)))
 
 /*
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/7] block: Fix double put in blk_integrity_unregister
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 1/7] block: Introduce integrity data ownership flag Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 3/7] block: Switch blk_integrity_compare from bdev to gendisk Martin K. Petersen
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

 - kobject_del already puts the parent.

 - Set integrity profile to NULL to prevent stale data.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 block/blk-integrity.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 69023da..e3817a0 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -376,7 +376,7 @@ void blk_integrity_unregister(struct gendisk *disk)
 
 	kobject_uevent(&bi->kobj, KOBJ_REMOVE);
 	kobject_del(&bi->kobj);
-	kobject_put(&disk_to_dev(disk)->kobj);
 	kmem_cache_free(integrity_cachep, bi);
+	disk->integrity = NULL;
 }
 EXPORT_SYMBOL(blk_integrity_unregister);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/7] block: Switch blk_integrity_compare from bdev to gendisk
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 1/7] block: Introduce integrity data ownership flag Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 2/7] block: Fix double put in blk_integrity_unregister Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 4/7] block: gendisk integrity wrapper Martin K. Petersen
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

The DM and MD integrity support now depends on being able to use
gendisks instead of block_devices when comparing integrity profiles.
Change function parameters accordingly.

Also update comparison logic so that two NULL profiles are a valid
configuration.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 block/blk-integrity.c  |   28 ++++++++++++++--------------
 include/linux/blkdev.h |    2 +-
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index e3817a0..61a8e2f 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -108,51 +108,51 @@ new_segment:
 EXPORT_SYMBOL(blk_rq_map_integrity_sg);
 
 /**
- * blk_integrity_compare - Compare integrity profile of two block devices
- * @bd1:	Device to compare
- * @bd2:	Device to compare
+ * blk_integrity_compare - Compare integrity profile of two disks
+ * @gd1:	Disk to compare
+ * @gd2:	Disk to compare
  *
  * Description: Meta-devices like DM and MD need to verify that all
  * sub-devices use the same integrity format before advertising to
  * upper layers that they can send/receive integrity metadata.  This
- * function can be used to check whether two block devices have
+ * function can be used to check whether two gendisk devices have
  * compatible integrity formats.
  */
-int blk_integrity_compare(struct block_device *bd1, struct block_device *bd2)
+int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
 {
-	struct blk_integrity *b1 = bd1->bd_disk->integrity;
-	struct blk_integrity *b2 = bd2->bd_disk->integrity;
+	struct blk_integrity *b1 = gd1->integrity;
+	struct blk_integrity *b2 = gd2->integrity;
 
-	BUG_ON(bd1->bd_disk == NULL);
-	BUG_ON(bd2->bd_disk == NULL);
+	if (!b1 && !b2)
+		return 0;
 
 	if (!b1 || !b2)
-		return 0;
+		return -1;
 
 	if (b1->sector_size != b2->sector_size) {
 		printk(KERN_ERR "%s: %s/%s sector sz %u != %u\n", __func__,
-		       bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+		       gd1->disk_name, gd2->disk_name,
 		       b1->sector_size, b2->sector_size);
 		return -1;
 	}
 
 	if (b1->tuple_size != b2->tuple_size) {
 		printk(KERN_ERR "%s: %s/%s tuple sz %u != %u\n", __func__,
-		       bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+		       gd1->disk_name, gd2->disk_name,
 		       b1->tuple_size, b2->tuple_size);
 		return -1;
 	}
 
 	if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) {
 		printk(KERN_ERR "%s: %s/%s tag sz %u != %u\n", __func__,
-		       bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+		       gd1->disk_name, gd2->disk_name,
 		       b1->tag_size, b2->tag_size);
 		return -1;
 	}
 
 	if (strcmp(b1->name, b2->name)) {
 		printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__,
-		       bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+		       gd1->disk_name, gd2->disk_name,
 		       b1->name, b2->name);
 		return -1;
 	}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 30c4292..eec0842 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1010,7 +1010,7 @@ struct blk_integrity {
 
 extern int blk_integrity_register(struct gendisk *, struct blk_integrity *);
 extern void blk_integrity_unregister(struct gendisk *);
-extern int blk_integrity_compare(struct block_device *, struct block_device *);
+extern int blk_integrity_compare(struct gendisk *, struct gendisk *);
 extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *);
 extern int blk_rq_count_integrity_sg(struct request *);
 
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/7] block: gendisk integrity wrapper
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
                   ` (2 preceding siblings ...)
  2008-10-01  7:38 ` [PATCH 3/7] block: Switch blk_integrity_compare from bdev to gendisk Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 5/7] block: Find bio sector offset given idx and offset Martin K. Petersen
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

This is a wrapper for accessing a gendisk's integrity bits.  It allows
the integrity support in MD to be compiled with BLK_DEV_INTEGRITY off.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 include/linux/blkdev.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index eec0842..ca08439 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1027,6 +1027,11 @@ static inline struct blk_integrity *bdev_get_integrity(struct block_device *bdev
 	return bdev->bd_disk->integrity;
 }
 
+static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
+{
+	return disk->integrity;
+}
+
 static inline unsigned int bdev_get_tag_size(struct block_device *bdev)
 {
 	struct blk_integrity *bi = bdev_get_integrity(bdev);
@@ -1069,6 +1074,7 @@ static inline int blk_integrity_rq(struct request *rq)
 #define blk_rq_count_integrity_sg(a)		(0)
 #define blk_rq_map_integrity_sg(a, b)		(0)
 #define bdev_get_integrity(a)			(0)
+#define blk_get_integrity(a)			(0)
 #define bdev_get_tag_size(a)			(0)
 #define blk_integrity_compare(a, b)		(0)
 #define blk_integrity_register(a, b)		(0)
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/7] block: Find bio sector offset given idx and offset
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
                   ` (3 preceding siblings ...)
  2008-10-01  7:38 ` [PATCH 4/7] block: gendisk integrity wrapper Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-01  8:10   ` Jens Axboe
  2008-10-01  7:38 ` [PATCH 6/7] dm: Add support for data integrity to DM Martin K. Petersen
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

Helper function to find the sector offset in a bio given bvec index
and page offset.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 fs/bio.c            |   34 ++++++++++++++++++++++++++++++++++
 include/linux/bio.h |    1 +
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/fs/bio.c b/fs/bio.c
index e56e768..55ee2fd 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1300,6 +1300,40 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
 	return bp;
 }
 
+/**
+ *	bio_sector_offset - Find hardware sector offset in bio
+ *	@bio:		bio to inspect
+ *	@index:		bio_vec index
+ *	@offset:	offset in bv_page
+ *
+ *	Return the number of hardware sectors between beginning of bio
+ *	and an end point indicated by a bio_vec index and an offset
+ *	within that vector's page.
+ */
+sector_t bio_sector_offset(struct bio *bio, unsigned short index,
+			   unsigned int offset)
+{
+	struct bio_vec *bv;
+	unsigned int sector_sz = bio->bi_bdev->bd_disk->queue->hardsect_size;
+	sector_t sectors;
+	int i;
+
+	sectors = 0;
+
+	BUG_ON(index >= bio->bi_vcnt);
+
+	bio_for_each_segment(bv, bio, i) {
+		if (i == index) {
+			if (offset > bv->bv_offset)
+				sectors += (offset - bv->bv_offset) / sector_sz;
+			return sectors;
+		}
+
+		sectors += bv->bv_len / sector_sz;
+	}
+
+	BUG();
+}
 
 /*
  * create memory pools for biovec's in a bio_set.
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 6aba97d..386a1df 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -327,6 +327,7 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
 			   unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
+extern sector_t bio_sector_offset(struct bio *, unsigned short, unsigned int);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
 				unsigned long, unsigned int, int, gfp_t);
 struct sg_iovec;
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/7] dm: Add support for data integrity to DM
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
                   ` (4 preceding siblings ...)
  2008-10-01  7:38 ` [PATCH 5/7] block: Find bio sector offset given idx and offset Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-01  7:38 ` [PATCH 7/7] md: Add support for data integrity to MD Martin K. Petersen
  2008-10-02 10:56 ` Block integrity patches for 2.6.28 Jens Axboe
  7 siblings, 0 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

If all subdevices support the same protection format the DM device is
flagged as capable.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 drivers/md/dm-table.c |   36 ++++++++++++++++++++++++++++++++++++
 drivers/md/dm.c       |   17 +++++++++++++++++
 drivers/md/dm.h       |    1 +
 3 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 61f4414..f089404 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -860,7 +860,43 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
 		queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
 	else
 		queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
+}
+
+void dm_table_set_integrity(struct dm_table *t, struct mapped_device *md)
+{
+	struct list_head *devices = dm_table_get_devices(t);
+	struct dm_dev *prev, *cur;
+
+	/*
+	 * Run through all devices to ensure they have matching
+	 * integrity profile
+	 */
+	cur = prev = NULL;
+
+	list_for_each_entry(cur, devices, list) {
+
+		if (prev && blk_integrity_compare(prev->bdev->bd_disk,
+						  cur->bdev->bd_disk) < 0) {
+			printk(KERN_ERR "%s: %s %s Integrity mismatch!\n",
+			       __func__, prev->bdev->bd_disk->disk_name,
+			       cur->bdev->bd_disk->disk_name);
+			return;
+		}
+		prev = cur;
+	}
 
+	/* Register dm device as being integrity capable */
+	if (prev && bdev_get_integrity(prev->bdev)) {
+		struct gendisk *disk = dm_disk(md);
+
+		if (blk_integrity_register(dm_disk(md),
+					   bdev_get_integrity(prev->bdev)))
+			printk(KERN_ERR "%s: %s Could not register integrity!\n",
+			       __func__, disk->disk_name);
+		else
+			printk(KERN_INFO "Enabling data integrity on %s\n",
+			       disk->disk_name);
+	}
 }
 
 unsigned int dm_table_get_num_targets(struct dm_table *t)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8d40369..4f65342 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -669,6 +669,13 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
 	clone->bi_size = to_bytes(len);
 	clone->bi_io_vec->bv_offset = offset;
 	clone->bi_io_vec->bv_len = clone->bi_size;
+	clone->bi_flags |= 1 << BIO_CLONED;
+
+	if (bio_integrity(bio)) {
+		bio_integrity_clone(clone, bio, bs);
+		bio_integrity_trim(clone,
+				   bio_sector_offset(bio, idx, offset), len);
+	}
 
 	return clone;
 }
@@ -691,6 +698,14 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
 	clone->bi_size = to_bytes(len);
 	clone->bi_flags &= ~(1 << BIO_SEG_VALID);
 
+	if (bio_integrity(bio)) {
+		bio_integrity_clone(clone, bio, bs);
+
+		if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
+			bio_integrity_trim(clone,
+					   bio_sector_offset(bio, idx, 0), len);
+	}
+
 	return clone;
 }
 
@@ -1157,6 +1172,7 @@ static void free_dev(struct mapped_device *md)
 	mempool_destroy(md->tio_pool);
 	mempool_destroy(md->io_pool);
 	bioset_free(md->bs);
+	blk_integrity_unregister(md->disk);
 	del_gendisk(md->disk);
 	free_minor(minor);
 
@@ -1222,6 +1238,7 @@ static int __bind(struct mapped_device *md, struct dm_table *t)
 	write_lock(&md->map_lock);
 	md->map = t;
 	dm_table_set_restrictions(t, q);
+	dm_table_set_integrity(t, md);
 	write_unlock(&md->map_lock);
 
 	return 0;
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 1e59a0b..cf34b99 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -44,6 +44,7 @@ void dm_table_event_callback(struct dm_table *t,
 struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index);
 struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
+void dm_table_set_integrity(struct dm_table *t, struct mapped_device *md);
 struct list_head *dm_table_get_devices(struct dm_table *t);
 void dm_table_presuspend_targets(struct dm_table *t);
 void dm_table_postsuspend_targets(struct dm_table *t);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 7/7] md: Add support for data integrity to MD
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
                   ` (5 preceding siblings ...)
  2008-10-01  7:38 ` [PATCH 6/7] dm: Add support for data integrity to DM Martin K. Petersen
@ 2008-10-01  7:38 ` Martin K. Petersen
  2008-10-02 10:56 ` Block integrity patches for 2.6.28 Jens Axboe
  7 siblings, 0 replies; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-01  7:38 UTC (permalink / raw)
  To: jens.axboe, neilb, agk; +Cc: linux-kernel, dm-devel, Martin K. Petersen

If all subdevices support the same protection format the MD device is
flagged as capable.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 drivers/md/md.c |   34 ++++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 45521da..35542f2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1411,6 +1411,38 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
 
 static LIST_HEAD(pending_raid_disks);
 
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+	struct mdk_personality *pers = mddev->pers;
+	struct gendisk *disk = mddev->gendisk;
+	struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
+	struct blk_integrity *bi_mddev = blk_get_integrity(disk);
+
+	/* Data integrity passthrough not supported on RAID 4, 5 and 6 */
+	if (pers && pers->level >= 4 && pers->level <= 6)
+		return;
+
+	/* If rdev is integrity capable, register profile for mddev */
+	if (!bi_mddev && bi_rdev) {
+		if (blk_integrity_register(disk, bi_rdev))
+			printk(KERN_ERR "%s: %s Could not register integrity!\n",
+			       __func__, disk->disk_name);
+		else
+			printk(KERN_NOTICE "Enabling data integrity on %s\n",
+			       disk->disk_name);
+		return;
+	}
+
+	/* Check that mddev and rdev have matching profiles */
+	if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
+		printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
+		       disk->disk_name, rdev->bdev->bd_disk->disk_name);
+		printk(KERN_NOTICE "Disabling data integrity on %s\n",
+		       disk->disk_name);
+		blk_integrity_unregister(disk);
+	}
+}
+
 static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 {
 	char b[BDEVNAME_SIZE];
@@ -1471,6 +1503,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 	}
 	list_add_rcu(&rdev->same_set, &mddev->disks);
 	bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk);
+	md_integrity_check(rdev, mddev);
 	return 0;
 
  fail:
@@ -3947,6 +3980,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
 		printk(KERN_INFO "md: %s switched to read-only mode.\n",
 			mdname(mddev));
 	err = 0;
+	blk_integrity_unregister(disk);
 	md_new_event(mddev);
 	sysfs_notify(&mddev->kobj, NULL, "array_state");
 out:
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/7] block: Find bio sector offset given idx and offset
  2008-10-01  7:38 ` [PATCH 5/7] block: Find bio sector offset given idx and offset Martin K. Petersen
@ 2008-10-01  8:10   ` Jens Axboe
  2008-10-02  2:42     ` Martin K. Petersen
  0 siblings, 1 reply; 14+ messages in thread
From: Jens Axboe @ 2008-10-01  8:10 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: neilb, agk, linux-kernel, dm-devel

On Wed, Oct 01 2008, Martin K. Petersen wrote:
> Helper function to find the sector offset in a bio given bvec index
> and page offset.
> 
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> ---
>  fs/bio.c            |   34 ++++++++++++++++++++++++++++++++++
>  include/linux/bio.h |    1 +
>  2 files changed, 35 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/bio.c b/fs/bio.c
> index e56e768..55ee2fd 100644
> --- a/fs/bio.c
> +++ b/fs/bio.c
> @@ -1300,6 +1300,40 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
>  	return bp;
>  }
>  
> +/**
> + *	bio_sector_offset - Find hardware sector offset in bio
> + *	@bio:		bio to inspect
> + *	@index:		bio_vec index
> + *	@offset:	offset in bv_page
> + *
> + *	Return the number of hardware sectors between beginning of bio
> + *	and an end point indicated by a bio_vec index and an offset
> + *	within that vector's page.
> + */
> +sector_t bio_sector_offset(struct bio *bio, unsigned short index,
> +			   unsigned int offset)
> +{
> +	struct bio_vec *bv;
> +	unsigned int sector_sz = bio->bi_bdev->bd_disk->queue->hardsect_size;
> +	sector_t sectors;
> +	int i;
> +
> +	sectors = 0;
> +
> +	BUG_ON(index >= bio->bi_vcnt);
> +
> +	bio_for_each_segment(bv, bio, i) {
> +		if (i == index) {
> +			if (offset > bv->bv_offset)
> +				sectors += (offset - bv->bv_offset) / sector_sz;
> +			return sectors;
> +		}
> +
> +		sectors += bv->bv_len / sector_sz;
> +	}
> +
> +	BUG();
> +}

Too may BUG's there, me thinks, and the interface looks fragile. What if
the bio is alreday done (bi_idx == bi_vcnt)? I'd prefer something ala:

sector_t bio_sector_offset(struct bio *bio, unsigned short index,
			   unsigned int offset)
{
	unsigned int sector_sz = queue_hardsect_size(bio->bi_bdev->bd_disk->queue);
	struct bio_vec *bv;
	sector_t sectors;
	int i;

	sectors = 0;

        /* total start of bio current start? */
#if 0
        if (index >= bio->bi_vcnt)
                index = bio->bi_vcnt - 1;

        __bio_for_each_segment(bv, bio, i, 0) {
#else
        if (index > bio->bi_idx)
                return 0;

	bio_for_each_segment(bv, bio, i) {
#endif
		if (i == index) {
			if (offset > bv->bv_offset)
				sectors += (offset - bv->bv_offset) / sector_sz;
                        break;
		}

		sectors += bv->bv_len / sector_sz;
	}

        return sectors;
}

Depending on which interface you want, pick one of the if/else parts :-)

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/7] block: Find bio sector offset given idx and offset
  2008-10-01  8:10   ` Jens Axboe
@ 2008-10-02  2:42     ` Martin K. Petersen
  2008-10-02 17:07       ` Jens Axboe
  0 siblings, 1 reply; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-02  2:42 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Martin K. Petersen, neilb, agk, linux-kernel, dm-devel

>>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:

Jens> Too may BUG's there, me thinks, and the interface looks
Jens> fragile. What if the bio is alreday done (bi_idx == bi_vcnt)?

Good point!  Obviously I've only used the function for bio splitting
and not at completion time.  Updated patch below.


block: Find bio sector offset given idx and offset

Helper function to find the sector offset in a bio given bvec index
and page offset.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 fs/bio.c            |   36 ++++++++++++++++++++++++++++++++++++
 include/linux/bio.h |    1 +
 2 files changed, 37 insertions(+)

diff --git a/fs/bio.c b/fs/bio.c
index e56e768..a5af580 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1300,6 +1300,42 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
 	return bp;
 }
 
+/**
+ *      bio_sector_offset - Find hardware sector offset in bio
+ *      @bio:           bio to inspect
+ *      @index:         bio_vec index
+ *      @offset:        offset in bv_page
+ *
+ *      Return the number of hardware sectors between beginning of bio
+ *      and an end point indicated by a bio_vec index and an offset
+ *      within that vector's page.
+ */
+sector_t bio_sector_offset(struct bio *bio, unsigned short index,
+			   unsigned int offset)
+{
+	unsigned int sector_sz = queue_hardsect_size(bio->bi_bdev->bd_disk->queue);
+	struct bio_vec *bv;
+	sector_t sectors;
+	int i;
+
+	sectors = 0;
+
+	if (index >= bio->bi_idx)
+		index = bio->bi_vcnt - 1;
+
+	__bio_for_each_segment(bv, bio, i, 0) {
+		if (i == index) {
+			if (offset > bv->bv_offset)
+				sectors += (offset - bv->bv_offset) / sector_sz;
+			break;
+		}
+
+		sectors += bv->bv_len / sector_sz;
+	}
+
+	return sectors;
+}
+EXPORT_SYMBOL(bio_sector_offset);
 
 /*
  * create memory pools for biovec's in a bio_set.
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 6aba97d..386a1df 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -327,6 +327,7 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
 			   unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
+extern sector_t bio_sector_offset(struct bio *, unsigned short, unsigned int);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
 				unsigned long, unsigned int, int, gfp_t);
 struct sg_iovec;

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: Block integrity patches for 2.6.28
  2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
                   ` (6 preceding siblings ...)
  2008-10-01  7:38 ` [PATCH 7/7] md: Add support for data integrity to MD Martin K. Petersen
@ 2008-10-02 10:56 ` Jens Axboe
  2008-10-02 13:54   ` Martin K. Petersen
  7 siblings, 1 reply; 14+ messages in thread
From: Jens Axboe @ 2008-10-02 10:56 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: neilb, agk, linux-kernel, dm-devel

On Wed, Oct 01 2008, Martin K. Petersen wrote:
> 
> This patch series contains block layer integrity updates for 2.6.28.
> 
> There are a few fixes to the core bits, including a switch from
> block_device to gendisk in the integrity compare function.  I also had
> to add a helper to access a gendisk's integrity profile.  This is used
> by MD.
> 
> The DM bits have been cleaned up and a separate dm_table_set_integrity
> function has been introduced.  This allows us to avoid changing
> dm_table_set_restrictions() and its callers.
> 
> The MD patch now correctly handles devices that come and go (as
> requested by Neil).
> 
> The patches are against for-2.6.28 and depend on
> 
>     d7533ad0e132f92e75c1b2eb7c26387b25a583c1

As far as I can tell, most of that commit is still fine. You want
bdev_get_integrity() in blkdev.h, the 3 other moves and the unused
bdev_get_tag_size() do not look like they are being used by this patch
set.

Correct?

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Block integrity patches for 2.6.28
  2008-10-02 10:56 ` Block integrity patches for 2.6.28 Jens Axboe
@ 2008-10-02 13:54   ` Martin K. Petersen
  2008-10-02 16:29     ` Jens Axboe
  0 siblings, 1 reply; 14+ messages in thread
From: Martin K. Petersen @ 2008-10-02 13:54 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Martin K. Petersen, neilb, agk, linux-kernel, dm-devel

>>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:

Jens> As far as I can tell, most of that commit is still fine. You
Jens> want bdev_get_integrity() in blkdev.h, the 3 other moves and the
Jens> unused bdev_get_tag_size() do not look like they are being used
Jens> by this patch set.

bdev_get_integrity() and bdev_get_tag_size() are being used by
stacking drivers and filesystems to prepare I/O.  It's correct that
none of the in-tree stuff currently uses bdev_get_tag_size().  That's
coming with the btrfs support.  If you want to pull that out for now
and have me put that back later in that's ok.  Just adds another
two-stage merge dependency for a later cycle.

bdev_integrity_enabled() and blk_integrity_tuple_size() are only being
used from within bio-integrity.c and can move there.  I originally put
them in blkdev.h because they are block device functions and not bio
ditto.

Want me to submit a new patch shuffling bdev_get_integrity() back
where it came from?

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Block integrity patches for 2.6.28
  2008-10-02 13:54   ` Martin K. Petersen
@ 2008-10-02 16:29     ` Jens Axboe
  0 siblings, 0 replies; 14+ messages in thread
From: Jens Axboe @ 2008-10-02 16:29 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: neilb, agk, linux-kernel, dm-devel

On Thu, Oct 02 2008, Martin K. Petersen wrote:
> >>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
> 
> Jens> As far as I can tell, most of that commit is still fine. You
> Jens> want bdev_get_integrity() in blkdev.h, the 3 other moves and the
> Jens> unused bdev_get_tag_size() do not look like they are being used
> Jens> by this patch set.
> 
> bdev_get_integrity() and bdev_get_tag_size() are being used by
> stacking drivers and filesystems to prepare I/O.  It's correct that
> none of the in-tree stuff currently uses bdev_get_tag_size().  That's
> coming with the btrfs support.  If you want to pull that out for now
> and have me put that back later in that's ok.  Just adds another
> two-stage merge dependency for a later cycle.

Well, I would not have added it in the first place, but it was there. I
already did the bdev_get_integrity() addon instead of the revert, so
lets please just keep it at that.

> bdev_integrity_enabled() and blk_integrity_tuple_size() are only being
> used from within bio-integrity.c and can move there.  I originally put
> them in blkdev.h because they are block device functions and not bio
> ditto.
> 
> Want me to submit a new patch shuffling bdev_get_integrity() back
> where it came from?

Do we need any on top of current for-2.6.28?

I'll apply your series with the modified patch #5, it'll probably need a
hand edit or two since I didn't revert the commit in question, but
should be trivial to resolve.


-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/7] block: Find bio sector offset given idx and offset
  2008-10-02  2:42     ` Martin K. Petersen
@ 2008-10-02 17:07       ` Jens Axboe
  0 siblings, 0 replies; 14+ messages in thread
From: Jens Axboe @ 2008-10-02 17:07 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: neilb, agk, linux-kernel, dm-devel

On Wed, Oct 01 2008, Martin K. Petersen wrote:
> >>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
> 
> Jens> Too may BUG's there, me thinks, and the interface looks
> Jens> fragile. What if the bio is alreday done (bi_idx == bi_vcnt)?
> 
> Good point!  Obviously I've only used the function for bio splitting
> and not at completion time.  Updated patch below.
> 
> 
> block: Find bio sector offset given idx and offset
> 
> Helper function to find the sector offset in a bio given bvec index
> and page offset.

Looks good, I've applied patches 1-5.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-10-02 17:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-01  7:38 Block integrity patches for 2.6.28 Martin K. Petersen
2008-10-01  7:38 ` [PATCH 1/7] block: Introduce integrity data ownership flag Martin K. Petersen
2008-10-01  7:38 ` [PATCH 2/7] block: Fix double put in blk_integrity_unregister Martin K. Petersen
2008-10-01  7:38 ` [PATCH 3/7] block: Switch blk_integrity_compare from bdev to gendisk Martin K. Petersen
2008-10-01  7:38 ` [PATCH 4/7] block: gendisk integrity wrapper Martin K. Petersen
2008-10-01  7:38 ` [PATCH 5/7] block: Find bio sector offset given idx and offset Martin K. Petersen
2008-10-01  8:10   ` Jens Axboe
2008-10-02  2:42     ` Martin K. Petersen
2008-10-02 17:07       ` Jens Axboe
2008-10-01  7:38 ` [PATCH 6/7] dm: Add support for data integrity to DM Martin K. Petersen
2008-10-01  7:38 ` [PATCH 7/7] md: Add support for data integrity to MD Martin K. Petersen
2008-10-02 10:56 ` Block integrity patches for 2.6.28 Jens Axboe
2008-10-02 13:54   ` Martin K. Petersen
2008-10-02 16:29     ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).