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>
This commit is contained in:
parent
c6a4759ea0
commit
a2c97909f9
|
@ -74,6 +74,7 @@ struct link_dead_args {
|
||||||
#define NBD_HAS_PID_FILE 3
|
#define NBD_HAS_PID_FILE 3
|
||||||
#define NBD_HAS_CONFIG_REF 4
|
#define NBD_HAS_CONFIG_REF 4
|
||||||
#define NBD_BOUND 5
|
#define NBD_BOUND 5
|
||||||
|
#define NBD_DESTROY_ON_DISCONNECT 6
|
||||||
|
|
||||||
struct nbd_config {
|
struct nbd_config {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
@ -174,6 +175,7 @@ static void nbd_dev_remove(struct nbd_device *nbd)
|
||||||
del_gendisk(disk);
|
del_gendisk(disk);
|
||||||
blk_cleanup_queue(disk->queue);
|
blk_cleanup_queue(disk->queue);
|
||||||
blk_mq_free_tag_set(&nbd->tag_set);
|
blk_mq_free_tag_set(&nbd->tag_set);
|
||||||
|
disk->private_data = NULL;
|
||||||
put_disk(disk);
|
put_disk(disk);
|
||||||
}
|
}
|
||||||
kfree(nbd);
|
kfree(nbd);
|
||||||
|
@ -1028,6 +1030,7 @@ static void nbd_config_put(struct nbd_device *nbd)
|
||||||
kfree(config->socks);
|
kfree(config->socks);
|
||||||
}
|
}
|
||||||
nbd_reset(nbd);
|
nbd_reset(nbd);
|
||||||
|
|
||||||
mutex_unlock(&nbd->config_lock);
|
mutex_unlock(&nbd->config_lock);
|
||||||
nbd_put(nbd);
|
nbd_put(nbd);
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
|
@ -1539,6 +1542,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
|
||||||
struct nbd_config *config;
|
struct nbd_config *config;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
int ret;
|
int ret;
|
||||||
|
bool put_dev = false;
|
||||||
|
|
||||||
if (!netlink_capable(skb, CAP_SYS_ADMIN))
|
if (!netlink_capable(skb, CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -1633,6 +1637,15 @@ again:
|
||||||
if (info->attrs[NBD_ATTR_SERVER_FLAGS])
|
if (info->attrs[NBD_ATTR_SERVER_FLAGS])
|
||||||
config->flags =
|
config->flags =
|
||||||
nla_get_u64(info->attrs[NBD_ATTR_SERVER_FLAGS]);
|
nla_get_u64(info->attrs[NBD_ATTR_SERVER_FLAGS]);
|
||||||
|
if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) {
|
||||||
|
u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]);
|
||||||
|
if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) {
|
||||||
|
set_bit(NBD_DESTROY_ON_DISCONNECT,
|
||||||
|
&config->runtime_flags);
|
||||||
|
put_dev = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (info->attrs[NBD_ATTR_SOCKETS]) {
|
if (info->attrs[NBD_ATTR_SOCKETS]) {
|
||||||
struct nlattr *attr;
|
struct nlattr *attr;
|
||||||
int rem, fd;
|
int rem, fd;
|
||||||
|
@ -1670,6 +1683,8 @@ out:
|
||||||
nbd_connect_reply(info, nbd->index);
|
nbd_connect_reply(info, nbd->index);
|
||||||
}
|
}
|
||||||
nbd_config_put(nbd);
|
nbd_config_put(nbd);
|
||||||
|
if (put_dev)
|
||||||
|
nbd_put(nbd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1722,6 +1737,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
|
||||||
struct nbd_config *config;
|
struct nbd_config *config;
|
||||||
int index;
|
int index;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
bool put_dev = false;
|
||||||
|
|
||||||
if (!netlink_capable(skb, CAP_SYS_ADMIN))
|
if (!netlink_capable(skb, CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -1773,6 +1789,18 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
|
||||||
nla_get_u64(info->attrs[NBD_ATTR_DEAD_CONN_TIMEOUT]);
|
nla_get_u64(info->attrs[NBD_ATTR_DEAD_CONN_TIMEOUT]);
|
||||||
config->dead_conn_timeout *= HZ;
|
config->dead_conn_timeout *= HZ;
|
||||||
}
|
}
|
||||||
|
if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) {
|
||||||
|
u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]);
|
||||||
|
if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) {
|
||||||
|
if (!test_and_set_bit(NBD_DESTROY_ON_DISCONNECT,
|
||||||
|
&config->runtime_flags))
|
||||||
|
put_dev = true;
|
||||||
|
} else {
|
||||||
|
if (test_and_clear_bit(NBD_DESTROY_ON_DISCONNECT,
|
||||||
|
&config->runtime_flags))
|
||||||
|
refcount_inc(&nbd->refs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (info->attrs[NBD_ATTR_SOCKETS]) {
|
if (info->attrs[NBD_ATTR_SOCKETS]) {
|
||||||
struct nlattr *attr;
|
struct nlattr *attr;
|
||||||
|
@ -1810,6 +1838,8 @@ out:
|
||||||
mutex_unlock(&nbd->config_lock);
|
mutex_unlock(&nbd->config_lock);
|
||||||
nbd_config_put(nbd);
|
nbd_config_put(nbd);
|
||||||
nbd_put(nbd);
|
nbd_put(nbd);
|
||||||
|
if (put_dev)
|
||||||
|
nbd_put(nbd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ enum {
|
||||||
NBD_CMD_TRIM = 4
|
NBD_CMD_TRIM = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
/* values for flags field */
|
/* values for flags field, these are server interaction specific. */
|
||||||
#define NBD_FLAG_HAS_FLAGS (1 << 0) /* nbd-server supports flags */
|
#define NBD_FLAG_HAS_FLAGS (1 << 0) /* nbd-server supports flags */
|
||||||
#define NBD_FLAG_READ_ONLY (1 << 1) /* device is read-only */
|
#define NBD_FLAG_READ_ONLY (1 << 1) /* device is read-only */
|
||||||
#define NBD_FLAG_SEND_FLUSH (1 << 2) /* can flush writeback cache */
|
#define NBD_FLAG_SEND_FLUSH (1 << 2) /* can flush writeback cache */
|
||||||
|
@ -45,6 +45,10 @@ enum {
|
||||||
#define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */
|
#define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */
|
||||||
#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Server supports multiple connections per export. */
|
#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Server supports multiple connections per export. */
|
||||||
|
|
||||||
|
/* These are client behavior specific flags. */
|
||||||
|
#define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0) /* delete the nbd device on
|
||||||
|
disconnect. */
|
||||||
|
|
||||||
/* userspace doesn't need the nbd_device structure */
|
/* userspace doesn't need the nbd_device structure */
|
||||||
|
|
||||||
/* These are sent over the network in the request/reply magic fields */
|
/* These are sent over the network in the request/reply magic fields */
|
||||||
|
|
Loading…
Reference in New Issue