Skip to content

Commit

Permalink
nbd: add a flag to destroy an nbd device on disconnect
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Josef Bacik authored and Jens Axboe committed Apr 17, 2017
1 parent c6a4759 commit a2c9790
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
30 changes: 30 additions & 0 deletions drivers/block/nbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct link_dead_args {
#define NBD_HAS_PID_FILE 3
#define NBD_HAS_CONFIG_REF 4
#define NBD_BOUND 5
#define NBD_DESTROY_ON_DISCONNECT 6

struct nbd_config {
u32 flags;
Expand Down Expand Up @@ -174,6 +175,7 @@ static void nbd_dev_remove(struct nbd_device *nbd)
del_gendisk(disk);
blk_cleanup_queue(disk->queue);
blk_mq_free_tag_set(&nbd->tag_set);
disk->private_data = NULL;
put_disk(disk);
}
kfree(nbd);
Expand Down Expand Up @@ -1028,6 +1030,7 @@ static void nbd_config_put(struct nbd_device *nbd)
kfree(config->socks);
}
nbd_reset(nbd);

mutex_unlock(&nbd->config_lock);
nbd_put(nbd);
module_put(THIS_MODULE);
Expand Down Expand Up @@ -1539,6 +1542,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
struct nbd_config *config;
int index = -1;
int ret;
bool put_dev = false;

if (!netlink_capable(skb, CAP_SYS_ADMIN))
return -EPERM;
Expand Down Expand Up @@ -1633,6 +1637,15 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NBD_ATTR_SERVER_FLAGS])
config->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]) {
struct nlattr *attr;
int rem, fd;
Expand Down Expand Up @@ -1670,6 +1683,8 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
nbd_connect_reply(info, nbd->index);
}
nbd_config_put(nbd);
if (put_dev)
nbd_put(nbd);
return ret;
}

Expand Down Expand Up @@ -1722,6 +1737,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
struct nbd_config *config;
int index;
int ret = -EINVAL;
bool put_dev = false;

if (!netlink_capable(skb, CAP_SYS_ADMIN))
return -EPERM;
Expand Down Expand Up @@ -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]);
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]) {
struct nlattr *attr;
Expand Down Expand Up @@ -1810,6 +1838,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&nbd->config_lock);
nbd_config_put(nbd);
nbd_put(nbd);
if (put_dev)
nbd_put(nbd);
return ret;
}

Expand Down
6 changes: 5 additions & 1 deletion include/uapi/linux/nbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ enum {
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_READ_ONLY (1 << 1) /* device is read-only */
#define NBD_FLAG_SEND_FLUSH (1 << 2) /* can flush writeback cache */
/* there is a gap here to match userspace */
#define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */
#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 */

/* These are sent over the network in the request/reply magic fields */
Expand Down

0 comments on commit a2c9790

Please sign in to comment.