aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2017-04-06 17:02:07 -0400
committerJens Axboe <axboe@fb.com>2017-04-17 11:58:42 -0400
commita2c97909f97ef32b76e856572fba4f77e1885fe6 (patch)
tree93693ce1eb0141806a19c307b92b6d5e11bbab0e
parentc6a4759ea0c9a7e7661f34f6943dafb1c6ae1b1c (diff)
nbd: add a flag to destroy an nbd device on disconnect
For ease of management it would be nice for users to specify that the device node for a nbd device is destroyed once it is disconnected and there are no more users. Add a client flag and enable this operation to happen. Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/nbd.c30
-rw-r--r--include/uapi/linux/nbd.h6
2 files changed, 35 insertions, 1 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 4237e7286e99..b78f23ce2395 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -74,6 +74,7 @@ struct link_dead_args {
74#define NBD_HAS_PID_FILE 3 74#define NBD_HAS_PID_FILE 3
75#define NBD_HAS_CONFIG_REF 4 75#define NBD_HAS_CONFIG_REF 4
76#define NBD_BOUND 5 76#define NBD_BOUND 5
77#define NBD_DESTROY_ON_DISCONNECT 6
77 78
78struct nbd_config { 79struct nbd_config {
79 u32 flags; 80 u32 flags;
@@ -174,6 +175,7 @@ static void nbd_dev_remove(struct nbd_device *nbd)
174 del_gendisk(disk); 175 del_gendisk(disk);
175 blk_cleanup_queue(disk->queue); 176 blk_cleanup_queue(disk->queue);
176 blk_mq_free_tag_set(&nbd->tag_set); 177 blk_mq_free_tag_set(&nbd->tag_set);
178 disk->private_data = NULL;
177 put_disk(disk); 179 put_disk(disk);
178 } 180 }
179 kfree(nbd); 181 kfree(nbd);
@@ -1028,6 +1030,7 @@ static void nbd_config_put(struct nbd_device *nbd)
1028 kfree(config->socks); 1030 kfree(config->socks);
1029 } 1031 }
1030 nbd_reset(nbd); 1032 nbd_reset(nbd);
1033
1031 mutex_unlock(&nbd->config_lock); 1034 mutex_unlock(&nbd->config_lock);
1032 nbd_put(nbd); 1035 nbd_put(nbd);
1033 module_put(THIS_MODULE); 1036 module_put(THIS_MODULE);
@@ -1539,6 +1542,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
1539 struct nbd_config *config; 1542 struct nbd_config *config;
1540 int index = -1; 1543 int index = -1;
1541 int ret; 1544 int ret;
1545 bool put_dev = false;
1542 1546
1543 if (!netlink_capable(skb, CAP_SYS_ADMIN)) 1547 if (!netlink_capable(skb, CAP_SYS_ADMIN))
1544 return -EPERM; 1548 return -EPERM;
@@ -1633,6 +1637,15 @@ again:
1633 if (info->attrs[NBD_ATTR_SERVER_FLAGS]) 1637 if (info->attrs[NBD_ATTR_SERVER_FLAGS])
1634 config->flags = 1638 config->flags =
1635 nla_get_u64(info->attrs[NBD_ATTR_SERVER_FLAGS]); 1639 nla_get_u64(info->attrs[NBD_ATTR_SERVER_FLAGS]);
1640 if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) {
1641 u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]);
1642 if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) {
1643 set_bit(NBD_DESTROY_ON_DISCONNECT,
1644 &config->runtime_flags);
1645 put_dev = true;
1646 }
1647 }
1648
1636 if (info->attrs[NBD_ATTR_SOCKETS]) { 1649 if (info->attrs[NBD_ATTR_SOCKETS]) {
1637 struct nlattr *attr; 1650 struct nlattr *attr;
1638 int rem, fd; 1651 int rem, fd;
@@ -1670,6 +1683,8 @@ out:
1670 nbd_connect_reply(info, nbd->index); 1683 nbd_connect_reply(info, nbd->index);
1671 } 1684 }
1672 nbd_config_put(nbd); 1685 nbd_config_put(nbd);
1686 if (put_dev)
1687 nbd_put(nbd);
1673 return ret; 1688 return ret;
1674} 1689}
1675 1690
@@ -1722,6 +1737,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
1722 struct nbd_config *config; 1737 struct nbd_config *config;
1723 int index; 1738 int index;
1724 int ret = -EINVAL; 1739 int ret = -EINVAL;
1740 bool put_dev = false;
1725 1741
1726 if (!netlink_capable(skb, CAP_SYS_ADMIN)) 1742 if (!netlink_capable(skb, CAP_SYS_ADMIN))
1727 return -EPERM; 1743 return -EPERM;
@@ -1773,6 +1789,18 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
1773 nla_get_u64(info->attrs[NBD_ATTR_DEAD_CONN_TIMEOUT]); 1789 nla_get_u64(info->attrs[NBD_ATTR_DEAD_CONN_TIMEOUT]);
1774 config->dead_conn_timeout *= HZ; 1790 config->dead_conn_timeout *= HZ;
1775 } 1791 }
1792 if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) {
1793 u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]);
1794 if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) {
1795 if (!test_and_set_bit(NBD_DESTROY_ON_DISCONNECT,
1796 &config->runtime_flags))
1797 put_dev = true;
1798 } else {
1799 if (test_and_clear_bit(NBD_DESTROY_ON_DISCONNECT,
1800 &config->runtime_flags))
1801 refcount_inc(&nbd->refs);
1802 }
1803 }
1776 1804
1777 if (info->attrs[NBD_ATTR_SOCKETS]) { 1805 if (info->attrs[NBD_ATTR_SOCKETS]) {
1778 struct nlattr *attr; 1806 struct nlattr *attr;
@@ -1810,6 +1838,8 @@ out:
1810 mutex_unlock(&nbd->config_lock); 1838 mutex_unlock(&nbd->config_lock);
1811 nbd_config_put(nbd); 1839 nbd_config_put(nbd);
1812 nbd_put(nbd); 1840 nbd_put(nbd);
1841 if (put_dev)
1842 nbd_put(nbd);
1813 return ret; 1843 return ret;
1814} 1844}
1815 1845
diff --git a/include/uapi/linux/nbd.h b/include/uapi/linux/nbd.h
index c91c642ea900..155e33f81913 100644
--- a/include/uapi/linux/nbd.h
+++ b/include/uapi/linux/nbd.h
@@ -37,7 +37,7 @@ enum {
37 NBD_CMD_TRIM = 4 37 NBD_CMD_TRIM = 4
38}; 38};
39 39
40/* values for flags field */ 40/* values for flags field, these are server interaction specific. */
41#define NBD_FLAG_HAS_FLAGS (1 << 0) /* nbd-server supports flags */ 41#define NBD_FLAG_HAS_FLAGS (1 << 0) /* nbd-server supports flags */
42#define NBD_FLAG_READ_ONLY (1 << 1) /* device is read-only */ 42#define NBD_FLAG_READ_ONLY (1 << 1) /* device is read-only */
43#define NBD_FLAG_SEND_FLUSH (1 << 2) /* can flush writeback cache */ 43#define NBD_FLAG_SEND_FLUSH (1 << 2) /* can flush writeback cache */
@@ -45,6 +45,10 @@ enum {
45#define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */ 45#define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */
46#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Server supports multiple connections per export. */ 46#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Server supports multiple connections per export. */
47 47
48/* These are client behavior specific flags. */
49#define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0) /* delete the nbd device on
50 disconnect. */
51
48/* userspace doesn't need the nbd_device structure */ 52/* userspace doesn't need the nbd_device structure */
49 53
50/* These are sent over the network in the request/reply magic fields */ 54/* These are sent over the network in the request/reply magic fields */