fs: move guard_bio_eod() after bio_set_op_attrs
commit5.4-rM2-2.2.x-imx-squashed83c9c54716
upstream. Commit85a8ce62c2
("block: add bio_truncate to fix guard_bio_eod") adds bio_truncate() for handling bio EOD. However, bio_truncate() doesn't use the passed 'op' parameter from guard_bio_eod's callers. So bio_trunacate() may retrieve wrong 'op', and zering pages may not be done for READ bio. Fixes this issue by moving guard_bio_eod() after bio_set_op_attrs() in submit_bh_wbc() so that bio_truncate() can always retrieve correct op info. Meantime remove the 'op' parameter from guard_bio_eod() because it isn't used any more. Cc: Carlos Maiolino <cmaiolino@redhat.com> Cc: linux-fsdevel@vger.kernel.org Fixes:85a8ce62c2
("block: add bio_truncate to fix guard_bio_eod") Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Fold in kerneldoc and bio_op() change. Signed-off-by: Jens Axboe <axboe@kernel.dk>
parent
80a332f418
commit
3fe209c843
12
block/bio.c
12
block/bio.c
|
@ -535,6 +535,16 @@ void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(zero_fill_bio_iter);
|
EXPORT_SYMBOL(zero_fill_bio_iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bio_truncate - truncate the bio to small size of @new_size
|
||||||
|
* @bio: the bio to be truncated
|
||||||
|
* @new_size: new size for truncating the bio
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Truncate the bio to new size of @new_size. If bio_op(bio) is
|
||||||
|
* REQ_OP_READ, zero the truncated part. This function should only
|
||||||
|
* be used for handling corner cases, such as bio eod.
|
||||||
|
*/
|
||||||
void bio_truncate(struct bio *bio, unsigned new_size)
|
void bio_truncate(struct bio *bio, unsigned new_size)
|
||||||
{
|
{
|
||||||
struct bio_vec bv;
|
struct bio_vec bv;
|
||||||
|
@ -545,7 +555,7 @@ void bio_truncate(struct bio *bio, unsigned new_size)
|
||||||
if (new_size >= bio->bi_iter.bi_size)
|
if (new_size >= bio->bi_iter.bi_size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bio_data_dir(bio) != READ)
|
if (bio_op(bio) != REQ_OP_READ)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
bio_for_each_segment(bv, bio, iter) {
|
bio_for_each_segment(bv, bio, iter) {
|
||||||
|
|
|
@ -2991,7 +2991,7 @@ static void end_bio_bh_io_sync(struct bio *bio)
|
||||||
* errors, this only handles the "we need to be able to
|
* errors, this only handles the "we need to be able to
|
||||||
* do IO at the final sector" case.
|
* do IO at the final sector" case.
|
||||||
*/
|
*/
|
||||||
void guard_bio_eod(int op, struct bio *bio)
|
void guard_bio_eod(struct bio *bio)
|
||||||
{
|
{
|
||||||
sector_t maxsector;
|
sector_t maxsector;
|
||||||
struct hd_struct *part;
|
struct hd_struct *part;
|
||||||
|
@ -3055,15 +3055,15 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
|
||||||
bio->bi_end_io = end_bio_bh_io_sync;
|
bio->bi_end_io = end_bio_bh_io_sync;
|
||||||
bio->bi_private = bh;
|
bio->bi_private = bh;
|
||||||
|
|
||||||
/* Take care of bh's that straddle the end of the device */
|
|
||||||
guard_bio_eod(op, bio);
|
|
||||||
|
|
||||||
if (buffer_meta(bh))
|
if (buffer_meta(bh))
|
||||||
op_flags |= REQ_META;
|
op_flags |= REQ_META;
|
||||||
if (buffer_prio(bh))
|
if (buffer_prio(bh))
|
||||||
op_flags |= REQ_PRIO;
|
op_flags |= REQ_PRIO;
|
||||||
bio_set_op_attrs(bio, op, op_flags);
|
bio_set_op_attrs(bio, op, op_flags);
|
||||||
|
|
||||||
|
/* Take care of bh's that straddle the end of the device */
|
||||||
|
guard_bio_eod(bio);
|
||||||
|
|
||||||
if (wbc) {
|
if (wbc) {
|
||||||
wbc_init_bio(wbc, bio);
|
wbc_init_bio(wbc, bio);
|
||||||
wbc_account_cgroup_owner(wbc, bh->b_page, bh->b_size);
|
wbc_account_cgroup_owner(wbc, bh->b_page, bh->b_size);
|
||||||
|
|
|
@ -38,7 +38,7 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait)
|
||||||
/*
|
/*
|
||||||
* buffer.c
|
* buffer.c
|
||||||
*/
|
*/
|
||||||
extern void guard_bio_eod(int rw, struct bio *bio);
|
extern void guard_bio_eod(struct bio *bio);
|
||||||
extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len,
|
extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len,
|
||||||
get_block_t *get_block, struct iomap *iomap);
|
get_block_t *get_block, struct iomap *iomap);
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_end_io = mpage_end_io;
|
bio->bi_end_io = mpage_end_io;
|
||||||
bio_set_op_attrs(bio, op, op_flags);
|
bio_set_op_attrs(bio, op, op_flags);
|
||||||
guard_bio_eod(op, bio);
|
guard_bio_eod(bio);
|
||||||
submit_bio(bio);
|
submit_bio(bio);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue