Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drbd: make drbd known to lsblk: use bd_link_disk_holder

lsblk should be able to pick up stacking device driver relations
involving DRBD conveniently.

Even though upstream kernel since 2011 says
"DON'T USE THIS UNLESS YOU'RE ALREADY USING IT."
a new user has been added since (bcache),
which sets the precedences for us to use it as well.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Lars Ellenberg and committed by
Jens Axboe
63a7c8ad 088b7052

+91 -52
+1 -1
drivers/block/drbd/drbd_int.h
··· 1126 1126 extern int drbd_send_bitmap(struct drbd_device *device); 1127 1127 extern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode); 1128 1128 extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode); 1129 - extern void drbd_free_ldev(struct drbd_backing_dev *ldev); 1129 + extern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev); 1130 1130 extern void drbd_device_cleanup(struct drbd_device *device); 1131 1131 void drbd_print_uuids(struct drbd_device *device, const char *text); 1132 1132
+2 -14
drivers/block/drbd/drbd_main.c
··· 1992 1992 drbd_bm_cleanup(device); 1993 1993 } 1994 1994 1995 - drbd_free_ldev(device->ldev); 1995 + drbd_backing_dev_free(device, device->ldev); 1996 1996 device->ldev = NULL; 1997 1997 1998 1998 clear_bit(AL_SUSPENDED, &device->flags); ··· 2171 2171 if (device->this_bdev) 2172 2172 bdput(device->this_bdev); 2173 2173 2174 - drbd_free_ldev(device->ldev); 2174 + drbd_backing_dev_free(device, device->ldev); 2175 2175 device->ldev = NULL; 2176 2176 2177 2177 drbd_release_all_peer_reqs(device); ··· 2962 2962 else 2963 2963 pr_err("initialization failure\n"); 2964 2964 return err; 2965 - } 2966 - 2967 - void drbd_free_ldev(struct drbd_backing_dev *ldev) 2968 - { 2969 - if (ldev == NULL) 2970 - return; 2971 - 2972 - blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); 2973 - blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); 2974 - 2975 - kfree(ldev->disk_conf); 2976 - kfree(ldev); 2977 2965 } 2978 2966 2979 2967 static void drbd_free_one_sock(struct drbd_socket *ds)
+86 -35
drivers/block/drbd/drbd_nl.c
··· 1471 1471 return 0; 1472 1472 } 1473 1473 1474 + static struct block_device *open_backing_dev(struct drbd_device *device, 1475 + const char *bdev_path, void *claim_ptr, bool do_bd_link) 1476 + { 1477 + struct block_device *bdev; 1478 + int err = 0; 1479 + 1480 + bdev = blkdev_get_by_path(bdev_path, 1481 + FMODE_READ | FMODE_WRITE | FMODE_EXCL, claim_ptr); 1482 + if (IS_ERR(bdev)) { 1483 + drbd_err(device, "open(\"%s\") failed with %ld\n", 1484 + bdev_path, PTR_ERR(bdev)); 1485 + return bdev; 1486 + } 1487 + 1488 + if (!do_bd_link) 1489 + return bdev; 1490 + 1491 + err = bd_link_disk_holder(bdev, device->vdisk); 1492 + if (err) { 1493 + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); 1494 + drbd_err(device, "bd_link_disk_holder(\"%s\", ...) failed with %d\n", 1495 + bdev_path, err); 1496 + bdev = ERR_PTR(err); 1497 + } 1498 + return bdev; 1499 + } 1500 + 1501 + static int open_backing_devices(struct drbd_device *device, 1502 + struct disk_conf *new_disk_conf, 1503 + struct drbd_backing_dev *nbc) 1504 + { 1505 + struct block_device *bdev; 1506 + 1507 + bdev = open_backing_dev(device, new_disk_conf->backing_dev, device, true); 1508 + if (IS_ERR(bdev)) 1509 + return ERR_OPEN_DISK; 1510 + nbc->backing_bdev = bdev; 1511 + 1512 + /* 1513 + * meta_dev_idx >= 0: external fixed size, possibly multiple 1514 + * drbd sharing one meta device. TODO in that case, paranoia 1515 + * check that [md_bdev, meta_dev_idx] is not yet used by some 1516 + * other drbd minor! (if you use drbd.conf + drbdadm, that 1517 + * should check it for you already; but if you don't, or 1518 + * someone fooled it, we need to double check here) 1519 + */ 1520 + bdev = open_backing_dev(device, new_disk_conf->meta_dev, 1521 + /* claim ptr: device, if claimed exclusively; shared drbd_m_holder, 1522 + * if potentially shared with other drbd minors */ 1523 + (new_disk_conf->meta_dev_idx < 0) ? (void*)device : (void*)drbd_m_holder, 1524 + /* avoid double bd_claim_by_disk() for the same (source,target) tuple, 1525 + * as would happen with internal metadata. */ 1526 + (new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_FLEX_INT && 1527 + new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_INTERNAL)); 1528 + if (IS_ERR(bdev)) 1529 + return ERR_OPEN_MD_DISK; 1530 + nbc->md_bdev = bdev; 1531 + return NO_ERROR; 1532 + } 1533 + 1534 + static void close_backing_dev(struct drbd_device *device, struct block_device *bdev, 1535 + bool do_bd_unlink) 1536 + { 1537 + if (!bdev) 1538 + return; 1539 + if (do_bd_unlink) 1540 + bd_unlink_disk_holder(bdev, device->vdisk); 1541 + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); 1542 + } 1543 + 1544 + void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev) 1545 + { 1546 + if (ldev == NULL) 1547 + return; 1548 + 1549 + close_backing_dev(device, ldev->md_bdev, ldev->md_bdev != ldev->backing_bdev); 1550 + close_backing_dev(device, ldev->backing_bdev, true); 1551 + 1552 + kfree(ldev->disk_conf); 1553 + kfree(ldev); 1554 + } 1555 + 1474 1556 int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 1475 1557 { 1476 1558 struct drbd_config_context adm_ctx; ··· 1566 1484 sector_t min_md_device_sectors; 1567 1485 struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ 1568 1486 struct disk_conf *new_disk_conf = NULL; 1569 - struct block_device *bdev; 1570 1487 struct lru_cache *resync_lru = NULL; 1571 1488 struct fifo_buffer *new_plan = NULL; 1572 1489 union drbd_state ns, os; ··· 1653 1572 } 1654 1573 rcu_read_unlock(); 1655 1574 1656 - bdev = blkdev_get_by_path(new_disk_conf->backing_dev, 1657 - FMODE_READ | FMODE_WRITE | FMODE_EXCL, device); 1658 - if (IS_ERR(bdev)) { 1659 - drbd_err(device, "open(\"%s\") failed with %ld\n", new_disk_conf->backing_dev, 1660 - PTR_ERR(bdev)); 1661 - retcode = ERR_OPEN_DISK; 1575 + retcode = open_backing_devices(device, new_disk_conf, nbc); 1576 + if (retcode != NO_ERROR) 1662 1577 goto fail; 1663 - } 1664 - nbc->backing_bdev = bdev; 1665 - 1666 - /* 1667 - * meta_dev_idx >= 0: external fixed size, possibly multiple 1668 - * drbd sharing one meta device. TODO in that case, paranoia 1669 - * check that [md_bdev, meta_dev_idx] is not yet used by some 1670 - * other drbd minor! (if you use drbd.conf + drbdadm, that 1671 - * should check it for you already; but if you don't, or 1672 - * someone fooled it, we need to double check here) 1673 - */ 1674 - bdev = blkdev_get_by_path(new_disk_conf->meta_dev, 1675 - FMODE_READ | FMODE_WRITE | FMODE_EXCL, 1676 - (new_disk_conf->meta_dev_idx < 0) ? 1677 - (void *)device : (void *)drbd_m_holder); 1678 - if (IS_ERR(bdev)) { 1679 - drbd_err(device, "open(\"%s\") failed with %ld\n", new_disk_conf->meta_dev, 1680 - PTR_ERR(bdev)); 1681 - retcode = ERR_OPEN_MD_DISK; 1682 - goto fail; 1683 - } 1684 - nbc->md_bdev = bdev; 1685 1578 1686 1579 if ((nbc->backing_bdev == nbc->md_bdev) != 1687 1580 (new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_INTERNAL || ··· 1955 1900 fail: 1956 1901 conn_reconfig_done(connection); 1957 1902 if (nbc) { 1958 - if (nbc->backing_bdev) 1959 - blkdev_put(nbc->backing_bdev, 1960 - FMODE_READ | FMODE_WRITE | FMODE_EXCL); 1961 - if (nbc->md_bdev) 1962 - blkdev_put(nbc->md_bdev, 1963 - FMODE_READ | FMODE_WRITE | FMODE_EXCL); 1903 + close_backing_dev(device, nbc->md_bdev, nbc->md_bdev != nbc->backing_bdev); 1904 + close_backing_dev(device, nbc->backing_bdev, true); 1964 1905 kfree(nbc); 1965 1906 } 1966 1907 kfree(new_disk_conf);
+1 -1
drivers/block/drbd/drbd_worker.c
··· 1841 1841 device->act_log = NULL; 1842 1842 1843 1843 __acquire(local); 1844 - drbd_free_ldev(device->ldev); 1844 + drbd_backing_dev_free(device, device->ldev); 1845 1845 device->ldev = NULL; 1846 1846 __release(local); 1847 1847
+1 -1
include/linux/drbd.h
··· 51 51 #endif 52 52 53 53 extern const char *drbd_buildtag(void); 54 - #define REL_VERSION "8.4.5" 54 + #define REL_VERSION "8.4.6" 55 55 #define API_VERSION 1 56 56 #define PRO_VERSION_MIN 86 57 57 #define PRO_VERSION_MAX 101