summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorsr2013-07-18 15:04:05 +0200
committersr2013-07-18 15:04:05 +0200
commit2a57d02723295cb688f1643ebabdbf549ad63fa3 (patch)
treecdf14624304cec1103d1cf7ca78da82057eed5d5 /src/kernel
parentkernel module changes (diff)
downloaddnbd3-2a57d02723295cb688f1643ebabdbf549ad63fa3.tar.gz
dnbd3-2a57d02723295cb688f1643ebabdbf549ad63fa3.tar.xz
dnbd3-2a57d02723295cb688f1643ebabdbf549ad63fa3.zip
fix deadlock
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/blk.c25
-rw-r--r--src/kernel/net.c4
2 files changed, 21 insertions, 8 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 2bb70de..72f354c 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -47,6 +47,7 @@ int dnbd3_blk_add_device(dnbd3_device_t *dev, int minor)
dev->thread_receive = NULL;
dev->thread_discover = NULL;
dev->discover = 0;
+ dev->disconnecting = 0;
dev->panic = 0;
dev->panic_count = 0;
dev->reported_size = 0;
@@ -106,22 +107,27 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
dnbd3_ioctl_t *msg = NULL;
//unsigned long irqflags;
+ printk("ioctl: A\n");
while (dev->disconnecting)
{
// do nothing
}
+ printk("ioctl: B\n");
if (arg != 0)
{
msg = kmalloc(sizeof(*msg), GFP_KERNEL);
if (msg == NULL) return -ENOMEM;
- copy_from_user((char *)msg, (char *)arg, 2);
- if (msg->len != sizeof(*msg))
+ if (copy_from_user((char *)msg, (char *)arg, 2) != 0 || msg->len != sizeof(*msg))
{
result = -ENOEXEC;
goto cleanup_return;
}
- copy_from_user((char *)msg, (char *)arg, sizeof(*msg));
+ if (copy_from_user((char *)msg, (char *)arg, sizeof(*msg)) != 0)
+ {
+ result = -ENOENT;
+ goto cleanup_return;
+ }
if (msg->imgname != NULL && msg->imgnamelen > 0)
{
imgname = kmalloc(msg->imgnamelen + 1, GFP_KERNEL);
@@ -130,7 +136,11 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
result = -ENOMEM;
goto cleanup_return;
}
- copy_from_user(imgname, msg->imgname, msg->imgnamelen);
+ if (copy_from_user(imgname, msg->imgname, msg->imgnamelen) != 0)
+ {
+ result = -ENOENT;
+ goto cleanup_return;
+ }
imgname[msg->imgnamelen] = '\0';
//printk("IOCTL Image name of len %d is %s\n", (int)msg->imgnamelen, imgname);
}
@@ -233,11 +243,14 @@ cleanup_return:
return result;
}
+/**
+ * dev->blk_lock and q->queue_lock are being held
+ * when this is called!
+ */
void dnbd3_blk_request(struct request_queue *q)
{
struct request *req;
dnbd3_device_t *dev;
- unsigned long flags;
while ((req = blk_fetch_request(q)) != NULL)
{
@@ -267,9 +280,7 @@ void dnbd3_blk_request(struct request_queue *q)
continue;
}
- spin_lock_irqsave(&dev->blk_lock, flags);
list_add_tail(&req->queuelist, &dev->request_queue_send);
- spin_unlock_irqrestore(&dev->blk_lock, flags);
spin_unlock_irq(q->queue_lock);
wake_up(&dev->process_queue_send);
spin_lock_irq(q->queue_lock);
diff --git a/src/kernel/net.c b/src/kernel/net.c
index 24fc4d6..36abf45 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -848,8 +848,10 @@ int dnbd3_net_send(void *data)
error:
debug_dev("ERROR: Connection to server lost (send)");
- if (dev->sock)
+ if (dev->sock) {
kernel_sock_shutdown(dev->sock, SHUT_RDWR);
+ dev->sock = NULL;
+ }
dev->thread_send = NULL;
if (!dev->disconnecting)
{