unsigned int            hr_num_pages;
 
        struct page             **hr_slot_data;
-       struct block_device     *hr_bdev;
+       struct bdev_handle      *hr_bdev_handle;
        struct o2hb_disk_slot   *hr_slots;
 
        /* live node map of this region */
        int                     hr_last_hb_status;
 };
 
+static inline struct block_device *reg_bdev(struct o2hb_region *reg)
+{
+       return reg->hr_bdev_handle ? reg->hr_bdev_handle->bdev : NULL;
+}
+
 struct o2hb_bio_wait_ctxt {
        atomic_t          wc_num_reqs;
        struct completion wc_io_complete;
                             hr_write_timeout_work.work);
 
        mlog(ML_ERROR, "Heartbeat write timeout to device %pg after %u "
-            "milliseconds\n", reg->hr_bdev,
+            "milliseconds\n", reg_bdev(reg),
             jiffies_to_msecs(jiffies - reg->hr_last_timeout_start));
 
        if (o2hb_global_heartbeat_active()) {
                if (!test_bit(master_node, reg->hr_nego_node_bitmap)) {
                        printk(KERN_NOTICE "o2hb: node %d hb write hung for %ds on region %s (%pg).\n",
                                o2nm_this_node(), O2HB_NEGO_TIMEOUT_MS/1000,
-                               config_item_name(®->hr_item), reg->hr_bdev);
+                               config_item_name(®->hr_item), reg_bdev(reg));
                        set_bit(master_node, reg->hr_nego_node_bitmap);
                }
                if (!bitmap_equal(reg->hr_nego_node_bitmap, live_node_bitmap,
                }
 
                printk(KERN_NOTICE "o2hb: all nodes hb write hung, maybe region %s (%pg) is down.\n",
-                       config_item_name(®->hr_item), reg->hr_bdev);
+                       config_item_name(®->hr_item),
+                       reg_bdev(reg));
                /* approve negotiate timeout request. */
                o2hb_arm_timeout(reg);
 
                /* negotiate timeout with master node. */
                printk(KERN_NOTICE "o2hb: node %d hb write hung for %ds on region %s (%pg), negotiate timeout with node %d.\n",
                        o2nm_this_node(), O2HB_NEGO_TIMEOUT_MS/1000, config_item_name(®->hr_item),
-                       reg->hr_bdev, master_node);
+                       reg_bdev(reg), master_node);
                ret = o2hb_send_nego_msg(reg->hr_key, O2HB_NEGO_TIMEOUT_MSG,
                                master_node);
                if (ret)
 
        nego_msg = (struct o2hb_nego_msg *)msg->buf;
        printk(KERN_NOTICE "o2hb: receive negotiate timeout message from node %d on region %s (%pg).\n",
-               nego_msg->node_num, config_item_name(®->hr_item), reg->hr_bdev);
+               nego_msg->node_num, config_item_name(®->hr_item),
+               reg_bdev(reg));
        if (nego_msg->node_num < O2NM_MAX_NODES)
                set_bit(nego_msg->node_num, reg->hr_nego_node_bitmap);
        else
        struct o2hb_region *reg = data;
 
        printk(KERN_NOTICE "o2hb: negotiate timeout approved by master node on region %s (%pg).\n",
-               config_item_name(®->hr_item), reg->hr_bdev);
+               config_item_name(®->hr_item), reg_bdev(reg));
        o2hb_arm_timeout(reg);
        return 0;
 }
         * GFP_KERNEL that the local node can get fenced. It would be
         * nicest if we could pre-allocate these bios and avoid this
         * all together. */
-       bio = bio_alloc(reg->hr_bdev, 16, opf, GFP_ATOMIC);
+       bio = bio_alloc(reg_bdev(reg), 16, opf, GFP_ATOMIC);
        if (!bio) {
                mlog(ML_ERROR, "Could not alloc slots BIO!\n");
                bio = ERR_PTR(-ENOMEM);
                errstr = ERRSTR3;
 
        mlog(ML_ERROR, "%s (%pg): expected(%u:0x%llx, 0x%llx), "
-            "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg->hr_bdev,
+            "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg_bdev(reg),
             slot->ds_node_num, (unsigned long long)slot->ds_last_generation,
             (unsigned long long)slot->ds_last_time, hb_block->hb_node,
             (unsigned long long)le64_to_cpu(hb_block->hb_generation),
                goto unlock;
 
        printk(KERN_NOTICE "o2hb: Region %s (%pg) is now a quorum device\n",
-              config_item_name(®->hr_item), reg->hr_bdev);
+              config_item_name(®->hr_item), reg_bdev(reg));
 
        set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
 
                 * consider it a transient miss but don't populate any
                 * other values as they may be junk. */
                mlog(ML_ERROR, "Node %d has written a bad crc to %pg\n",
-                    slot->ds_node_num, reg->hr_bdev);
+                    slot->ds_node_num, reg_bdev(reg));
                o2hb_dump_slot(hb_block);
 
                slot->ds_equal_samples++;
                             "of %u ms, but our count is %u ms.\n"
                             "Please double check your configuration values "
                             "for 'O2CB_HEARTBEAT_THRESHOLD'\n",
-                            slot->ds_node_num, reg->hr_bdev, slot_dead_ms,
-                            dead_ms);
+                            slot->ds_node_num, reg_bdev(reg),
+                            slot_dead_ms, dead_ms);
                }
                goto out;
        }
                 * can't be sure that the new block ever made it to
                 * disk */
                mlog(ML_ERROR, "Write error %d on device \"%pg\"\n",
-                    write_wc.wc_error, reg->hr_bdev);
+                    write_wc.wc_error, reg_bdev(reg));
                ret = write_wc.wc_error;
                goto bail;
        }
                        printk(KERN_NOTICE "o2hb: Unable to stabilize "
                               "heartbeat on region %s (%pg)\n",
                               config_item_name(®->hr_item),
-                              reg->hr_bdev);
+                              reg_bdev(reg));
                        atomic_set(®->hr_steady_iterations, 0);
                        reg->hr_aborted_start = 1;
                        wake_up(&o2hb_steady_queue);
        struct page *page;
        struct o2hb_region *reg = to_o2hb_region(item);
 
-       mlog(ML_HEARTBEAT, "hb region release (%pg)\n", reg->hr_bdev);
+       mlog(ML_HEARTBEAT, "hb region release (%pg)\n", reg_bdev(reg));
 
        kfree(reg->hr_tmp_block);
 
                kfree(reg->hr_slot_data);
        }
 
-       if (reg->hr_bdev)
-               blkdev_put(reg->hr_bdev, NULL);
+       if (reg->hr_bdev_handle)
+               bdev_release(reg->hr_bdev_handle);
 
        kfree(reg->hr_slots);
 
        unsigned long block_bytes;
        unsigned int block_bits;
 
-       if (reg->hr_bdev)
+       if (reg->hr_bdev_handle)
                return -EINVAL;
 
        status = o2hb_read_block_input(reg, page, &block_bytes,
        char *p = (char *)page;
        ssize_t ret;
 
-       if (reg->hr_bdev)
+       if (reg->hr_bdev_handle)
                return -EINVAL;
 
        ret = kstrtoull(p, 0, &tmp);
        unsigned long tmp;
        char *p = (char *)page;
 
-       if (reg->hr_bdev)
+       if (reg->hr_bdev_handle)
                return -EINVAL;
 
        tmp = simple_strtoul(p, &p, 0);
 {
        unsigned int ret = 0;
 
-       if (to_o2hb_region(item)->hr_bdev)
-               ret = sprintf(page, "%pg\n", to_o2hb_region(item)->hr_bdev);
+       if (to_o2hb_region(item)->hr_bdev_handle)
+               ret = sprintf(page, "%pg\n", reg_bdev(to_o2hb_region(item)));
 
        return ret;
 }
        return ret;
 }
 
-/* this is acting as commit; we set up all of hr_bdev and hr_task or nothing */
+/*
+ * this is acting as commit; we set up all of hr_bdev_handle and hr_task or
+ * nothing
+ */
 static ssize_t o2hb_region_dev_store(struct config_item *item,
                                     const char *page,
                                     size_t count)
        ssize_t ret = -EINVAL;
        int live_threshold;
 
-       if (reg->hr_bdev)
+       if (reg->hr_bdev_handle)
                goto out;
 
        /* We can't heartbeat without having had our node number
        if (!S_ISBLK(f.file->f_mapping->host->i_mode))
                goto out2;
 
-       reg->hr_bdev = blkdev_get_by_dev(f.file->f_mapping->host->i_rdev,
-                                        BLK_OPEN_WRITE | BLK_OPEN_READ, NULL,
-                                        NULL);
-       if (IS_ERR(reg->hr_bdev)) {
-               ret = PTR_ERR(reg->hr_bdev);
-               reg->hr_bdev = NULL;
+       reg->hr_bdev_handle = bdev_open_by_dev(f.file->f_mapping->host->i_rdev,
+                       BLK_OPEN_WRITE | BLK_OPEN_READ, NULL, NULL);
+       if (IS_ERR(reg->hr_bdev_handle)) {
+               ret = PTR_ERR(reg->hr_bdev_handle);
+               reg->hr_bdev_handle = NULL;
                goto out2;
        }
 
-       sectsize = bdev_logical_block_size(reg->hr_bdev);
+       sectsize = bdev_logical_block_size(reg_bdev(reg));
        if (sectsize != reg->hr_block_bytes) {
                mlog(ML_ERROR,
                     "blocksize %u incorrect for device, expected %d",
 
        if (hb_task && o2hb_global_heartbeat_active())
                printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%pg)\n",
-                      config_item_name(®->hr_item), reg->hr_bdev);
+                      config_item_name(®->hr_item), reg_bdev(reg));
 
 out3:
        if (ret < 0) {
-               blkdev_put(reg->hr_bdev, NULL);
-               reg->hr_bdev = NULL;
+               bdev_release(reg->hr_bdev_handle);
+               reg->hr_bdev_handle = NULL;
        }
 out2:
        fdput(f);
                printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%pg)\n",
                       ((atomic_read(®->hr_steady_iterations) == 0) ?
                        "stopped" : "start aborted"), config_item_name(item),
-                      reg->hr_bdev);
+                      reg_bdev(reg));
        }
 
        /*