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>
This commit is contained in:
Родитель
e0ce0eacb3
Коммит
6678d83f18
|
@ -1336,57 +1336,6 @@ static int blkfront_probe(struct xenbus_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a clone of md_trim_bio, used to split a bio into smaller ones
|
||||
*/
|
||||
static void trim_bio(struct bio *bio, int offset, int size)
|
||||
{
|
||||
/* 'bio' is a cloned bio which we need to trim to match
|
||||
* the given offset and size.
|
||||
* This requires adjusting bi_sector, bi_size, and bi_io_vec
|
||||
*/
|
||||
int i;
|
||||
struct bio_vec *bvec;
|
||||
int sofar = 0;
|
||||
|
||||
size <<= 9;
|
||||
if (offset == 0 && size == bio->bi_size)
|
||||
return;
|
||||
|
||||
bio->bi_sector += offset;
|
||||
bio->bi_size = size;
|
||||
offset <<= 9;
|
||||
clear_bit(BIO_SEG_VALID, &bio->bi_flags);
|
||||
|
||||
while (bio->bi_idx < bio->bi_vcnt &&
|
||||
bio->bi_io_vec[bio->bi_idx].bv_len <= offset) {
|
||||
/* remove this whole bio_vec */
|
||||
offset -= bio->bi_io_vec[bio->bi_idx].bv_len;
|
||||
bio->bi_idx++;
|
||||
}
|
||||
if (bio->bi_idx < bio->bi_vcnt) {
|
||||
bio->bi_io_vec[bio->bi_idx].bv_offset += offset;
|
||||
bio->bi_io_vec[bio->bi_idx].bv_len -= offset;
|
||||
}
|
||||
/* avoid any complications with bi_idx being non-zero*/
|
||||
if (bio->bi_idx) {
|
||||
memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx,
|
||||
(bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec));
|
||||
bio->bi_vcnt -= bio->bi_idx;
|
||||
bio->bi_idx = 0;
|
||||
}
|
||||
/* Make sure vcnt and last bv are not too big */
|
||||
bio_for_each_segment(bvec, bio, i) {
|
||||
if (sofar + bvec->bv_len > size)
|
||||
bvec->bv_len = size - sofar;
|
||||
if (bvec->bv_len == 0) {
|
||||
bio->bi_vcnt = i;
|
||||
break;
|
||||
}
|
||||
sofar += bvec->bv_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void split_bio_end(struct bio *bio, int error)
|
||||
{
|
||||
struct split_bio *split_bio = bio->bi_private;
|
||||
|
@ -1522,7 +1471,7 @@ static int blkif_recover(struct blkfront_info *info)
|
|||
(unsigned int)(bio->bi_size >> 9) - offset);
|
||||
cloned_bio = bio_clone(bio, GFP_NOIO);
|
||||
BUG_ON(cloned_bio == NULL);
|
||||
trim_bio(cloned_bio, offset, size);
|
||||
bio_trim(cloned_bio, offset, size);
|
||||
cloned_bio->bi_private = split_bio;
|
||||
cloned_bio->bi_end_io = split_bio_end;
|
||||
submit_bio(cloned_bio->bi_rw, cloned_bio);
|
||||
|
|
|
@ -183,46 +183,6 @@ struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(bio_clone_mddev);
|
||||
|
||||
void md_trim_bio(struct bio *bio, int offset, int size)
|
||||
{
|
||||
/* 'bio' is a cloned bio which we need to trim to match
|
||||
* the given offset and size.
|
||||
* This requires adjusting bi_sector, bi_size, and bi_io_vec
|
||||
*/
|
||||
int i;
|
||||
struct bio_vec *bvec;
|
||||
int sofar = 0;
|
||||
|
||||
size <<= 9;
|
||||
if (offset == 0 && size == bio->bi_size)
|
||||
return;
|
||||
|
||||
clear_bit(BIO_SEG_VALID, &bio->bi_flags);
|
||||
|
||||
bio_advance(bio, offset << 9);
|
||||
|
||||
bio->bi_size = size;
|
||||
|
||||
/* avoid any complications with bi_idx being non-zero*/
|
||||
if (bio->bi_idx) {
|
||||
memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx,
|
||||
(bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec));
|
||||
bio->bi_vcnt -= bio->bi_idx;
|
||||
bio->bi_idx = 0;
|
||||
}
|
||||
/* Make sure vcnt and last bv are not too big */
|
||||
bio_for_each_segment(bvec, bio, i) {
|
||||
if (sofar + bvec->bv_len > size)
|
||||
bvec->bv_len = size - sofar;
|
||||
if (bvec->bv_len == 0) {
|
||||
bio->bi_vcnt = i;
|
||||
break;
|
||||
}
|
||||
sofar += bvec->bv_len;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(md_trim_bio);
|
||||
|
||||
/*
|
||||
* We have a system wide 'event count' that is incremented
|
||||
* on any 'interesting' event, and readers of /proc/mdstat
|
||||
|
|
|
@ -617,7 +617,6 @@ extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
|
|||
struct mddev *mddev);
|
||||
extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
|
||||
struct mddev *mddev);
|
||||
extern void md_trim_bio(struct bio *bio, int offset, int size);
|
||||
|
||||
extern void md_unplug(struct blk_plug_cb *cb, bool from_schedule);
|
||||
static inline int mddev_check_plugged(struct mddev *mddev)
|
||||
|
|
|
@ -1097,8 +1097,8 @@ read_again:
|
|||
r1_bio->read_disk = rdisk;
|
||||
|
||||
read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(read_bio, r1_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
bio_trim(read_bio, r1_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
|
||||
r1_bio->bios[rdisk] = read_bio;
|
||||
|
||||
|
@ -1266,7 +1266,7 @@ read_again:
|
|||
continue;
|
||||
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r1_bio->sector - bio->bi_sector, max_sectors);
|
||||
bio_trim(mbio, r1_bio->sector - bio->bi_sector, max_sectors);
|
||||
|
||||
if (first_clone) {
|
||||
/* do behind I/O ?
|
||||
|
@ -2126,7 +2126,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
|
|||
wbio->bi_sector = r1_bio->sector;
|
||||
wbio->bi_size = r1_bio->sectors << 9;
|
||||
|
||||
md_trim_bio(wbio, sector - r1_bio->sector, sectors);
|
||||
bio_trim(wbio, sector - r1_bio->sector, sectors);
|
||||
wbio->bi_sector += rdev->data_offset;
|
||||
wbio->bi_bdev = rdev->bdev;
|
||||
if (submit_bio_wait(WRITE, wbio) == 0)
|
||||
|
@ -2241,7 +2241,7 @@ read_more:
|
|||
}
|
||||
r1_bio->read_disk = disk;
|
||||
bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(bio, r1_bio->sector - bio->bi_sector, max_sectors);
|
||||
bio_trim(bio, r1_bio->sector - bio->bi_sector, max_sectors);
|
||||
r1_bio->bios[r1_bio->read_disk] = bio;
|
||||
rdev = conf->mirrors[disk].rdev;
|
||||
printk_ratelimited(KERN_ERR
|
||||
|
|
|
@ -1302,8 +1302,8 @@ read_again:
|
|||
slot = r10_bio->read_slot;
|
||||
|
||||
read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(read_bio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
bio_trim(read_bio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
|
||||
r10_bio->devs[slot].bio = read_bio;
|
||||
r10_bio->devs[slot].rdev = rdev;
|
||||
|
@ -1510,8 +1510,8 @@ retry_write:
|
|||
if (r10_bio->devs[i].bio) {
|
||||
struct md_rdev *rdev = conf->mirrors[d].rdev;
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
bio_trim(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
r10_bio->devs[i].bio = mbio;
|
||||
|
||||
mbio->bi_sector = (r10_bio->devs[i].addr+
|
||||
|
@ -1553,8 +1553,8 @@ retry_write:
|
|||
rdev = conf->mirrors[d].rdev;
|
||||
}
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
bio_trim(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
r10_bio->devs[i].repl_bio = mbio;
|
||||
|
||||
mbio->bi_sector = (r10_bio->devs[i].addr +
|
||||
|
@ -2614,7 +2614,7 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
|
|||
sectors = sect_to_write;
|
||||
/* Write at 'sector' for 'sectors' */
|
||||
wbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(wbio, sector - bio->bi_sector, sectors);
|
||||
bio_trim(wbio, sector - bio->bi_sector, sectors);
|
||||
wbio->bi_sector = (r10_bio->devs[i].addr+
|
||||
choose_data_offset(r10_bio, rdev) +
|
||||
(sector - r10_bio->sector));
|
||||
|
@ -2687,9 +2687,7 @@ read_more:
|
|||
(unsigned long long)r10_bio->sector);
|
||||
bio = bio_clone_mddev(r10_bio->master_bio,
|
||||
GFP_NOIO, mddev);
|
||||
md_trim_bio(bio,
|
||||
r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
bio_trim(bio, r10_bio->sector - bio->bi_sector, max_sectors);
|
||||
r10_bio->devs[slot].bio = bio;
|
||||
r10_bio->devs[slot].rdev = rdev;
|
||||
bio->bi_sector = r10_bio->devs[slot].addr
|
||||
|
|
46
fs/bio.c
46
fs/bio.c
|
@ -1804,6 +1804,52 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
|
|||
}
|
||||
EXPORT_SYMBOL(bio_split);
|
||||
|
||||
/**
|
||||
* bio_trim - trim a bio
|
||||
* @bio: bio to trim
|
||||
* @offset: number of sectors to trim from the front of @bio
|
||||
* @size: size we want to trim @bio to, in sectors
|
||||
*/
|
||||
void bio_trim(struct bio *bio, int offset, int size)
|
||||
{
|
||||
/* 'bio' is a cloned bio which we need to trim to match
|
||||
* the given offset and size.
|
||||
* This requires adjusting bi_sector, bi_size, and bi_io_vec
|
||||
*/
|
||||
int i;
|
||||
struct bio_vec *bvec;
|
||||
int sofar = 0;
|
||||
|
||||
size <<= 9;
|
||||
if (offset == 0 && size == bio->bi_size)
|
||||
return;
|
||||
|
||||
clear_bit(BIO_SEG_VALID, &bio->bi_flags);
|
||||
|
||||
bio_advance(bio, offset << 9);
|
||||
|
||||
bio->bi_size = size;
|
||||
|
||||
/* avoid any complications with bi_idx being non-zero*/
|
||||
if (bio->bi_idx) {
|
||||
memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx,
|
||||
(bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec));
|
||||
bio->bi_vcnt -= bio->bi_idx;
|
||||
bio->bi_idx = 0;
|
||||
}
|
||||
/* Make sure vcnt and last bv are not too big */
|
||||
bio_for_each_segment(bvec, bio, i) {
|
||||
if (sofar + bvec->bv_len > size)
|
||||
bvec->bv_len = size - sofar;
|
||||
if (bvec->bv_len == 0) {
|
||||
bio->bi_vcnt = i;
|
||||
break;
|
||||
}
|
||||
sofar += bvec->bv_len;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bio_trim);
|
||||
|
||||
/**
|
||||
* bio_sector_offset - Find hardware sector offset in bio
|
||||
* @bio: bio to inspect
|
||||
|
|
|
@ -218,6 +218,7 @@ struct bio_pair {
|
|||
};
|
||||
extern struct bio_pair *bio_split(struct bio *bi, int first_sectors);
|
||||
extern void bio_pair_release(struct bio_pair *dbio);
|
||||
extern void bio_trim(struct bio *bio, int offset, int size);
|
||||
|
||||
extern struct bio_set *bioset_create(unsigned int, unsigned int);
|
||||
extern void bioset_free(struct bio_set *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче