diff options
author | Johann Latocha | 2012-02-03 20:15:25 +0100 |
---|---|---|
committer | Johann Latocha | 2012-02-03 20:15:25 +0100 |
commit | 6b40869a06d6fb3331630409e0949b75caeb9923 (patch) | |
tree | 7ab1c6012d189aa074945098c6c5cd3ad280b708 /src/kernel | |
parent | [CLIENT] Connecting via config file (diff) | |
download | dnbd3-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.c | 38 | ||||
-rw-r--r-- | src/kernel/net.c | 20 |
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 |