summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorJohann Latocha2012-02-03 20:15:25 +0100
committerJohann Latocha2012-02-03 20:15:25 +0100
commit6b40869a06d6fb3331630409e0949b75caeb9923 (patch)
tree7ab1c6012d189aa074945098c6c5cd3ad280b708 /src/kernel
parent[CLIENT] Connecting via config file (diff)
downloaddnbd3-6b40869a06d6fb3331630409e0949b75caeb9923.tar.gz
dnbd3-6b40869a06d6fb3331630409e0949b75caeb9923.tar.xz
dnbd3-6b40869a06d6fb3331630409e0949b75caeb9923.zip
[KERNEL] Device can now be closed
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/blk.c38
-rw-r--r--src/kernel/net.c20
2 files changed, 39 insertions, 19 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index c4bbeb1..46e20d8 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -33,6 +33,7 @@ int dnbd3_blk_add_device(dnbd3_device_t *dev, int minor)
dev->vid = 0;
dev->rid = 0;
+ dev->sock = NULL;
if (!(disk = alloc_disk(1)))
{
@@ -89,34 +90,41 @@ struct block_device_operations dnbd3_blk_ops =
int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
{
dnbd3_device_t *lo = bdev->bd_disk->private_data;
+ int minor = lo->disk->first_minor;
+
+ dnbd3_ioctl_t *msg = kmalloc(sizeof(dnbd3_ioctl_t), GFP_KERNEL);
+ copy_from_user((char *)msg, (char *)arg, sizeof(*msg));
switch (cmd)
{
- case IOCTL_SET_HOST:
- strcpy(lo->host, (char *) arg);
- break;
- case IOCTL_SET_PORT:
- strcpy(lo->port, (char *) arg);
- break;
- case IOCTL_SET_VID:
- lo->vid = arg;
- break;
- case IOCTL_SET_RID:
- lo->rid = arg;
- break;
- case IOCTL_CONNECT:
+ case IOCTL_OPEN:
+ strcpy(lo->host, msg->host);
+ strcpy(lo->port, msg->port);
+ lo->vid = msg->vid;
+ lo->rid = msg->rid;
dnbd3_net_connect(lo);
break;
- case IOCTL_DISCONNECT:
+
+ case IOCTL_CLOSE:
dnbd3_net_disconnect(lo);
+ dnbd3_blk_del_device(lo);
+ dnbd3_blk_add_device(lo, minor);
break;
+
+ case IOCTL_SWITCH:
+ dnbd3_net_disconnect(lo);
+ strcpy(lo->host, msg->host);
+ dnbd3_net_connect(lo);
+ break;
+
case BLKFLSBUF:
break;
default:
return -1;
-
}
+
+ kfree(msg);
return 0;
}
diff --git a/src/kernel/net.c b/src/kernel/net.c
index a83b4b6..53a12af 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -35,13 +35,19 @@ void dnbd3_net_connect(dnbd3_device_t *lo)
return;
}
- // TODO: check if already connected
+ if (lo->sock)
+ {
+ printk("ERROR: Device %s already connected to %s.\n", lo->disk->disk_name, lo->host);
+ return;
+ }
+
printk("INFO: Connecting device %s to %s\n", lo->disk->disk_name, lo->host);
// initialize socket
if (sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &lo->sock) < 0)
{
- printk("ERROR: dnbd3 couldn't create socket.\n");
+ printk("ERROR: Couldn't create socket.\n");
+ lo->sock = NULL;
return;
}
lo->sock->sk->sk_allocation = GFP_NOIO;
@@ -50,7 +56,8 @@ void dnbd3_net_connect(dnbd3_device_t *lo)
sin.sin_port = htons(simple_strtol(lo->port, NULL, 10));
if (kernel_connect(lo->sock, (struct sockaddr *) &sin, sizeof(sin), 0) < 0)
{
- printk("ERROR: dnbd3 couldn't connect to host %s:%s\n", lo->host, lo->port);
+ printk("ERROR: Couldn't connect to host %s:%s\n", lo->host, lo->port);
+ lo->sock = NULL;
return;
}
@@ -78,10 +85,13 @@ void dnbd3_net_connect(dnbd3_device_t *lo)
if (dnbd3_reply.filesize <= 0)
{
printk("ERROR: File size returned by server is < 0.\n");
+ sock_release(lo->sock);
+ lo->sock = NULL;
return;
}
+
set_capacity(lo->disk, dnbd3_reply.filesize >> 9); /* 512 Byte blocks */
- printk("INFO: dnbd3 filesize: %llu\n", dnbd3_reply.filesize);
+ printk("INFO: Filesize %s: %llu\n", lo->disk->disk_name, dnbd3_reply.filesize);
// start sending thread
lo->thread_send = kthread_create(dnbd3_net_send, lo, lo->disk->disk_name);
@@ -109,6 +119,8 @@ void dnbd3_net_disconnect(dnbd3_device_t *lo)
{
kthread_stop(lo->thread_send);
kthread_stop(lo->thread_receive);
+ lo->thread_send = NULL;
+ lo->thread_receive = NULL;
}
// clear sock