diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-08-07 14:14:32 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2013-11-08 11:02:31 -0500 |
commit | 6678d83f18386eb103f8345024e52c5abe61725c (patch) | |
tree | a40f84cb760584da430b4471b3cdad91db8e9831 | |
parent | e0ce0eacb3197ad6e4ae37006c73af9411f97ecc (diff) |
block: Consolidate duplicated bio_trim() implementations
Someone cut and pasted md's md_trim_bio() into xen-blkfront.c. Come on,
we should know better than this.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Neil Brown <neilb@suse.de>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/xen-blkfront.c | 53 | ||||
-rw-r--r-- | drivers/md/md.c | 40 | ||||
-rw-r--r-- | drivers/md/md.h | 1 | ||||
-rw-r--r-- | drivers/md/raid1.c | 10 | ||||
-rw-r--r-- | drivers/md/raid10.c | 18 | ||||
-rw-r--r-- | fs/bio.c | 46 | ||||
-rw-r--r-- | include/linux/bio.h | 1 |
7 files changed, 61 insertions, 108 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index a4660bbee8a6..8d53ed293606 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -1336,57 +1336,6 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
1336 | return 0; | 1336 | return 0; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | /* | ||
1340 | * This is a clone of md_trim_bio, used to split a bio into smaller ones | ||
1341 | */ | ||
1342 | static void trim_bio(struct bio *bio, int offset, int size) | ||
1343 | { | ||
1344 | /* 'bio' is a cloned bio which we need to trim to match | ||
1345 | * the given offset and size. | ||
1346 | * This requires adjusting bi_sector, bi_size, and bi_io_vec | ||
1347 | */ | ||
1348 | int i; | ||
1349 | struct bio_vec *bvec; | ||
1350 | int sofar = 0; | ||
1351 | |||
1352 | size <<= 9; | ||
1353 | if (offset == 0 && size == bio->bi_size) | ||
1354 | return; | ||
1355 | |||
1356 | bio->bi_sector += offset; | ||
1357 | bio->bi_size = size; | ||
1358 | offset <<= 9; | ||
1359 | clear_bit(BIO_SEG_VALID, &bio->bi_flags); | ||
1360 | |||
1361 | while (bio->bi_idx < bio->bi_vcnt && | ||
1362 | bio->bi_io_vec[bio->bi_idx].bv_len <= offset) { | ||
1363 | /* remove this whole bio_vec */ | ||
1364 | offset -= bio->bi_io_vec[bio->bi_idx].bv_len; | ||
1365 | bio->bi_idx++; | ||
1366 | } | ||
1367 | if (bio->bi_idx < bio->bi_vcnt) { | ||
1368 | bio->bi_io_vec[bio->bi_idx].bv_offset += offset; | ||
1369 | bio->bi_io_vec[bio->bi_idx].bv_len -= offset; | ||
1370 | } | ||
1371 | /* avoid any complications with bi_idx being non-zero*/ | ||
1372 | if (bio->bi_idx) { | ||
1373 | memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx, | ||
1374 | (bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec)); | ||
1375 | bio->bi_vcnt -= bio->bi_idx; | ||
1376 | bio->bi_idx = 0; | ||
1377 | } | ||
1378 | /* Make sure vcnt and last bv are not too big */ | ||
1379 | bio_for_each_segment(bvec, bio, i) { | ||
1380 | if (sofar + bvec->bv_len > size) | ||
1381 | bvec->bv_len = size - sofar; | ||
1382 | if (bvec->bv_len == 0) { | ||
1383 | bio->bi_vcnt = i; | ||
1384 | break; | ||
1385 | } | ||
1386 | sofar += bvec->bv_len; | ||
1387 | } | ||
1388 | } | ||
1389 | |||
1390 | static void split_bio_end(struct bio *bio, int error) | 1339 | static void split_bio_end(struct bio *bio, int error) |
1391 | { | 1340 | { |
1392 | struct split_bio *split_bio = bio->bi_private; | 1341 | struct split_bio *split_bio = bio->bi_private; |
@@ -1522,7 +1471,7 @@ static int blkif_recover(struct blkfront_info *info) | |||
1522 | (unsigned int)(bio->bi_size >> 9) - offset); | 1471 | (unsigned int)(bio->bi_size >> 9) - offset); |
1523 | cloned_bio = bio_clone(bio, GFP_NOIO); | 1472 | cloned_bio = bio_clone(bio, GFP_NOIO); |
1524 | BUG_ON(cloned_bio == NULL); | 1473 | BUG_ON(cloned_bio == NULL); |
1525 | trim_bio(cloned_bio, offset, size); | 1474 | bio_trim(cloned_bio, offset, size); |
1526 | cloned_bio->bi_private = split_bio; | 1475 | cloned_bio->bi_private = split_bio; |
1527 | cloned_bio->bi_end_io = split_bio_end; | 1476 | cloned_bio->bi_end_io = split_bio_end; |
1528 | submit_bio(cloned_bio->bi_rw, cloned_bio); | 1477 | submit_bio(cloned_bio->bi_rw, cloned_bio); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 561a65f82e26..752119068d66 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -183,46 +183,6 @@ struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask, | |||
183 | } | 183 | } |
184 | EXPORT_SYMBOL_GPL(bio_clone_mddev); | 184 | EXPORT_SYMBOL_GPL(bio_clone_mddev); |
185 | 185 | ||
186 | void md_trim_bio(struct bio *bio, int offset, int size) | ||
187 | { | ||
188 | /* 'bio' is a cloned bio which we need to trim to match | ||
189 | * the given offset and size. | ||
190 | * This requires adjusting bi_sector, bi_size, and bi_io_vec | ||
191 | */ | ||
192 | int i; | ||
193 | struct bio_vec *bvec; | ||
194 | int sofar = 0; | ||
195 | |||
196 | size <<= 9; | ||
197 | if (offset == 0 && size == bio->bi_size) | ||
198 | return; | ||
199 | |||
200 | clear_bit(BIO_SEG_VALID, &bio->bi_flags); | ||
201 | |||
202 | bio_advance(bio, offset << 9); | ||
203 | |||
204 | bio->bi_size = size; | ||
205 | |||
206 | /* avoid any complications with bi_idx being non-zero*/ | ||
207 | if (bio->bi_idx) { | ||
208 | memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx, | ||
209 | (bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec)); | ||
210 | bio->bi_vcnt -= bio->bi_idx; | ||
211 | bio->bi_idx = 0; | ||
212 | } | ||
213 | /* Make sure vcnt and last bv are not too big */ | ||
214 | bio_for_each_segment(bvec, bio, i) { | ||
215 | if (sofar + bvec->bv_len > size) | ||
216 | bvec->bv_len = size - sofar; | ||
217 | if (bvec->bv_len == 0) { | ||
218 | bio->bi_vcnt = i; | ||
219 | break; | ||
220 | } | ||
221 | sofar += bvec->bv_len; | ||
222 | } | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(md_trim_bio); | ||
225 | |||
226 | /* | 186 | /* |
227 | * We have a system wide 'event count' that is incremented | 187 | * We have a system wide 'event count' that is incremented |
228 | * on any 'interesting' event, and readers of /proc/mdstat | 188 | * on any 'interesting' event, and readers of /proc/mdstat |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 608050c43f17..c96456c16700 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -617,7 +617,6 @@ extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask, | |||
617 | struct mddev *mddev); | 617 | struct mddev *mddev); |
618 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, | 618 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, |
619 | struct mddev *mddev); | 619 | struct mddev *mddev); |
620 | extern void md_trim_bio(struct bio *bio, int offset, int size); | ||
621 | 620 | ||
622 | extern void md_unplug(struct blk_plug_cb *cb, bool from_schedule); | 621 | extern void md_unplug(struct blk_plug_cb *cb, bool from_schedule); |
623 | static inline int mddev_check_plugged(struct mddev *mddev) | 622 | static inline int mddev_check_plugged(struct mddev *mddev) |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index aacf6bf352d8..af6681b19776 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1097,8 +1097,8 @@ read_again: | |||
1097 | r1_bio->read_disk = rdisk; | 1097 | r1_bio->read_disk = rdisk; |
1098 | 1098 | ||
1099 | read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1099 | read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
1100 | md_trim_bio(read_bio, r1_bio->sector - bio->bi_sector, | 1100 | bio_trim(read_bio, r1_bio->sector - bio->bi_sector, |
1101 | max_sectors); | 1101 | max_sectors); |
1102 | 1102 | ||
1103 | r1_bio->bios[rdisk] = read_bio; | 1103 | r1_bio->bios[rdisk] = read_bio; |
1104 | 1104 | ||
@@ -1266,7 +1266,7 @@ read_again: | |||
1266 | continue; | 1266 | continue; |
1267 | 1267 | ||
1268 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1268 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
1269 | md_trim_bio(mbio, r1_bio->sector - bio->bi_sector, max_sectors); | 1269 | bio_trim(mbio, r1_bio->sector - bio->bi_sector, max_sectors); |
1270 | 1270 | ||
1271 | if (first_clone) { | 1271 | if (first_clone) { |
1272 | /* do behind I/O ? | 1272 | /* do behind I/O ? |
@@ -2126,7 +2126,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i) | |||
2126 | wbio->bi_sector = r1_bio->sector; | 2126 | wbio->bi_sector = r1_bio->sector; |
2127 | wbio->bi_size = r1_bio->sectors << 9; | 2127 | wbio->bi_size = r1_bio->sectors << 9; |
2128 | 2128 | ||
2129 | md_trim_bio(wbio, sector - r1_bio->sector, sectors); | 2129 | bio_trim(wbio, sector - r1_bio->sector, sectors); |
2130 | wbio->bi_sector += rdev->data_offset; | 2130 | wbio->bi_sector += rdev->data_offset; |
2131 | wbio->bi_bdev = rdev->bdev; | 2131 | wbio->bi_bdev = rdev->bdev; |
2132 | if (submit_bio_wait(WRITE, wbio) == 0) | 2132 | if (submit_bio_wait(WRITE, wbio) == 0) |
@@ -2241,7 +2241,7 @@ read_more: | |||
2241 | } | 2241 | } |
2242 | r1_bio->read_disk = disk; | 2242 | r1_bio->read_disk = disk; |
2243 | bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev); | 2243 | bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev); |
2244 | md_trim_bio(bio, r1_bio->sector - bio->bi_sector, max_sectors); | 2244 | bio_trim(bio, r1_bio->sector - bio->bi_sector, max_sectors); |
2245 | r1_bio->bios[r1_bio->read_disk] = bio; | 2245 | r1_bio->bios[r1_bio->read_disk] = bio; |
2246 | rdev = conf->mirrors[disk].rdev; | 2246 | rdev = conf->mirrors[disk].rdev; |
2247 | printk_ratelimited(KERN_ERR | 2247 | printk_ratelimited(KERN_ERR |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 73dc8a377522..7c3508abb5e1 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1302,8 +1302,8 @@ read_again: | |||
1302 | slot = r10_bio->read_slot; | 1302 | slot = r10_bio->read_slot; |
1303 | 1303 | ||
1304 | read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1304 | read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
1305 | md_trim_bio(read_bio, r10_bio->sector - bio->bi_sector, | 1305 | bio_trim(read_bio, r10_bio->sector - bio->bi_sector, |
1306 | max_sectors); | 1306 | max_sectors); |
1307 | 1307 | ||
1308 | r10_bio->devs[slot].bio = read_bio; | 1308 | r10_bio->devs[slot].bio = read_bio; |
1309 | r10_bio->devs[slot].rdev = rdev; | 1309 | r10_bio->devs[slot].rdev = rdev; |
@@ -1510,8 +1510,8 @@ retry_write: | |||
1510 | if (r10_bio->devs[i].bio) { | 1510 | if (r10_bio->devs[i].bio) { |
1511 | struct md_rdev *rdev = conf->mirrors[d].rdev; | 1511 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
1512 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1512 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
1513 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | 1513 | bio_trim(mbio, r10_bio->sector - bio->bi_sector, |
1514 | max_sectors); | 1514 | max_sectors); |
1515 | r10_bio->devs[i].bio = mbio; | 1515 | r10_bio->devs[i].bio = mbio; |
1516 | 1516 | ||
1517 | mbio->bi_sector = (r10_bio->devs[i].addr+ | 1517 | mbio->bi_sector = (r10_bio->devs[i].addr+ |
@@ -1553,8 +1553,8 @@ retry_write: | |||
1553 | rdev = conf->mirrors[d].rdev; | 1553 | rdev = conf->mirrors[d].rdev; |
1554 | } | 1554 | } |
1555 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1555 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
1556 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | 1556 | bio_trim(mbio, r10_bio->sector - bio->bi_sector, |
1557 | max_sectors); | 1557 | max_sectors); |
1558 | r10_bio->devs[i].repl_bio = mbio; | 1558 | r10_bio->devs[i].repl_bio = mbio; |
1559 | 1559 | ||
1560 | mbio->bi_sector = (r10_bio->devs[i].addr + | 1560 | mbio->bi_sector = (r10_bio->devs[i].addr + |
@@ -2614,7 +2614,7 @@ static int narrow_write_error(struct r10bio *r10_bio, int i) | |||
2614 | sectors = sect_to_write; | 2614 | sectors = sect_to_write; |
2615 | /* Write at 'sector' for 'sectors' */ | 2615 | /* Write at 'sector' for 'sectors' */ |
2616 | wbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 2616 | wbio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
2617 | md_trim_bio(wbio, sector - bio->bi_sector, sectors); | 2617 | bio_trim(wbio, sector - bio->bi_sector, sectors); |
2618 | wbio->bi_sector = (r10_bio->devs[i].addr+ | 2618 | wbio->bi_sector = (r10_bio->devs[i].addr+ |
2619 | choose_data_offset(r10_bio, rdev) + | 2619 | choose_data_offset(r10_bio, rdev) + |
2620 | (sector - r10_bio->sector)); | 2620 | (sector - r10_bio->sector)); |
@@ -2687,9 +2687,7 @@ read_more: | |||
2687 | (unsigned long long)r10_bio->sector); | 2687 | (unsigned long long)r10_bio->sector); |
2688 | bio = bio_clone_mddev(r10_bio->master_bio, | 2688 | bio = bio_clone_mddev(r10_bio->master_bio, |
2689 | GFP_NOIO, mddev); | 2689 | GFP_NOIO, mddev); |
2690 | md_trim_bio(bio, | 2690 | bio_trim(bio, r10_bio->sector - bio->bi_sector, max_sectors); |
2691 | r10_bio->sector - bio->bi_sector, | ||
2692 | max_sectors); | ||
2693 | r10_bio->devs[slot].bio = bio; | 2691 | r10_bio->devs[slot].bio = bio; |
2694 | r10_bio->devs[slot].rdev = rdev; | 2692 | r10_bio->devs[slot].rdev = rdev; |
2695 | bio->bi_sector = r10_bio->devs[slot].addr | 2693 | bio->bi_sector = r10_bio->devs[slot].addr |
@@ -1805,6 +1805,52 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors) | |||
1805 | EXPORT_SYMBOL(bio_split); | 1805 | EXPORT_SYMBOL(bio_split); |
1806 | 1806 | ||
1807 | /** | 1807 | /** |
1808 | * bio_trim - trim a bio | ||
1809 | * @bio: bio to trim | ||
1810 | * @offset: number of sectors to trim from the front of @bio | ||
1811 | * @size: size we want to trim @bio to, in sectors | ||
1812 | */ | ||
1813 | void bio_trim(struct bio *bio, int offset, int size) | ||
1814 | { | ||
1815 | /* 'bio' is a cloned bio which we need to trim to match | ||
1816 | * the given offset and size. | ||
1817 | * This requires adjusting bi_sector, bi_size, and bi_io_vec | ||
1818 | */ | ||
1819 | int i; | ||
1820 | struct bio_vec *bvec; | ||
1821 | int sofar = 0; | ||
1822 | |||
1823 | size <<= 9; | ||
1824 | if (offset == 0 && size == bio->bi_size) | ||
1825 | return; | ||
1826 | |||
1827 | clear_bit(BIO_SEG_VALID, &bio->bi_flags); | ||
1828 | |||
1829 | bio_advance(bio, offset << 9); | ||
1830 | |||
1831 | bio->bi_size = size; | ||
1832 | |||
1833 | /* avoid any complications with bi_idx being non-zero*/ | ||
1834 | if (bio->bi_idx) { | ||
1835 | memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx, | ||
1836 | (bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec)); | ||
1837 | bio->bi_vcnt -= bio->bi_idx; | ||
1838 | bio->bi_idx = 0; | ||
1839 | } | ||
1840 | /* Make sure vcnt and last bv are not too big */ | ||
1841 | bio_for_each_segment(bvec, bio, i) { | ||
1842 | if (sofar + bvec->bv_len > size) | ||
1843 | bvec->bv_len = size - sofar; | ||
1844 | if (bvec->bv_len == 0) { | ||
1845 | bio->bi_vcnt = i; | ||
1846 | break; | ||
1847 | } | ||
1848 | sofar += bvec->bv_len; | ||
1849 | } | ||
1850 | } | ||
1851 | EXPORT_SYMBOL_GPL(bio_trim); | ||
1852 | |||
1853 | /** | ||
1808 | * bio_sector_offset - Find hardware sector offset in bio | 1854 | * bio_sector_offset - Find hardware sector offset in bio |
1809 | * @bio: bio to inspect | 1855 | * @bio: bio to inspect |
1810 | * @index: bio_vec index | 1856 | * @index: bio_vec index |
diff --git a/include/linux/bio.h b/include/linux/bio.h index ec48bac5b039..162036aca741 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -218,6 +218,7 @@ struct bio_pair { | |||
218 | }; | 218 | }; |
219 | extern struct bio_pair *bio_split(struct bio *bi, int first_sectors); | 219 | extern struct bio_pair *bio_split(struct bio *bi, int first_sectors); |
220 | extern void bio_pair_release(struct bio_pair *dbio); | 220 | extern void bio_pair_release(struct bio_pair *dbio); |
221 | extern void bio_trim(struct bio *bio, int offset, int size); | ||
221 | 222 | ||
222 | extern struct bio_set *bioset_create(unsigned int, unsigned int); | 223 | extern struct bio_set *bioset_create(unsigned int, unsigned int); |
223 | extern void bioset_free(struct bio_set *); | 224 | extern void bioset_free(struct bio_set *); |