I/O accounting buckets I/O into the read/write/discard categories into
which passthrough I/O does not fit at all.  It also accounts to the
block_device, which may not even exist for passthrough I/O.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20220308055200.735835-2-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
 
 static void __blk_account_io_start(struct request *rq)
 {
-       /* passthrough requests can hold bios that do not have ->bi_bdev set */
-       if (rq->bio && rq->bio->bi_bdev)
+       /*
+        * All non-passthrough requests are created from a bio with one
+        * exception: when a flush command that is part of a flush sequence
+        * generated by the state machine in blk-flush.c is cloned onto the
+        * lower device by dm-multipath we can get here without a bio.
+        */
+       if (rq->bio)
                rq->part = rq->bio->bi_bdev;
-       else if (rq->q->disk)
+       else
                rq->part = rq->q->disk->part0;
 
        part_stat_lock();
 
  */
 static inline bool blk_do_io_stat(struct request *rq)
 {
-       return (rq->rq_flags & RQF_IO_STAT) && rq->q->disk;
+       return (rq->rq_flags & RQF_IO_STAT) && !blk_rq_is_passthrough(rq);
 }
 
 void update_io_ticks(struct block_device *part, unsigned long now, bool end);