Skip to content

Commit 2729a60

Browse files
Christoph Hellwigbrauner
authored andcommitted
block: don't silently ignore metadata for sync read/write
The block fops don't try to handle metadata for synchronous requests, probably because the completion handler looks at dio->iocb which is not valid for synchronous requests. But silently ignoring metadata (or warning in case of __blkdev_direct_IO_simple) is a really bad idea as that can cause silent data corruption if a user ever shows up. Instead simply handle metadata for synchronous requests as the completion handler can simply check for bio_integrity() as the block layer default integrity will already be freed at this point, and thus bio_integrity() will only return true for user mapped integrity. Fixes: 3d8b5a2 ("block: add support to pass user meta buffer") Signed-off-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/[email protected] Reviewed-by: Martin K. Petersen <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent d072148 commit 2729a60

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

block/fops.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
5555
struct bio bio;
5656
ssize_t ret;
5757

58-
WARN_ON_ONCE(iocb->ki_flags & IOCB_HAS_METADATA);
5958
if (nr_pages <= DIO_INLINE_BIO_VECS)
6059
vecs = inline_vecs;
6160
else {
@@ -132,7 +131,7 @@ static void blkdev_bio_end_io(struct bio *bio)
132131
if (bio->bi_status && !dio->bio.bi_status)
133132
dio->bio.bi_status = bio->bi_status;
134133

135-
if (!is_sync && (dio->iocb->ki_flags & IOCB_HAS_METADATA))
134+
if (bio_integrity(bio))
136135
bio_integrity_unmap_user(bio);
137136

138137
if (atomic_dec_and_test(&dio->ref)) {
@@ -234,7 +233,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
234233
}
235234
bio->bi_opf |= REQ_NOWAIT;
236235
}
237-
if (!is_sync && (iocb->ki_flags & IOCB_HAS_METADATA)) {
236+
if (iocb->ki_flags & IOCB_HAS_METADATA) {
238237
ret = bio_integrity_map_iter(bio, iocb->private);
239238
if (unlikely(ret))
240239
goto fail;
@@ -302,7 +301,7 @@ static void blkdev_bio_end_io_async(struct bio *bio)
302301
ret = blk_status_to_errno(bio->bi_status);
303302
}
304303

305-
if (iocb->ki_flags & IOCB_HAS_METADATA)
304+
if (bio_integrity(bio))
306305
bio_integrity_unmap_user(bio);
307306

308307
iocb->ki_complete(iocb, ret);
@@ -423,7 +422,8 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
423422
}
424423

425424
nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1);
426-
if (likely(nr_pages <= BIO_MAX_VECS)) {
425+
if (likely(nr_pages <= BIO_MAX_VECS &&
426+
!(iocb->ki_flags & IOCB_HAS_METADATA))) {
427427
if (is_sync_kiocb(iocb))
428428
return __blkdev_direct_IO_simple(iocb, iter, bdev,
429429
nr_pages);

0 commit comments

Comments
 (0)