]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/block-integrity-update
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / block-integrity-update
1 Subject: Block integrity update
2 From: Martin K. Petersen <martin.petersen@oracle.com>
3 Date: Mon Dec 8 09:36:35 2008 +0100:
4 References: FATE#304345
5
6 This patch series contains block layer integrity updates for 2.6.28.
7
8 There are a few fixes to the core bits, including a switch from
9 block_device to gendisk in the integrity compare function. I also had
10 to add a helper to access a gendisk's integrity profile. This is used
11 by MD.
12
13 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
14 Signed-off-by: Hannes Reinecke <hare@suse.de>
15
16 ---
17 block/blk-integrity.c | 30 +++++++++++++++---------------
18 fs/bio-integrity.c | 3 ++-
19 fs/bio.c | 36 ++++++++++++++++++++++++++++++++++++
20 include/linux/bio.h | 2 ++
21 include/linux/blkdev.h | 8 +++++++-
22 5 files changed, 62 insertions(+), 17 deletions(-)
23
24 --- a/block/blk-integrity.c
25 +++ b/block/blk-integrity.c
26 @@ -108,51 +108,51 @@ new_segment:
27 EXPORT_SYMBOL(blk_rq_map_integrity_sg);
28
29 /**
30 - * blk_integrity_compare - Compare integrity profile of two block devices
31 - * @bd1: Device to compare
32 - * @bd2: Device to compare
33 + * blk_integrity_compare - Compare integrity profile of two disks
34 + * @gd1: Disk to compare
35 + * @gd2: Disk to compare
36 *
37 * Description: Meta-devices like DM and MD need to verify that all
38 * sub-devices use the same integrity format before advertising to
39 * upper layers that they can send/receive integrity metadata. This
40 - * function can be used to check whether two block devices have
41 + * function can be used to check whether two gendisk devices have
42 * compatible integrity formats.
43 */
44 -int blk_integrity_compare(struct block_device *bd1, struct block_device *bd2)
45 +int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
46 {
47 - struct blk_integrity *b1 = bd1->bd_disk->integrity;
48 - struct blk_integrity *b2 = bd2->bd_disk->integrity;
49 + struct blk_integrity *b1 = gd1->integrity;
50 + struct blk_integrity *b2 = gd2->integrity;
51
52 - BUG_ON(bd1->bd_disk == NULL);
53 - BUG_ON(bd2->bd_disk == NULL);
54 + if (!b1 && !b2)
55 + return 0;
56
57 if (!b1 || !b2)
58 - return 0;
59 + return -1;
60
61 if (b1->sector_size != b2->sector_size) {
62 printk(KERN_ERR "%s: %s/%s sector sz %u != %u\n", __func__,
63 - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
64 + gd1->disk_name, gd2->disk_name,
65 b1->sector_size, b2->sector_size);
66 return -1;
67 }
68
69 if (b1->tuple_size != b2->tuple_size) {
70 printk(KERN_ERR "%s: %s/%s tuple sz %u != %u\n", __func__,
71 - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
72 + gd1->disk_name, gd2->disk_name,
73 b1->tuple_size, b2->tuple_size);
74 return -1;
75 }
76
77 if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) {
78 printk(KERN_ERR "%s: %s/%s tag sz %u != %u\n", __func__,
79 - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
80 + gd1->disk_name, gd2->disk_name,
81 b1->tag_size, b2->tag_size);
82 return -1;
83 }
84
85 if (strcmp(b1->name, b2->name)) {
86 printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__,
87 - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
88 + gd1->disk_name, gd2->disk_name,
89 b1->name, b2->name);
90 return -1;
91 }
92 @@ -375,7 +375,7 @@ void blk_integrity_unregister(struct gen
93
94 kobject_uevent(&bi->kobj, KOBJ_REMOVE);
95 kobject_del(&bi->kobj);
96 - kobject_put(&disk->dev.kobj);
97 kmem_cache_free(integrity_cachep, bi);
98 + disk->integrity = NULL;
99 }
100 EXPORT_SYMBOL(blk_integrity_unregister);
101 --- a/fs/bio.c
102 +++ b/fs/bio.c
103 @@ -1274,6 +1274,42 @@ struct bio_pair *bio_split(struct bio *b
104 return bp;
105 }
106
107 +/**
108 + * bio_sector_offset - Find hardware sector offset in bio
109 + * @bio: bio to inspect
110 + * @index: bio_vec index
111 + * @offset: offset in bv_page
112 + *
113 + * Return the number of hardware sectors between beginning of bio
114 + * and an end point indicated by a bio_vec index and an offset
115 + * within that vector's page.
116 + */
117 +sector_t bio_sector_offset(struct bio *bio, unsigned short index,
118 + unsigned int offset)
119 +{
120 + unsigned int sector_sz = queue_hardsect_size(bio->bi_bdev->bd_disk->queue);
121 + struct bio_vec *bv;
122 + sector_t sectors;
123 + int i;
124 +
125 + sectors = 0;
126 +
127 + if (index >= bio->bi_idx)
128 + index = bio->bi_vcnt - 1;
129 +
130 + __bio_for_each_segment(bv, bio, i, 0) {
131 + if (i == index) {
132 + if (offset > bv->bv_offset)
133 + sectors += (offset - bv->bv_offset) / sector_sz;
134 + break;
135 + }
136 +
137 + sectors += bv->bv_len / sector_sz;
138 + }
139 +
140 + return sectors;
141 +}
142 +EXPORT_SYMBOL(bio_sector_offset);
143
144 /*
145 * create memory pools for biovec's in a bio_set.
146 --- a/fs/bio-integrity.c
147 +++ b/fs/bio-integrity.c
148 @@ -107,7 +107,8 @@ void bio_integrity_free(struct bio *bio,
149 BUG_ON(bip == NULL);
150
151 /* A cloned bio doesn't own the integrity metadata */
152 - if (!bio_flagged(bio, BIO_CLONED) && bip->bip_buf != NULL)
153 + if (!bio_flagged(bio, BIO_CLONED) && !bio_flagged(bio, BIO_FS_INTEGRITY)
154 + && bip->bip_buf != NULL)
155 kfree(bip->bip_buf);
156
157 mempool_free(bip->bip_vec, bs->bvec_pools[bip->bip_pool]);
158 --- a/include/linux/bio.h
159 +++ b/include/linux/bio.h
160 @@ -115,6 +115,7 @@ struct bio {
161 #define BIO_USER_MAPPED 6 /* contains user pages */
162 #define BIO_EOPNOTSUPP 7 /* not supported */
163 #define BIO_CPU_AFFINE 8 /* complete bio on same CPU as submitted */
164 +#define BIO_FS_INTEGRITY 10 /* fs owns integrity data, not block layer */
165 #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
166
167 /*
168 @@ -331,6 +332,7 @@ extern int bio_add_page(struct bio *, st
169 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
170 unsigned int, unsigned int);
171 extern int bio_get_nr_vecs(struct block_device *);
172 +extern sector_t bio_sector_offset(struct bio *, unsigned short, unsigned int);
173 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
174 unsigned long, unsigned int, int);
175 struct sg_iovec;
176 --- a/include/linux/blkdev.h
177 +++ b/include/linux/blkdev.h
178 @@ -980,7 +980,7 @@ struct blk_integrity {
179
180 extern int blk_integrity_register(struct gendisk *, struct blk_integrity *);
181 extern void blk_integrity_unregister(struct gendisk *);
182 -extern int blk_integrity_compare(struct block_device *, struct block_device *);
183 +extern int blk_integrity_compare(struct gendisk *, struct gendisk *);
184 extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *);
185 extern int blk_rq_count_integrity_sg(struct request *);
186
187 @@ -997,6 +997,11 @@ static inline struct blk_integrity *bdev
188 return bdev->bd_disk->integrity;
189 }
190
191 +static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
192 +{
193 + return disk->integrity;
194 +}
195 +
196 static inline unsigned int bdev_get_tag_size(struct block_device *bdev)
197 {
198 struct blk_integrity *bi = bdev_get_integrity(bdev);
199 @@ -1039,6 +1044,7 @@ static inline int blk_integrity_rq(struc
200 #define blk_rq_count_integrity_sg(a) (0)
201 #define blk_rq_map_integrity_sg(a, b) (0)
202 #define bdev_get_integrity(a) (0)
203 +#define blk_get_integrity(a) (0)
204 #define bdev_get_tag_size(a) (0)
205 #define blk_integrity_compare(a, b) (0)
206 #define blk_integrity_register(a, b) (0)