>From 153918f99e45c685700e919a92384395dc18fd5d Mon Sep 17 00:00:00 2001
From: Jack Wang <jinpu.wang@profitbricks.com>
Date: Thu, 2 Jan 2014 10:24:29 +0100
Subject: [PATCH] fix null pointer dereference in __blkdev_put We were hit by
 bug below: Dec 28 16:24:26 pserver1812 kernel: [979193.076399] BUG: unable to
 handle kernel NULL pointer dereference at 0000000000000008 Dec 28 16:24:26
 pserver1812 kernel: [979193.076401] IP: [<ffffffff8116952f>]
 __blkdev_put+0x17f/0x1d0 Dec 28 16:24:26 pserver1812 kernel: [979193.076442]
 Pid: 56544, comm: multipath Tainted: G           O 3.4.71-3-pserver #1
 Supermicro BHQGE/BHQGE Dec 28 16:24:26 pserver1812 kernel: [979193.076445]
 RIP: 0010:[<ffffffff8116952f>]  [<ffffffff8116952f>] __blkdev_put+0x17f/0x1d0
 Dec 28 16:24:26 pserver1812 kernel: [979193.076472] Call Trace: Dec 28
 16:24:26 pserver1812 kernel: [979193.076477]  [<ffffffff81136bad>] ?
 fput+0xdd/0x270 Dec 28 16:24:26 pserver1812 kernel: [979193.076479] 
 [<ffffffff81132f0c>] ? filp_close+0x5c/0x90 Dec 28 16:24:26 pserver1812
 kernel: [979193.076481]  [<ffffffff81132fb1>] ? sys_close+0x71/0xc0 Dec 28
 16:24:26 pserver1812 kernel: [979193.076484]  [<ffffffff816801b9>] ?
 system_call_fastpath+0x16/0x1b Dec 28 16:24:26 pserver1812 kernel:
 [979193.076486] Code: 8b 5c 24 18 48 8b 6c 24 20 4c 8b 64 24 28 4c 8b 6c 24
 30 4c 8b 74 24 38 4c 8b 7c 24 40 48 83 c4 48 c3 66 90 49 8b 86 48 03 00 00
 <48> 8b 40 08 48 85 c0 0f 84 fc fe ff ff 44 89 e6 4c 89 f7 ff d0 Dec 28
 16:24:26 pserver1812 kernel: [979193.076500] RIP  [<ffffffff8116952f>]
 __blkdev_put+0x17f/0x1d0 Dec 28 16:24:26 pserver1812 kernel: [979193.076503] 
 RSP <ffff882802f4beb8> Dec 28 16:24:26 pserver1812 kernel: [979193.076504]
 CR2: 0000000000000008 Dec 28 16:24:26 pserver1812 kernel: [979193.077599]
 ---[ end trace 23f39da823d257f9 ]---

Disamble code show null pointer happened in fops, fix by check before use it.

Signed-off-by: Jack Wang <jinpu.wang@profitbricks.com>
---
 fs/block_dev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 319d9c7..d3c45b4 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1483,8 +1483,9 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
 					&default_backing_dev_info);
 	}
 	if (bdev->bd_contains == bdev) {
-		if (disk->fops->release)
-			ret = disk->fops->release(disk, mode);
+		if (disk->fops)
+			if (disk->fops->release)
+				ret = disk->fops->release(disk, mode);
 	}
 	if (!bdev->bd_openers) {
 		struct module *owner = disk->fops->owner;
-- 
1.8.4