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

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

nbd: cleanup ioctl handling



Break the ioctl handling out into helper functions, some of these things
are getting pretty big and unwieldy.

Signed-off-by: default avatarJosef Bacik <jbacik@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent ee524236
Loading
Loading
Loading
Loading
+132 −137
Original line number Diff line number Diff line
@@ -96,6 +96,10 @@ static int max_part;
static struct workqueue_struct *recv_workqueue;
static int part_shift;

static int nbd_dev_dbg_init(struct nbd_device *nbd);
static void nbd_dev_dbg_close(struct nbd_device *nbd);


static inline struct device *nbd_to_dev(struct nbd_device *nbd)
{
	return disk_to_dev(nbd->disk);
@@ -571,10 +575,17 @@ static int nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
	return BLK_MQ_RQ_QUEUE_OK;
}

static int nbd_add_socket(struct nbd_device *nbd, struct socket *sock)
static int nbd_add_socket(struct nbd_device *nbd, struct block_device *bdev,
			  unsigned long arg)
{
	struct socket *sock;
	struct nbd_sock **socks;
	struct nbd_sock *nsock;
	int err;

	sock = sockfd_lookup(arg, &err);
	if (!sock)
		return err;

	if (!nbd->task_setup)
		nbd->task_setup = current;
@@ -598,26 +609,20 @@ static int nbd_add_socket(struct nbd_device *nbd, struct socket *sock)
	nsock->sock = sock;
	socks[nbd->num_connections++] = nsock;

	if (max_part)
		bdev->bd_invalidated = 1;
	return 0;
}

/* Reset all properties of an NBD device */
static void nbd_reset(struct nbd_device *nbd)
{
	int i;

	for (i = 0; i < nbd->num_connections; i++)
		kfree(nbd->socks[i]);
	kfree(nbd->socks);
	nbd->socks = NULL;
	nbd->runtime_flags = 0;
	nbd->blksize = 1024;
	nbd->bytesize = 0;
	set_capacity(nbd->disk, 0);
	nbd->flags = 0;
	nbd->tag_set.timeout = 0;
	nbd->num_connections = 0;
	nbd->task_setup = NULL;
	queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
}

@@ -659,15 +664,8 @@ static void send_disconnects(struct nbd_device *nbd)
	}
}

static int nbd_dev_dbg_init(struct nbd_device *nbd);
static void nbd_dev_dbg_close(struct nbd_device *nbd);

/* Must be called with config_lock held */
static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
		       unsigned int cmd, unsigned long arg)
static int nbd_disconnect(struct nbd_device *nbd, struct block_device *bdev)
{
	switch (cmd) {
	case NBD_DISCONNECT: {
	dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
	if (!nbd->socks)
		return -EINVAL;
@@ -686,7 +684,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
	return 0;
}

	case NBD_CLEAR_SOCK:
static int nbd_clear_sock(struct nbd_device *nbd, struct block_device *bdev)
{
	sock_shutdown(nbd);
	nbd_clear_que(nbd);
	kill_bdev(bdev);
@@ -695,7 +694,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
	 * We want to give the run thread a chance to wait for everybody
	 * to clean up and then do it's own cleanup.
	 */
		if (!test_bit(NBD_RUNNING, &nbd->runtime_flags)) {
	if (!test_bit(NBD_RUNNING, &nbd->runtime_flags) &&
	    nbd->num_connections) {
		int i;

		for (i = 0; i < nbd->num_connections; i++)
@@ -703,46 +703,14 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
		kfree(nbd->socks);
		nbd->socks = NULL;
		nbd->num_connections = 0;
			nbd->task_setup = NULL;
		}
		return 0;

	case NBD_SET_SOCK: {
		int err;
		struct socket *sock = sockfd_lookup(arg, &err);

		if (!sock)
			return err;

		err = nbd_add_socket(nbd, sock);
		if (!err && max_part)
			bdev->bd_invalidated = 1;

		return err;
	}

	case NBD_SET_BLKSIZE: {
		loff_t bsize = div_s64(nbd->bytesize, arg);

		return nbd_size_set(nbd, bdev, arg, bsize);
	}
	nbd->task_setup = NULL;

	case NBD_SET_SIZE:
		return nbd_size_set(nbd, bdev, nbd->blksize,
					div_s64(arg, nbd->blksize));

	case NBD_SET_SIZE_BLOCKS:
		return nbd_size_set(nbd, bdev, nbd->blksize, arg);

	case NBD_SET_TIMEOUT:
		nbd->tag_set.timeout = arg * HZ;
		return 0;

	case NBD_SET_FLAGS:
		nbd->flags = arg;
	return 0;
}

	case NBD_DO_IT: {
static int nbd_start_device(struct nbd_device *nbd, struct block_device *bdev)
{
	struct recv_thread_args *args;
	int num_connections = nbd->num_connections;
	int error = 0, i;
@@ -798,10 +766,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
	mutex_lock(&nbd->config_lock);
	nbd->task_recv = NULL;
out_err:
		sock_shutdown(nbd);
		nbd_clear_que(nbd);
		kill_bdev(bdev);
		nbd_bdev_reset(bdev);
	clear_bit(NBD_RUNNING, &nbd->runtime_flags);
	nbd_clear_sock(nbd, bdev);

	/* user requested, ignore socket errors */
	if (test_bit(NBD_DISCONNECT_REQUESTED, &nbd->runtime_flags))
@@ -813,13 +779,42 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
	return error;
}

/* Must be called with config_lock held */
static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
		       unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case NBD_DISCONNECT:
		return nbd_disconnect(nbd, bdev);
	case NBD_CLEAR_SOCK:
		return nbd_clear_sock(nbd, bdev);
	case NBD_SET_SOCK:
		return nbd_add_socket(nbd, bdev, arg);
	case NBD_SET_BLKSIZE:
		return nbd_size_set(nbd, bdev, arg,
				    div_s64(nbd->bytesize, arg));
	case NBD_SET_SIZE:
		return nbd_size_set(nbd, bdev, nbd->blksize,
					div_s64(arg, nbd->blksize));

	case NBD_SET_SIZE_BLOCKS:
		return nbd_size_set(nbd, bdev, nbd->blksize, arg);

	case NBD_SET_TIMEOUT:
		nbd->tag_set.timeout = arg * HZ;
		return 0;

	case NBD_SET_FLAGS:
		nbd->flags = arg;
		return 0;
	case NBD_DO_IT:
		return nbd_start_device(nbd, bdev);
	case NBD_CLEAR_QUE:
		/*
		 * This is for compatibility only.  The queue is always cleared
		 * by NBD_DO_IT or NBD_CLEAR_SOCK.
		 */
		return 0;

	case NBD_PRINT_DEBUG:
		/*
		 * For compatibility only, we no longer keep a list of