summaryrefslogtreecommitdiff
path: root/block/bio.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2020-01-05 09:41:14 +0800
committerJens Axboe <axboe@kernel.dk>2020-01-09 08:16:12 -0700
commit83c9c547168e8b914ea6398430473a4de68c52cc (patch)
tree9134fc796f74f44136d488d92ab270f9b1cdf788 /block/bio.c
parent57415790f405534e5578d0106d806630c325dcb3 (diff)
fs: move guard_bio_eod() after bio_set_op_attrs
Commit 85a8ce62c2ea ("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: 85a8ce62c2ea ("block: add bio_truncate to fix guard_bio_eod") Signed-off-by: Ming Lei <ming.lei@redhat.com> Fold in kerneldoc and bio_op() change. Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/bio.c')
-rw-r--r--block/bio.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/block/bio.c b/block/bio.c
index 006bcc52a77e..94d697217887 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -538,6 +538,16 @@ void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start)
}
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)
{
struct bio_vec bv;
@@ -548,7 +558,7 @@ void bio_truncate(struct bio *bio, unsigned new_size)
if (new_size >= bio->bi_iter.bi_size)
return;
- if (bio_data_dir(bio) != READ)
+ if (bio_op(bio) != REQ_OP_READ)
goto exit;
bio_for_each_segment(bv, bio, iter) {