Re: [PATCH 1/2] block: add bio_rewind() to reset bio_vec

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jens,
 (I tried sending this a week ago but managed to not include your email - no
  wonder I didn't get a reply!)

 Are you OK with adding this to fs/bio.c?
 The follow-on patch which uses it to fix a crash in md in 3.10 is at 
    http://marc.info/?l=linux-raid&m=137331514131503&w=2

 If so: will you submit or should I?  Both patches are in my "for-next" and
 so should be in linux-next.

 If not, I'll just do something local in raid1 to reset the bio before
 calling bio_copy_data().

Thanks,
NeilBrown


On Mon,  8 Jul 2013 16:25:13 -0400 Joe Lawrence <joe.lawrence@xxxxxxxxxxx>
wrote:

> Provide a mechanism for drivers to "rewind" a bio, essentially undoing
> all bio_advance() calls on the bio. After the rewind, the bio idx will
> be 0, size and sector reset, and each bio_vec len and offset restored to
> their initial values.
> 
> Suggested-by: NeilBrown <neilb@xxxxxxx>
> Signed-off-by: Joe Lawrence <joe.lawrence@xxxxxxxxxxx>
> ---
>  fs/bio.c            | 27 +++++++++++++++++++++++++++
>  include/linux/bio.h |  1 +
>  2 files changed, 28 insertions(+)
> 
> diff --git a/fs/bio.c b/fs/bio.c
> index 94bbc04..04309df 100644
> --- a/fs/bio.c
> +++ b/fs/bio.c
> @@ -833,6 +833,33 @@ void bio_advance(struct bio *bio, unsigned bytes)
>  EXPORT_SYMBOL(bio_advance);
>  
>  /**
> + * bio_rewind - reset a bio to its start
> + * @bio:        bio to rewind
> + *
> + * This resets bi_sector, bi_size and bi_idx; completely undoing all
> + * bio_advances on the @bio.
> + */
> +void bio_rewind(struct bio *bio)
> +{
> +	int bytes = 0;
> +
> +	if (bio->bi_idx < bio->bi_vcnt && bio_iovec(bio)->bv_offset > 0) {
> +		bytes = bio_iovec(bio)->bv_offset;
> +		bio_iovec(bio)->bv_offset -= bytes;
> +		bio_iovec(bio)->bv_len += bytes;
> +	}
> +	while (bio->bi_idx) {
> +		bio->bi_idx -= 1;
> +		bio_iovec(bio)->bv_len += bio_iovec(bio)->bv_offset;
> +		bio_iovec(bio)->bv_offset = 0;
> +		bytes += bio_iovec(bio)->bv_len;
> +	}
> +	bio->bi_size += bytes;
> +	bio->bi_sector -= bytes >> 9;
> +}
> +EXPORT_SYMBOL(bio_rewind);
> +
> +/**
>   * bio_alloc_pages - allocates a single page for each bvec in a bio
>   * @bio: bio to allocate pages for
>   * @gfp_mask: flags for allocation
> diff --git a/include/linux/bio.h b/include/linux/bio.h
> index ef24466..e2082fb 100644
> --- a/include/linux/bio.h
> +++ b/include/linux/bio.h
> @@ -258,6 +258,7 @@ extern int bio_phys_segments(struct request_queue *, struct bio *);
>  
>  extern int submit_bio_wait(int rw, struct bio *bio);
>  extern void bio_advance(struct bio *, unsigned);
> +extern void bio_rewind(struct bio *);
>  
>  extern void bio_init(struct bio *);
>  extern void bio_reset(struct bio *);

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux