diff options
author | sr | 2012-09-09 23:01:00 +0200 |
---|---|---|
committer | sr | 2012-09-09 23:01:00 +0200 |
commit | 3e8cd5b2284fd68206cd7ea9943e892fcce037f8 (patch) | |
tree | 3b4a67620bf6bedf678b8b70bf4cf3e7822edf89 /src/kernel | |
parent | [SERVER] Automatically assign and connect a dnbd3 device to a relayed image (diff) | |
download | dnbd3-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.c | 44 | ||||
-rw-r--r-- | src/kernel/net.c | 17 |
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)); |