diff options
Diffstat (limited to 'fs/bio.c')
-rw-r--r-- | fs/bio.c | 23 |
1 files changed, 11 insertions, 12 deletions
@@ -1006,13 +1006,14 @@ void bio_check_pages_dirty(struct bio *bio) * @error: error, if any * * Description: - * bio_endio() will end I/O on @bytes_done number of bytes. This may be - * just a partial part of the bio, or it may be the whole bio. bio_endio() - * is the preferred way to end I/O on a bio, it takes care of decrementing - * bi_size and clearing BIO_UPTODATE on error. @error is 0 on success, and - * and one of the established -Exxxx (-EIO, for instance) error values in - * case something went wrong. Noone should call bi_end_io() directly on - * a bio unless they own it and thus know that it has an end_io function. + * bio_endio() will end I/O on @bytes_done number of bytes. This + * must always be the whole (remaining) bio. bio_endio() is the + * preferred way to end I/O on a bio, it takes care of clearing + * BIO_UPTODATE on error. @error is 0 on success, and and one of the + * established -Exxxx (-EIO, for instance) error values in case + * something went wrong. Noone should call bi_end_io() directly on a + * bio unless they own it and thus know that it has an end_io + * function. **/ void bio_endio(struct bio *bio, unsigned int bytes_done, int error) { @@ -1021,16 +1022,14 @@ void bio_endio(struct bio *bio, unsigned int bytes_done, int error) else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) error = -EIO; - if (unlikely(bytes_done > bio->bi_size)) { + if (unlikely(bytes_done != bio->bi_size)) { printk("%s: want %u bytes done, only %u left\n", __FUNCTION__, bytes_done, bio->bi_size); bytes_done = bio->bi_size; } - bio->bi_size -= bytes_done; - bio->bi_sector += (bytes_done >> 9); - - if (bio->bi_size && bio->bi_end_io) + bio->bi_size = 0; /* expected by some callees - will be removed */ + if (bio->bi_end_io) bio->bi_end_io(bio, bytes_done, error); } |