summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-02-02 17:56:52 +0300
committerJens Axboe <axboe@fb.com>2017-02-02 18:20:53 +0300
commitb1d2dc5659b41741f5a29b2ade76ffb4e5bb13d8 (patch)
tree6f01d065b95e5d7a94a26d3892142db6ea60dae5 /block
parentd03f6cdc1fc422accb734c7c07a661a0018d8631 (diff)
downloadlinux-b1d2dc5659b41741f5a29b2ade76ffb4e5bb13d8.tar.xz
block: Make blk_get_backing_dev_info() safe without open bdev
Currenly blk_get_backing_dev_info() is not safe to be called when the block device is not open as bdev->bd_disk is NULL in that case. However inode_to_bdi() uses this function and may be call called from flusher worker or other writeback related functions without bdev being open which leads to crashes such as: [113031.075540] Unable to handle kernel paging request for data at address 0x00000000 [113031.075614] Faulting instruction address: 0xc0000000003692e0 0:mon> t [c0000000fb65f900] c00000000036cb6c writeback_sb_inodes+0x30c/0x590 [c0000000fb65fa10] c00000000036ced4 __writeback_inodes_wb+0xe4/0x150 [c0000000fb65fa70] c00000000036d33c wb_writeback+0x30c/0x450 [c0000000fb65fb40] c00000000036e198 wb_workfn+0x268/0x580 [c0000000fb65fc50] c0000000000f3470 process_one_work+0x1e0/0x590 [c0000000fb65fce0] c0000000000f38c8 worker_thread+0xa8/0x660 [c0000000fb65fd80] c0000000000fc4b0 kthread+0x110/0x130 [c0000000fb65fe30] c0000000000098f0 ret_from_kernel_thread+0x5c/0x6c Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index d2bba4700e65..6375674e719b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -110,14 +110,12 @@ void blk_queue_congestion_threshold(struct request_queue *q)
* @bdev: device
*
* Locates the passed device's request queue and returns the address of its
- * backing_dev_info. This function can only be called if @bdev is opened
- * and the return value is never NULL.
+ * backing_dev_info. The return value is never NULL however we may return
+ * &noop_backing_dev_info if the bdev is not currently open.
*/
struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev)
{
- struct request_queue *q = bdev_get_queue(bdev);
-
- return q->backing_dev_info;
+ return bdev->bd_bdi;
}
EXPORT_SYMBOL(blk_get_backing_dev_info);