summaryrefslogtreecommitdiffstats
path: root/src/kernel/core.c
diff options
context:
space:
mode:
authorSimon Rettberg2020-07-17 18:19:58 +0200
committerSimon Rettberg2020-07-17 18:19:58 +0200
commita231e6283e1c79a33d6f3bdf786832f10e355d0c (patch)
treea5be40fa9fe93230d06de56ccac3c378f80c3833 /src/kernel/core.c
parent[KERNEL] After nullptr check, MAYBE RETURN!? (diff)
downloaddnbd3-ng-a231e6283e1c79a33d6f3bdf786832f10e355d0c.tar.gz
dnbd3-ng-a231e6283e1c79a33d6f3bdf786832f10e355d0c.tar.xz
dnbd3-ng-a231e6283e1c79a33d6f3bdf786832f10e355d0c.zip
[KERNEL] Trying to get locking under control
Current code doesn't pay much attention to properly locking when accessing structures that are being used in multiple workers/threads. Try to fix this, slowly.
Diffstat (limited to 'src/kernel/core.c')
-rw-r--r--src/kernel/core.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/kernel/core.c b/src/kernel/core.c
index 35ea1ef..8da2b39 100644
--- a/src/kernel/core.c
+++ b/src/kernel/core.c
@@ -124,6 +124,7 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
switch (cmd) {
case IOCTL_OPEN:
debug_dev(dev, "ioctl open");
+ mutex_lock(&dev->device_lock);
if (dev->imgname != NULL) {
result = -EBUSY;
} else if (imgname == NULL) {
@@ -131,7 +132,6 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
} else if (msg == NULL) {
result = -EINVAL;
} else {
- mutex_lock(&dev->device_lock);
if (sizeof(msg->host) != sizeof(dnbd3_host_t)) {
warn_dev(dev, "odd size bug#1 triggered in ioctl");
}
@@ -154,7 +154,6 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
} else {
dev->number_connections = msg->number_connections;
}
- mutex_unlock(&dev->device_lock);
result = dnbd3_net_connect(dev);
if (result) {
@@ -165,10 +164,12 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
}
imgname = NULL;
}
+ mutex_unlock(&dev->device_lock);
break;
case IOCTL_CLOSE:
debug_dev(dev, "ioctl close");
+ mutex_lock(&dev->device_lock);
result = dnbd3_net_disconnect(dev);
set_capacity(dev->disk, 0);
if (dev->imgname) {
@@ -177,6 +178,7 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
}
dev->rid = 0;
dev->reported_size = 0;
+ mutex_unlock(&dev->device_lock);
break;
case IOCTL_SWITCH:
@@ -187,6 +189,7 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
case IOCTL_ADD_SRV:
case IOCTL_REM_SRV:
debug_dev(dev, "ioctl add/rem srv");
+ mutex_lock(&dev->device_lock);
if (dev->imgname == NULL) {
result = -ENOENT;
} else if (dev->new_servers_num >= NUMBER_SERVERS) {
@@ -194,16 +197,15 @@ static int dnbd3_ioctl(struct block_device *bdev, fmode_t mode,
} else if (msg == NULL) {
result = -EINVAL;
} else {
- mutex_lock(&dev->device_lock);
memcpy(&dev->new_servers[dev->new_servers_num].host,
&msg->host, sizeof(msg->host));
/* 0 = ADD, 1 = REM */
dev->new_servers[dev->new_servers_num].failures =
(cmd == IOCTL_ADD_SRV ? 0 : 1);
dev->new_servers_num++;
- mutex_unlock(&dev->device_lock);
result = 0;
}
+ mutex_unlock(&dev->device_lock);
break;
case BLKFLSBUF:
@@ -417,7 +419,7 @@ static void dnbd3_dev_remove(struct dnbd3_device *dev)
struct gendisk *disk = dev->disk;
struct request_queue *q;
- if (dev->connected) {
+ if (dev->socks) {
dnbd3_net_disconnect(dev);
}