All of lore.kernel.org
 help / color / mirror / Atom feed
From: Josef Bacik <jbacik@fb.com>
To: <arnd@arndb.de>, <gregkh@linuxfoundation.org>, <axboe@fb.com>,
	<nbd-general@lists.sourceforge.net>,
	<linux-block@vger.kernel.org>, <kernel-team@fb.com>
Subject: [PATCH 4/4] nbd: add a nbd-control interface
Date: Fri, 20 Jan 2017 16:56:52 -0500	[thread overview]
Message-ID: <1484949412-6903-4-git-send-email-jbacik@fb.com> (raw)
In-Reply-To: <1484949412-6903-1-git-send-email-jbacik@fb.com>

This patch mirrors the loop back device behavior with a few changes.  First
there is no DEL operation as NBD doesn't get as much churn as loop devices do.
Secondly the GET_NEXT operation can optionally create a new NBD device or not.
Our infrastructure people want to not allow NBD to create new devices as it
causes problems for them in containers.  However allow this to be optional as
things like the OSS NBD client probably doesn't care and would like to just be
given a device to use.

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 drivers/block/nbd.c      | 129 ++++++++++++++++++++++++++++++++++++++++++-----
 include/uapi/linux/nbd.h |  10 ++++
 2 files changed, 125 insertions(+), 14 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 96f7681..c06ed36 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -35,6 +35,7 @@
 #include <linux/types.h>
 #include <linux/debugfs.h>
 #include <linux/blk-mq.h>
+#include <linux/miscdevice.h>
 
 #include <linux/uaccess.h>
 #include <asm/types.h>
@@ -59,6 +60,7 @@ struct nbd_device {
 	unsigned long runtime_flags;
 	struct nbd_sock **socks;
 	int magic;
+	int index;
 
 	struct blk_mq_tag_set tag_set;
 
@@ -1041,6 +1043,7 @@ static int nbd_dev_add(int index)
 	if (err < 0)
 		goto out_free_disk;
 
+	nbd->index = index;
 	nbd->disk = disk;
 	nbd->tag_set.ops = &nbd_mq_ops;
 	nbd->tag_set.nr_hw_queues = 1;
@@ -1097,20 +1100,109 @@ static int nbd_dev_add(int index)
 	return err;
 }
 
-/*
- * And here should be modules and kernel interface 
- *  (Just smiley confuses emacs :-)
- */
+static int find_free_cb(int id, void *ptr, void *data)
+{
+	struct nbd_device *nbd = ptr;
+	struct nbd_device **ret = data;
+
+	if (nbd->num_connections == 0) {
+		*ret = nbd;
+		return 1;
+	}
+	if (*ret == NULL || (*ret)->index < nbd->index)
+		*ret = nbd;
+	return 0;
+}
+
+static int nbd_dev_lookup(struct nbd_device **ret, int index)
+{
+	struct nbd_device *nbd = NULL;
+
+	if (index < 0) {
+		int err = idr_for_each(&nbd_index_idr, &find_free_cb, &nbd);
+		if (err != 1) {
+			if (nbd != NULL) {
+				*ret = NULL;
+				return nbd->index + 1;
+			} else {
+				return 0;
+			}
+		}
+	} else
+		nbd = idr_find(&nbd_index_idr, index);
+	if (nbd) {
+		*ret = nbd;
+		return nbd->index;
+	}
+	return -ENODEV;
+}
+
+static long nbd_control_ioctl(struct file *file, unsigned int cmd,
+			      unsigned long parm)
+{
+	struct nbd_device *nbd = NULL;
+	int ret = -ENOSYS;
+
+	mutex_lock(&nbd_index_mutex);
+	switch (cmd) {
+	case NBD_CTL_ADD:
+		ret = nbd_dev_lookup(&nbd, parm);
+		if (ret >= 0) {
+			ret = -EEXIST;
+			break;
+		}
+		ret = nbd_dev_add(parm);
+		break;
+	case NBD_CTL_GET_FREE:
+		ret = nbd_dev_lookup(&nbd, -1);
+		if (ret < 0)
+			break;
+		if (parm && !nbd) {
+			int index = ret;
+
+			ret = nbd_dev_add(ret);
+			if (ret < 0)
+				break;
+			ret = index;
+		}
+		break;
+	default:
+		break;
+	}
+	mutex_unlock(&nbd_index_mutex);
+	return ret;
+}
+
+static const struct file_operations nbd_ctl_fops = {
+	.open		= nonseekable_open,
+	.unlocked_ioctl	= nbd_control_ioctl,
+	.compat_ioctl	= nbd_control_ioctl,
+	.owner		= THIS_MODULE,
+	.llseek		= noop_llseek,
+};
+
+static struct miscdevice nbd_misc = {
+	.minor	= NBD_CTRL_MINOR,
+	.name	= "nbd-control",
+	.fops	= &nbd_ctl_fops,
+};
+
+MODULE_ALIAS_MISCDEV(NBD_CTRL_MINOR);
+MODULE_ALIAS("devname:nbd-control");
 
 static int __init nbd_init(void)
 {
-	int i;
+	int i, ret;
 
 	BUILD_BUG_ON(sizeof(struct nbd_request) != 28);
+	ret = misc_register(&nbd_misc);
+	if (ret < 0)
+		return ret;
 
+	ret = -EINVAL;
 	if (max_part < 0) {
 		printk(KERN_ERR "nbd: max_part must be >= 0\n");
-		return -EINVAL;
+		goto out_misc;
 	}
 
 	part_shift = 0;
@@ -1129,17 +1221,20 @@ static int __init nbd_init(void)
 	}
 
 	if ((1UL << part_shift) > DISK_MAX_PARTS)
