Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2c97909 authored by Josef Bacik's avatar Josef Bacik Committed by Jens Axboe
Browse files

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: default avatarJosef Bacik <jbacik@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent c6a4759e
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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);
@@ -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;
@@ -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;
@@ -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;
}

@@ -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;
@@ -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;
@@ -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;
}

+5 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ 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 */
@@ -45,6 +45,10 @@ enum {
#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 */