提交 9442b739 编写于 作者: J Josef Bacik 提交者: Jens Axboe

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: NJosef Bacik <jbacik@fb.com>
Signed-off-by: NJens Axboe <axboe@fb.com>
上级 ee524236
...@@ -96,6 +96,10 @@ static int max_part; ...@@ -96,6 +96,10 @@ static int max_part;
static struct workqueue_struct *recv_workqueue; static struct workqueue_struct *recv_workqueue;
static int part_shift; 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) static inline struct device *nbd_to_dev(struct nbd_device *nbd)
{ {
return disk_to_dev(nbd->disk); return disk_to_dev(nbd->disk);
...@@ -571,10 +575,17 @@ static int nbd_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -571,10 +575,17 @@ static int nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
return BLK_MQ_RQ_QUEUE_OK; 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 **socks;
struct nbd_sock *nsock; struct nbd_sock *nsock;
int err;
sock = sockfd_lookup(arg, &err);
if (!sock)
return err;
if (!nbd->task_setup) if (!nbd->task_setup)
nbd->task_setup = current; nbd->task_setup = current;
...@@ -598,26 +609,20 @@ static int nbd_add_socket(struct nbd_device *nbd, struct socket *sock) ...@@ -598,26 +609,20 @@ static int nbd_add_socket(struct nbd_device *nbd, struct socket *sock)
nsock->sock = sock; nsock->sock = sock;
socks[nbd->num_connections++] = nsock; socks[nbd->num_connections++] = nsock;
if (max_part)
bdev->bd_invalidated = 1;
return 0; return 0;
} }
/* Reset all properties of an NBD device */ /* Reset all properties of an NBD device */
static void nbd_reset(struct nbd_device *nbd) 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->runtime_flags = 0;
nbd->blksize = 1024; nbd->blksize = 1024;
nbd->bytesize = 0; nbd->bytesize = 0;
set_capacity(nbd->disk, 0); set_capacity(nbd->disk, 0);
nbd->flags = 0; nbd->flags = 0;
nbd->tag_set.timeout = 0; nbd->tag_set.timeout = 0;
nbd->num_connections = 0;
nbd->task_setup = NULL;
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue); queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
} }
...@@ -659,15 +664,8 @@ static void send_disconnects(struct nbd_device *nbd) ...@@ -659,15 +664,8 @@ static void send_disconnects(struct nbd_device *nbd)
} }
} }
static int nbd_dev_dbg_init(struct nbd_device *nbd); static int nbd_disconnect(struct nbd_device *nbd, struct block_device *bdev)
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)
{ {
switch (cmd) {
case NBD_DISCONNECT: {
dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n"); dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
if (!nbd->socks) if (!nbd->socks)
return -EINVAL; return -EINVAL;
...@@ -684,9 +682,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, ...@@ -684,9 +682,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
&nbd->runtime_flags)) &nbd->runtime_flags))
send_disconnects(nbd); send_disconnects(nbd);
return 0; return 0;
} }
case NBD_CLEAR_SOCK: static int nbd_clear_sock(struct nbd_device *nbd, struct block_device *bdev)
{
sock_shutdown(nbd); sock_shutdown(nbd);
nbd_clear_que(nbd); nbd_clear_que(nbd);
kill_bdev(bdev); kill_bdev(bdev);
...@@ -695,7 +694,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, ...@@ -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 * We want to give the run thread a chance to wait for everybody
* to clean up and then do it's own cleanup. * 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; int i;
for (i = 0; i < nbd->num_connections; 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, ...@@ -703,46 +703,14 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
kfree(nbd->socks); kfree(nbd->socks);
nbd->socks = NULL; nbd->socks = NULL;
nbd->num_connections = 0; 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; return 0;
}
case NBD_DO_IT: { static int nbd_start_device(struct nbd_device *nbd, struct block_device *bdev)
{
struct recv_thread_args *args; struct recv_thread_args *args;
int num_connections = nbd->num_connections; int num_connections = nbd->num_connections;
int error = 0, i; int error = 0, i;
...@@ -798,10 +766,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, ...@@ -798,10 +766,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
mutex_lock(&nbd->config_lock); mutex_lock(&nbd->config_lock);
nbd->task_recv = NULL; nbd->task_recv = NULL;
out_err: out_err:
sock_shutdown(nbd); clear_bit(NBD_RUNNING, &nbd->runtime_flags);
nbd_clear_que(nbd); nbd_clear_sock(nbd, bdev);
kill_bdev(bdev);
nbd_bdev_reset(bdev);
/* user requested, ignore socket errors */ /* user requested, ignore socket errors */
if (test_bit(NBD_DISCONNECT_REQUESTED, &nbd->runtime_flags)) if (test_bit(NBD_DISCONNECT_REQUESTED, &nbd->runtime_flags))
...@@ -811,15 +777,44 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, ...@@ -811,15 +777,44 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
nbd_reset(nbd); nbd_reset(nbd);
return error; 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: case NBD_CLEAR_QUE:
/* /*
* This is for compatibility only. The queue is always cleared * This is for compatibility only. The queue is always cleared
* by NBD_DO_IT or NBD_CLEAR_SOCK. * by NBD_DO_IT or NBD_CLEAR_SOCK.
*/ */
return 0; return 0;
case NBD_PRINT_DEBUG: case NBD_PRINT_DEBUG:
/* /*
* For compatibility only, we no longer keep a list of * For compatibility only, we no longer keep a list of
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册