-		return -EINVAL;
-
+		goto out_misc;
 	if (nbds_max > 1UL << (MINORBITS - part_shift))
-		return -EINVAL;
+		goto out_misc;
+
 	recv_workqueue = alloc_workqueue("knbd-recv",
 					 WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
-	if (!recv_workqueue)
-		return -ENOMEM;
-
-	if (register_blkdev(NBD_MAJOR, "nbd"))
-		return -EIO;
+	if (!recv_workqueue) {
+		ret = -ENOMEM;
+		goto out_misc;
+	}
+	if (register_blkdev(NBD_MAJOR, "nbd")) {
+		ret = -EIO;
+		goto out_workqueue;
+	}
 
 	nbd_dbg_init();
 
@@ -1148,6 +1243,11 @@ static int __init nbd_init(void)
 		nbd_dev_add(i);
 	mutex_unlock(&nbd_index_mutex);
 	return 0;
+out_workqueue:
+	destroy_workqueue(recv_workqueue);
+out_misc:
+	misc_deregister(&nbd_misc);
+	return ret;
 }
 
 static int nbd_exit_cb(int id, void *ptr, void *data)
@@ -1164,6 +1264,7 @@ static void __exit nbd_cleanup(void)
 	idr_for_each(&nbd_index_idr, &nbd_exit_cb, NULL);
 	idr_destroy(&nbd_index_idr);
 	destroy_workqueue(recv_workqueue);
+	misc_deregister(&nbd_misc);
 	unregister_blkdev(NBD_MAJOR, "nbd");
 }
 
diff --git a/include/uapi/linux/nbd.h b/include/uapi/linux/nbd.h
index c91c642..a76924b 100644
--- a/include/uapi/linux/nbd.h
+++ b/include/uapi/linux/nbd.h
@@ -29,6 +29,16 @@
 #define NBD_SET_TIMEOUT _IO( 0xab, 9 )
 #define NBD_SET_FLAGS   _IO( 0xab, 10)
 
+/* Use the last 8 values of our allocation for CTRL ioctls. */
+#define NBD_CTL_ADD		_IO( 0xab, 23)
+#define NBD_CTL_GET_FREE	_IO( 0xab, 24)
+
+enum {
+	NBD_CTL_GET_FREE_SCAN = 0, /* Get the next free available device. */
+	NBD_CTL_GET_FREE_ADD = 1, /* Get the next free available device, but
+				     create one if one does not exist. */
+};
+
 enum {
 	NBD_CMD_READ = 0,
 	NBD_CMD_WRITE = 1,
-- 
2.7.4


  parent reply	other threads:[~2017-01-20 21:57 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-20 21:56 [PATCH 1/4] nbd: use our own workqueue for recv threads Josef Bacik
2017-01-20 21:56 ` [PATCH 2/4] miscdevice: add a minor number for nbd-control Josef Bacik
2017-01-21  9:03   ` Greg KH
2017-01-21 13:25     ` Josef Bacik
2017-01-22 11:09       ` Greg KH
2017-01-20 21:56 ` [PATCH 3/4] nbd: use an idr to keep track of nbd devices Josef Bacik
2017-01-20 21:56 ` Josef Bacik [this message]
2017-01-21  9:05   ` [PATCH 4/4] nbd: add a nbd-control interface Greg KH
2017-01-23 14:42     ` Josef Bacik
2017-01-23 14:52       ` Greg KH
2017-01-23 14:57         ` Josef Bacik
2017-01-23 15:03           ` Greg KH
2017-01-23 15:52             ` Josef Bacik
2017-01-24  7:11               ` Greg KH
2017-01-25  8:55                 ` [Nbd] " Wouter Verhelst
2017-01-25 13:47                 ` Josef Bacik
2017-01-25 14:23                   ` Arnd Bergmann
2017-01-25 16:48                     ` Alex Gartrell
2017-01-25 18:21                       ` [Nbd] " Wouter Verhelst
2017-01-25 18:25                       ` Alex Bligh
2017-01-25 21:30                         ` Greg KH
2017-01-25 21:36                           ` Eric Blake
2017-01-26  8:40                             ` Christoph Hellwig
2017-01-26  9:17                               ` Greg KH
2017-01-26 13:17                                 ` Christoph Hellwig
2017-01-25 18:24                     ` Paul Clements
2017-01-21 12:11   ` Wouter Verhelst
2017-01-21 13:44     ` Josef Bacik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1484949412-6903-4-git-send-email-jbacik@fb.com \
    --to=jbacik@fb.com \
    --cc=arnd@arndb.de \
    --cc=axboe@fb.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel-team@fb.com \
    --cc=linux-block@vger.kernel.org \
    --cc=nbd-general@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.