summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorsr2012-09-09 23:01:00 +0200
committersr2012-09-09 23:01:00 +0200
commit3e8cd5b2284fd68206cd7ea9943e892fcce037f8 (patch)
tree3b4a67620bf6bedf678b8b70bf4cf3e7822edf89 /src/kernel
parent[SERVER] Automatically assign and connect a dnbd3 device to a relayed image (diff)
downloaddnbd3-3e8cd5b2284fd68206cd7ea9943e892fcce037f8.tar.gz
dnbd3-3e8cd5b2284fd68206cd7ea9943e892fcce037f8.tar.xz
dnbd3-3e8cd5b2284fd68206cd7ea9943e892fcce037f8.zip
[SERVER] Automatically connect a dnbd3 device for a relayed image
[SERVER] Automatically disconnect dnbd3 device if local cache copy is complete [SERVER] Pre-allocate disk space for cache file [KERNEL] Refuse connection if server reports disk size < 4096 bytes
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/blk.c44
-rw-r--r--src/kernel/net.c17
2 files changed, 37 insertions, 24 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 388f8b6..938a0e8 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -99,34 +99,39 @@ struct block_device_operations dnbd3_blk_ops =
int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
{
- int result = 0;
+ int result = -100;
dnbd3_device_t *dev = bdev->bd_disk->private_data;
struct request_queue *blk_queue = dev->disk->queue;
char *imgname = NULL;
- dnbd3_ioctl_t *msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- unsigned long irqflags;
+ dnbd3_ioctl_t *msg = NULL;
+ //unsigned long irqflags;
- if (msg == NULL) return -ENOMEM;
- copy_from_user((char *)msg, (char *)arg, 2);
- if (msg->len != sizeof(*msg))
+ if (arg != 0)
{
- result = -ENOEXEC;
- goto cleanup_return;
- }
- copy_from_user((char *)msg, (char *)arg, sizeof(*msg));
- if (msg->imgname != NULL && msg->imgnamelen > 0)
- {
- imgname = kmalloc(msg->imgnamelen + 1, GFP_KERNEL);
- if (imgname == NULL)
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (msg == NULL) return -ENOMEM;
+ copy_from_user((char *)msg, (char *)arg, 2);
+ if (msg->len != sizeof(*msg))
{
- result = -ENOMEM;
+ result = -ENOEXEC;
goto cleanup_return;
}
- copy_from_user(imgname, msg->imgname, msg->imgnamelen);
- imgname[msg->imgnamelen] = '\0';
- //printk("IOCTL Image name of len %d is %s\n", (int)msg->imgnamelen, imgname);
+ copy_from_user((char *)msg, (char *)arg, sizeof(*msg));
+ if (msg->imgname != NULL && msg->imgnamelen > 0)
+ {
+ imgname = kmalloc(msg->imgnamelen + 1, GFP_KERNEL);
+ if (imgname == NULL)
+ {
+ result = -ENOMEM;
+ goto cleanup_return;
+ }
+ copy_from_user(imgname, msg->imgname, msg->imgnamelen);
+ imgname[msg->imgnamelen] = '\0';
+ //printk("IOCTL Image name of len %d is %s\n", (int)msg->imgnamelen, imgname);
+ }
}
+
switch (cmd)
{
case IOCTL_OPEN:
@@ -196,7 +201,6 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
}
else
{
- spin_lock_irqsave(&dev->blk_lock, irqflags);
if (dev->new_servers_num >= NUMBER_SERVERS)
result = -EAGAIN;
else
@@ -206,11 +210,11 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
++dev->new_servers_num;
result = 0;
}
- spin_unlock_irqrestore(&dev->blk_lock, irqflags);
}
break;
case BLKFLSBUF:
+ result = 0;
break;
default:
diff --git a/src/kernel/net.c b/src/kernel/net.c
index 67a4b17..d6ebb32 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -231,6 +231,8 @@ int dnbd3_net_connect(dnbd3_device_t *dev)
error_dev_va("FATAL: Server provides rid %d, requested was %d.", (int)rid, (int)dev->rid);
dev->rid = rid;
dev->reported_size = serializer_get_uint64(&dev->payload_buffer);
+ if (dev->reported_size < 4096)
+ error_dev("ERROR: Reported size by server is < 4096");
// store image information
set_capacity(dev->disk, dev->reported_size >> 9); /* 512 Byte blocks */
debug_dev_va("INFO: Filesize: %llu.", dev->reported_size);
@@ -442,6 +444,9 @@ int dnbd3_net_discover(void *data)
continue;
dev->discover = 0;
+ if (dev->reported_size < 4096)
+ continue;
+
// Check if the list of alt servers needs to be updated and do so if neccessary
if (dev->new_servers_num)
{
@@ -457,6 +462,7 @@ int dnbd3_net_discover(void *data)
{
// REMOVE request
alt_server->host.type = 0;
+ debug_dev_va("Removing alt server %pI4", alt_server->host.addr);
continue;
}
// ADD, so just reset fail counter
@@ -469,9 +475,8 @@ int dnbd3_net_discover(void *data)
if (alt_server == NULL) // All NUMBER_SERVERS slots are taken, ignore entry
continue;
// Add new server entry
- memcpy(alt_server->host.addr, dev->new_servers[i].host.addr, 16);
- alt_server->host.type = dev->new_servers[i].host.type;
- alt_server->host.port = dev->new_servers[i].host.port;
+ alt_server->host = dev->new_servers[i].host;
+ debug_dev_va("Adding alt server %pI4", alt_server->host.addr);
alt_server->rtts[0] = alt_server->rtts[1]
= alt_server->rtts[2] = alt_server->rtts[3]
= RTT_UNREACHABLE;
@@ -576,7 +581,11 @@ int dnbd3_net_discover(void *data)
// Request block
dnbd3_request.cmd = CMD_GET_BLOCK;
// Pick random block
- if (sizeof(size_t) >= 8)
+ if (dev->reported_size == 0)
+ {
+ dnbd3_request.offset = 0;
+ }
+ else if (sizeof(size_t) >= 8)
{
dnbd3_request.offset = ((((start.tv_usec << 12) ^ start.tv_usec) << 4) % dev->reported_size) & ~(uint64_t)(RTT_BLOCK_SIZE-1);
//printk("Random offset 64bit: %lluMiB\n", (unsigned long long)(dnbd3_request.offset >> 20));