]> git.pld-linux.org Git - packages/kernel.git/blame - linux-cluster-gnbd.patch
+CONFIG_IP_NF_MATCH_LAYER7=m
[packages/kernel.git] / linux-cluster-gnbd.patch
CommitLineData
4bf12011 1diff -urN linux-2.6.7/drivers/block/Kconfig linux-2.6.7-patched/drivers/block/Kconfig
2--- linux-2.6.7/drivers/block/Kconfig 2004-06-16 00:19:01.000000000 -0500
3+++ linux-2.6.7-patched/drivers/block/Kconfig 2004-06-17 16:38:45.000000000 -0500
4@@ -347,6 +347,13 @@
5 your machine, or if you want to have a raid or loopback device
6 bigger than 2TB. Otherwise say N.
7
8+config BLK_DEV_GNBD
9+ tristate "Global network block device support"
10+ depends on NET
11+ ---help---
12+
13+ If unsure, say N.
14+
15 source "drivers/s390/block/Kconfig"
16
17 endmenu
18diff -urN linux-2.6.7/drivers/block/Makefile linux-2.6.7-patched/drivers/block/Makefile
19--- linux-2.6.7/drivers/block/Makefile 2004-06-16 00:19:52.000000000 -0500
20+++ linux-2.6.7-patched/drivers/block/Makefile 2004-06-17 16:38:45.000000000 -0500
21@@ -42,4 +42,4 @@
22
23 obj-$(CONFIG_VIODASD) += viodasd.o
24 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
25-
26+obj-$(CONFIG_BLK_DEV_GNBD) += gnbd.o
27diff -urN linux-orig/drivers/block/gnbd.c linux-patched/drivers/block/gnbd.c
28--- linux-orig/drivers/block/gnbd.c 1969-12-31 18:00:00.000000000 -0600
5cdbd17b
AM
29+++ linux-patched/drivers/block/gnbd.c 2004-06-30 16:48:06.000000000 -0500
30@@ -0,0 +1,1076 @@
4bf12011 31+/******************************************************************************
32+*******************************************************************************
33+**
34+** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
35+** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
36+**
37+** This copyrighted material is made available to anyone wishing to use,
38+** modify, copy, or redistribute it subject to the terms and conditions
39+** of the GNU General Public License v.2.
40+**
41+*******************************************************************************
42+******************************************************************************/
43+
44+/* Large chunks of this code were lifted from nbd.c */
45+
46+#include <linux/major.h>
47+
48+#include <linux/blkdev.h>
49+#include <linux/module.h>
50+#include <linux/init.h>
51+#include <linux/sched.h>
52+#include <linux/fs.h>
53+#include <linux/bio.h>
54+#include <linux/stat.h>
55+#include <linux/errno.h>
56+#include <linux/file.h>
57+#include <linux/ioctl.h>
58+#include <net/sock.h>
59+#include <linux/in.h>
60+#include <linux/buffer_head.h>
61+#include <linux/miscdevice.h>
62+
63+#include <linux/devfs_fs_kernel.h>
64+
65+#include <asm/uaccess.h>
66+#include <asm/types.h>
67+
68+#include <linux/gnbd.h>
69+
70+static int major_nr = 0;
71+uint64_t insmod_time;
72+
73+
74+#define GNBD_MAGIC 0x74d06100
75+
76+#ifdef NDEBUG
77+#define dprintk(flags, fmt...)
78+#else /* NDEBUG */
79+#define dprintk(flags, fmt...) do { \
80+ if (debugflags & (flags)) printk(KERN_DEBUG fmt); \
81+} while (0)
82+#define DBG_IOCTL 0x0004
83+#define DBG_INIT 0x0010
84+#define DBG_EXIT 0x0020
85+#define DBG_BLKDEV 0x0100
86+#define DBG_RX 0x0200
87+#define DBG_TX 0x0400
88+static unsigned int debugflags;
89+#endif /* NDEBUG */
90+
91+static struct gnbd_device gnbd_dev[MAX_GNBD];
92+
93+struct request shutdown_req;
94+struct request ping_req;
95+
96+static spinlock_t gnbd_lock = SPIN_LOCK_UNLOCKED;
97+
98+#define to_gnbd_dev(d) container_of(d, struct gnbd_device, class_dev)
99+
100+static void gnbd_class_release(struct class_device *class_dev)
101+{
102+ printk("releasing gnbd class\n");
103+ /* FIXME -- What the hell do I have to free up here */
104+}
105+
106+static struct class gnbd_class = {
107+ .name = "gnbd",
108+ .release = gnbd_class_release
109+};
110+
111+
112+static ssize_t show_pid(struct class_device *class_dev, char *buf)
113+{
114+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
115+ return sprintf(buf, "%d\n", dev->receiver_pid);
116+}
117+
118+static CLASS_DEVICE_ATTR(pid, S_IRUGO, show_pid, NULL);
119+
120+static ssize_t show_server(struct class_device *class_dev, char *buf)
121+{
122+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
5cdbd17b
AM
123+ if (dev->server_name)
124+ return sprintf(buf, "%s/%hx\n", dev->server_name,
125+ dev->server_port);
126+ else
127+ return sprintf(buf, "\n");
4bf12011 128+}
129+
5cdbd17b 130+/* FIXME -- should a empty store free the memory */
4bf12011 131+static ssize_t store_server(struct class_device *class_dev,
132+ const char *buf, size_t count)
133+{
134+ int res;
4bf12011 135+ short unsigned int port;
5cdbd17b 136+ char *ptr;
4bf12011 137+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
138+ if (down_trylock(&dev->do_it_lock))
139+ return -EBUSY;
5cdbd17b
AM
140+ if (dev->server_name)
141+ kfree(dev->server_name);
142+ dev->server_name = kmalloc(count + 1, GFP_KERNEL);
143+ if (!dev->server_name)
144+ return -ENOMEM;
145+ memcpy(dev->server_name, buf, count);
146+ dev->server_name[count] = 0;
147+ ptr = strchr(dev->server_name, '/');
148+ if (!ptr)
149+ return -EINVAL;
150+ *ptr++ = 0;
151+ res = sscanf(ptr, "%4hx", &port);
152+ if (res != 1){
4bf12011 153+ up(&dev->do_it_lock);
154+ return -EINVAL;
155+ }
4bf12011 156+ dev->server_port = port;
157+ up(&dev->do_it_lock);
158+ return count;
159+}
160+
161+CLASS_DEVICE_ATTR(server, S_IRUGO | S_IWUSR, show_server, store_server);
162+
163+static ssize_t show_name(struct class_device *class_dev, char *buf)
164+{
165+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
166+ return sprintf(buf, "%s\n", dev->name);
167+}
168+
169+static ssize_t store_name(struct class_device *class_dev,
170+ const char *buf, size_t count)
171+{
172+ int res;
173+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
174+ if (down_trylock(&dev->do_it_lock))
175+ return -EBUSY;
176+ res = sscanf(buf, "%31s", dev->name);
177+ up(&dev->do_it_lock);
178+ if (res != 1)
179+ return -EINVAL;
180+ return count;
181+}
182+
183+CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_name, store_name);
184+
185+
186+static ssize_t show_sectors(struct class_device *class_dev, char *buf)
187+{
188+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
189+ return sprintf(buf, "%Lu\n",
190+ (unsigned long long)get_capacity(dev->disk));
191+}
192+
193+static ssize_t store_sectors(struct class_device *class_dev,
194+ const char *buf, size_t count)
195+{
196+ int res;
197+ sector_t size;
198+ struct block_device *bdev;
199+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
200+
201+ if (down_trylock(&dev->do_it_lock))
202+ return -EBUSY;
203+ res = sscanf(buf, "%Lu\n", &size);
204+ if (res != 1){
205+ up(&dev->do_it_lock);
206+ return -EINVAL;
207+ }
208+ /* FIXME -- should I switch the order here, so that I don't have
209+ capacity set to one thing and the bdev inode size set to another */
210+ set_capacity(dev->disk, size);
211+ bdev = bdget_disk(dev->disk, 0);
212+ if (bdev) {
213+ down(&bdev->bd_inode->i_sem);
214+ i_size_write(bdev->bd_inode, (loff_t)size << 9);
215+ up(&bdev->bd_inode->i_sem);
216+ bdput(bdev);
217+ }
218+ up(&dev->do_it_lock);
219+ return count;
220+}
221+
222+CLASS_DEVICE_ATTR(sectors, S_IRUGO | S_IWUSR, show_sectors, store_sectors);
223+
224+static ssize_t show_usage(struct class_device *class_dev, char *buf)
225+{
226+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
227+ return sprintf(buf, "%d\n", dev->open_count);
228+}
229+
230+CLASS_DEVICE_ATTR(usage, S_IRUGO, show_usage, NULL);
231+
232+static ssize_t show_flags(struct class_device *class_dev, char *buf)
233+{
234+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
235+ return sprintf(buf, "0x%04x\n", dev->flags);
236+}
237+
238+static ssize_t store_flags(struct class_device *class_dev,
239+ const char *buf, size_t count)
240+{
241+ int res;
242+
243+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
244+ if (down_trylock(&dev->do_it_lock))
245+ return -EBUSY;
246+ res = sscanf(buf, "0x%hx", &dev->flags);
247+ up(&dev->do_it_lock);
248+ if (res != 1)
249+ return -EINVAL;
250+ return count;
251+}
252+
253+
254+CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
255+
256+static ssize_t show_waittime(struct class_device *class_dev, char *buf)
257+{
258+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
259+ if (list_empty(&dev->queue_head))
260+ return sprintf(buf, "-1\n");
261+ return sprintf(buf, "%ld\n",
262+ ((long)jiffies - (long)dev->last_received) / HZ);
263+}
264+
265+CLASS_DEVICE_ATTR(waittime, S_IRUGO, show_waittime, NULL);
266+
267+static ssize_t show_connected(struct class_device *class_dev, char *buf)
268+{
269+ struct gnbd_device *dev = to_gnbd_dev(class_dev);
270+ return sprintf(buf, "%d\n", (dev->sock != NULL));
271+}
272+
273+CLASS_DEVICE_ATTR(connected, S_IRUGO, show_connected, NULL);
274+
275+#ifndef NDEBUG
276+static const char *ioctl_cmd_to_ascii(int cmd)
277+{
278+ switch (cmd) {
279+ case GNBD_DO_IT: return "do-it";
280+ case GNBD_CLEAR_QUE: return "clear-que";
281+ case GNBD_PRINT_DEBUG: return "print-debug";
282+ case GNBD_DISCONNECT: return "disconnect";
283+ }
284+ return "unknown";
285+}
286+
287+static const char *gnbdcmd_to_ascii(int cmd)
288+{
289+ switch (cmd) {
290+ case GNBD_CMD_READ: return "read";
291+ case GNBD_CMD_WRITE: return "write";
292+ case GNBD_CMD_DISC: return "disconnect";
293+ case GNBD_CMD_PING: return "ping";
294+ }
295+ return "invalid";
296+}
297+#endif /* NDEBUG */
298+
299+static void gnbd_end_request(struct request *req)
300+{
301+ int uptodate = (req->errors == 0) ? 1 : 0;
302+ request_queue_t *q = req->q;
303+ struct gnbd_device *dev = req->rq_disk->private_data;
304+ unsigned long flags;
305+
306+ dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name,
307+ req, uptodate? "done": "failed");
308+
309+ if (!uptodate)
310+ printk("%s %d called gnbd_end_request with and error\n",
311+ current->comm, current->pid);
312+
313+ spin_lock(&dev->queue_lock);
314+ while (req->ref_count > 1) { /* still in send */
315+ spin_unlock(&dev->queue_lock);
316+ printk(KERN_DEBUG "%s: request %p still in use (%d), waiting\n",
317+ dev->disk->disk_name, req, req->ref_count);
318+ set_current_state(TASK_UNINTERRUPTIBLE);
319+ schedule_timeout(HZ); /* wait a second */
320+ spin_lock(&dev->queue_lock);
321+ }
322+ spin_unlock(&dev->queue_lock);
323+
324+ spin_lock_irqsave(q->queue_lock, flags);
325+ if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
326+ end_that_request_last(req);
327+ }
328+ spin_unlock_irqrestore(q->queue_lock, flags);
329+}
330+
331+/*
332+ * Send or receive packet.
333+ */
334+static int sock_xmit(struct socket *sock, int send, void *buf, int size,
335+ int msg_flags)
336+{
337+ mm_segment_t oldfs;
338+ int result;
339+ struct msghdr msg;
340+ struct iovec iov;
341+ unsigned long flags;
342+ sigset_t oldset;
343+
344+ oldfs = get_fs();
345+ set_fs(get_ds());
346+ /* Allow interception of SIGKILL only
347+ * Don't allow other signals to interrupt the transmission */
348+ spin_lock_irqsave(&current->sighand->siglock, flags);
349+ oldset = current->blocked;
350+ sigfillset(&current->blocked);
351+ sigdelsetmask(&current->blocked, sigmask(SIGKILL));
352+ recalc_sigpending();
353+ spin_unlock_irqrestore(&current->sighand->siglock, flags);
354+
355+ do {
356+ sock->sk->sk_allocation = GFP_NOIO;
357+ iov.iov_base = buf;
358+ iov.iov_len = size;
359+ msg.msg_name = NULL;
360+ msg.msg_namelen = 0;
361+ msg.msg_iov = &iov;
362+ msg.msg_iovlen = 1;
363+ msg.msg_control = NULL;
364+ msg.msg_controllen = 0;
365+ msg.msg_namelen = 0;
366+ msg.msg_flags = msg_flags | MSG_NOSIGNAL;
367+
368+ if (send)
369+ result = sock_sendmsg(sock, &msg, size);
370+ else
371+ result = sock_recvmsg(sock, &msg, size, 0);
372+
373+ if (signal_pending(current)) {
374+ siginfo_t info;
375+ spin_lock_irqsave(&current->sighand->siglock, flags);
376+ printk(KERN_WARNING "gnbd (pid %d: %s) got signal %d\n",
377+ current->pid, current->comm,
378+ dequeue_signal(current, &current->blocked, &info));
379+ spin_unlock_irqrestore(&current->sighand->siglock, flags);
380+ result = -EINTR;
381+ break;
382+ }
383+
384+ if (result <= 0) {
385+ if (result == 0)
386+ result = -EPIPE; /* short read */
387+ break;
388+ }
389+ size -= result;
390+ buf += result;
391+ } while (size > 0);
392+
393+ spin_lock_irqsave(&current->sighand->siglock, flags);
394+ current->blocked = oldset;
395+ recalc_sigpending();
396+ spin_unlock_irqrestore(&current->sighand->siglock, flags);
397+
398+ set_fs(oldfs);
399+ return result;
400+}
401+
402+static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec,
403+ int flags)
404+{
405+ int result;
406+ void *kaddr = kmap(bvec->bv_page);
407+ result = sock_xmit(sock, 1, kaddr + bvec->bv_offset, bvec->bv_len,
408+ flags);
409+ kunmap(bvec->bv_page);
410+ return result;
411+}
412+
413+
414+#define gnbd_send_req(dev, req) __gnbd_send_req((dev), (dev)->sock, (req))
415+
416+int __gnbd_send_req(struct gnbd_device *dev, struct socket *sock,
417+ struct request *req)
418+{
419+ int result, i, flags;
420+ struct gnbd_request request;
421+ unsigned long size = req->nr_sectors << 9;
422+
423+ request.magic = htonl(GNBD_REQUEST_MAGIC);
424+ request.type = htonl(gnbd_cmd(req));
425+ request.from = cpu_to_be64((u64) req->sector << 9);
426+ request.len = htonl(size);
427+ memcpy(request.handle, &req, sizeof(req));
428+
429+ down(&dev->tx_lock);
430+
431+ if (!sock) {
432+ printk(KERN_ERR "%s: Attempted send on closed socket\n",
433+ dev->disk->disk_name);
434+ result = -ENOTCONN;
435+ goto error_out;
436+ }
437+
438+ dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%luB)\n",
439+ dev->disk->disk_name, req,
440+ gnbdcmd_to_ascii(gnbd_cmd(req)),
441+ (unsigned long long)req->sector << 9,
442+ req->nr_sectors << 9);
443+ result = sock_xmit(sock, 1, &request, sizeof(request),
444+ (gnbd_cmd(req) == GNBD_CMD_WRITE)? MSG_MORE: 0);
445+ if (result < 0) {
446+ printk(KERN_ERR "%s: Send control failed (result %d)\n",
447+ dev->disk->disk_name, result);
448+ goto error_out;
449+ }
450+
451+ if (gnbd_cmd(req) == GNBD_CMD_WRITE) {
452+ struct bio *bio;
453+ /*
454+ * we are really probing at internals to determine
455+ * whether to set MSG_MORE or not...
456+ */
457+ rq_for_each_bio(bio, req) {
458+ struct bio_vec *bvec;
459+ bio_for_each_segment(bvec, bio, i) {
460+ flags = 0;
461+ if ((i < (bio->bi_vcnt - 1)) || bio->bi_next)
462+ flags = MSG_MORE;
463+ dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
464+ dev->disk->disk_name, req,
465+ bvec->bv_len);
466+ result = sock_send_bvec(sock, bvec, flags);
467+ if (result < 0) {
468+ printk(KERN_ERR "%s: Send data failed (result %d)\n",
469+ dev->disk->disk_name,
470+ result);
471+ goto error_out;
472+ }
473+ }
474+ }
475+ }
476+ up(&dev->tx_lock);
477+ return 0;
478+
479+error_out:
480+ up(&dev->tx_lock);
481+ return result;
482+}
483+
484+
485+static int gnbd_find_request(struct gnbd_device *dev, struct request *xreq)
486+{
487+ struct request *req;
488+ struct list_head *tmp;
489+
490+ list_for_each(tmp, &dev->queue_head) {
491+ req = list_entry(tmp, struct request, queuelist);
492+ if (req != xreq)
493+ continue;
494+ return 1;
495+ }
496+ return 0;
497+}
498+
499+static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec)
500+{
501+ int result;
502+ void *kaddr = kmap(bvec->bv_page);
503+ result = sock_xmit(sock, 0, kaddr + bvec->bv_offset, bvec->bv_len,
504+ MSG_WAITALL);
505+ kunmap(bvec->bv_page);
506+ return result;
507+}
508+
509+int gnbd_recv_req(struct gnbd_device *dev, struct request *req)
510+{
511+ int result;
512+ int i;
513+ struct bio *bio;
514+ rq_for_each_bio(bio, req) {
515+ struct bio_vec *bvec;
516+ bio_for_each_segment(bvec, bio, i) {
517+ result = sock_recv_bvec(dev->sock, bvec);
518+ if (result < 0) {
519+ printk(KERN_ERR "%s: Receive data failed (result %d)\n",
520+ dev->disk->disk_name,
521+ result);
522+ return result;
523+ }
524+ dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
525+ dev->disk->disk_name, req, bvec->bv_len);
526+ }
527+ }
528+ return 0;
529+}
530+
531+int gnbd_do_it(struct gnbd_device *dev)
532+{
533+ int result;
534+ struct gnbd_reply reply;
535+ struct request *req;
536+ struct socket *sock = dev->sock;
537+
538+ BUG_ON(dev->magic != GNBD_MAGIC);
539+
540+ while((result = sock_xmit(sock, 0, &reply,sizeof(reply), MSG_WAITALL)) > 0){
541+ if (ntohl(reply.magic) == GNBD_KEEP_ALIVE_MAGIC)
542+ /* FIXME -- I should reset the wait time here */
543+ continue;
544+
545+ memcpy(&req, reply.handle, sizeof(req));
546+ if (req == &shutdown_req)
547+ return 0;
548+
549+ if (!gnbd_find_request(dev, req)){
550+ printk(KERN_ERR "%s: Unexpected reply (%p)\n",
551+ dev->disk->disk_name, reply.handle);
552+ return -EBADR;
553+ }
554+ if (ntohl(reply.magic) != GNBD_REPLY_MAGIC) {
555+ printk(KERN_ERR "%s: Wrong magic (0x%lx)\n",
556+ dev->disk->disk_name,
557+ (unsigned long)ntohl(reply.magic));
558+ return -EPROTO;
559+ }
560+ if (ntohl(reply.error)) {
561+ printk(KERN_ERR "%s: Other side returned error (%d)\n",
562+ dev->disk->disk_name, ntohl(reply.error));
563+ req->errors++;
564+ goto remove_req;
565+ }
566+ dprintk(DBG_RX, "%s: request %p: got reply\n",
567+ dev->disk->disk_name, req);
568+
569+ if (gnbd_cmd(req) == GNBD_CMD_READ){
570+ result = gnbd_recv_req(dev, req);
571+ if (result < 0)
572+ return result;
573+ }
574+remove_req:
575+ spin_lock(&dev->queue_lock);
576+ list_del_init(&req->queuelist);
577+ dev->last_received = jiffies;
578+ spin_unlock(&dev->queue_lock);
579+ if (req != &ping_req)
580+ gnbd_end_request(req);
581+ }
582+ printk(KERN_ERR "%s: Receive control failed (result %d)\n",
583+ dev->disk->disk_name, result);
584+ return result;
585+}
586+
587+void gnbd_clear_que(struct gnbd_device *dev)
588+{
589+ struct request *req;
590+
591+ BUG_ON(dev->magic != GNBD_MAGIC);
592+
593+ do {
594+ req = NULL;
595+ if (!list_empty(&dev->queue_head)) {
596+ req = list_entry(dev->queue_head.next, struct request, queuelist);
597+ list_del_init(&req->queuelist);
598+ }
599+ if (req && req != &ping_req) {
600+ req->errors++;
601+ gnbd_end_request(req);
602+ }
603+ } while (req);
604+}
605+
606+/*
607+ * We always wait for result of write, for now. It would be nice to make it optional
608+ * in future
609+ * if ((req->cmd == WRITE) && (dev->flags & GNBD_WRITE_NOCHK))
610+ * { printk( "Warning: Ignoring result!\n"); gnbd_end_request( req ); }
611+ */
612+
613+static void do_gnbd_request(request_queue_t * q)
614+{
615+ int err;
616+ struct request *req;
617+
618+ while ((req = elv_next_request(q)) != NULL) {
619+ struct gnbd_device *dev;
620+
621+ blkdev_dequeue_request(req);
622+ dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n",
623+ req->rq_disk->disk_name, req, req->flags);
624+
625+ if (!(req->flags & REQ_CMD))
626+ goto error_out;
627+
628+ dev = req->rq_disk->private_data;
629+
630+ if (dev->receiver_pid == -1)
631+ goto error_out;
632+
633+ BUG_ON(dev->magic != GNBD_MAGIC);
634+
635+ gnbd_cmd(req) = GNBD_CMD_READ;
636+ if (rq_data_dir(req) == WRITE) {
637+ gnbd_cmd(req) = GNBD_CMD_WRITE;
638+ if (dev->flags & GNBD_READ_ONLY) {
639+ printk(KERN_ERR "%s: Write on read-only\n",
640+ dev->disk->disk_name);
641+ goto error_out;
642+ }
643+ }
644+
645+ req->errors = 0;
646+ spin_unlock_irq(q->queue_lock);
647+
648+ spin_lock(&dev->queue_lock);
649+
650+ if (list_empty(&dev->queue_head))
651+ dev->last_received = jiffies;
652+ list_add(&req->queuelist, &dev->queue_head);
653+ req->ref_count++; /* make sure req does not get freed */
654+ spin_unlock(&dev->queue_lock);
655+
656+ err = gnbd_send_req(dev, req);
657+
658+ spin_lock(&dev->queue_lock);
659+ req->ref_count--;
660+ spin_unlock(&dev->queue_lock);
661+ spin_lock_irq(q->queue_lock);
662+ if (err)
663+ goto sock_error;
664+ continue;
665+
666+error_out:
667+ req->errors++;
668+ spin_unlock(q->queue_lock);
669+ gnbd_end_request(req);
670+ spin_lock(q->queue_lock);
671+ }
672+ return;
673+
674+sock_error:
675+ return;
676+}
677+
678+/*
679+ * This is called before dev-sock is set, so you dodn't need
680+ * to worry about the tx_lock or the queue_lock
681+ */
682+static int gnbd_resend_requests(struct gnbd_device *dev, struct socket *sock)
683+{
684+ int err = 0;
685+ struct request *req;
686+ struct list_head *tmp;
687+
688+ printk("resending requests\n");
689+ list_for_each(tmp, &dev->queue_head) {
690+ req = list_entry(tmp, struct request, queuelist);
691+ err = __gnbd_send_req(dev, sock, req);
692+
693+ if (err){
694+ printk("failed trying to resend request (%d)\n", err);
695+ break;
696+ }
697+ }
698+
699+ return err;
700+}
701+/*
702+static int get_server_info(struct gnbd_device *dev, struct socket *sock)
703+{
704+ struct sockaddr_in server;
705+ int len;
706+ int err;
707+
708+ err = sock->ops->getname(sock, (struct sockaddr *) &server, &len, 1);
709+ if (err) {
710+ printk(KERN_WARNING "cannot get socket info, shutting down\n");
711+ } else{
712+ dev->server_addr = server.sin_addr;
713+ dev->server_port = server.sin_port;
714+ }
715+ return err;
716+}
717+*/
718+
719+static int gnbd_ctl_ioctl(struct inode *inode, struct file *file,
720+ unsigned int cmd, unsigned long arg)
721+{
722+ struct gnbd_device *dev = NULL;
723+ struct block_device *bdev;
724+ do_it_req_t req;
725+ int error;
726+
727+ if (!capable(CAP_SYS_ADMIN))
728+ return -EPERM;
729+
730+ if (cmd == GNBD_DISCONNECT || cmd == GNBD_CLEAR_QUE ||
731+ cmd == GNBD_PING || cmd == GNBD_PRINT_DEBUG) {
732+ if (arg >= MAX_GNBD)
733+ return -EINVAL;
734+ dev = &gnbd_dev[arg];
735+ BUG_ON(dev->magic != GNBD_MAGIC);
736+ }
737+
738+ /* Anyone capable of this syscall can do *real bad* things */
739+ dprintk(DBG_IOCTL, "%s: gnbd_ioctl cmd=%s(0x%x) arg=%lu\n",
740+ dev->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
741+
742+ switch (cmd) {
743+ case GNBD_DISCONNECT:
744+ printk(KERN_INFO "%s: GNBD_DISCONNECT\n", dev->disk->disk_name);
745+ spin_lock(&dev->open_lock);
746+ if (dev->open_count > 0){
747+ spin_unlock(&dev->open_lock);
748+ return -EBUSY;
749+ }
750+ dev->receiver_pid = -1;
751+ spin_unlock(&dev->open_lock);
752+ /* There is no one using the device, you can disconnect it */
753+ if (dev->sock == NULL)
754+ return -ENOTCONN;
755+ gnbd_send_req(dev, &shutdown_req);
756+ return 0;
757+ case GNBD_CLEAR_QUE:
758+ if (down_interruptible(&dev->do_it_lock))
759+ return -EBUSY;
760+ dev->receiver_pid = -1;
761+ gnbd_clear_que(dev);
762+ bdev = dev->bdev;
763+ if (bdev) {
764+ blk_run_queue(dev->disk->queue);
765+ fsync_bdev(bdev);
766+ invalidate_bdev(bdev, 0);
767+ }
768+ up(&dev->do_it_lock);
769+ return 0;
770+ case GNBD_DO_IT:
771+ if (copy_from_user(&req, (do_it_req_t *)arg, sizeof(req)))
772+ return -EFAULT;
773+ if (req.minor >= 128)
774+ return -EINVAL;
775+ dev = &gnbd_dev[req.minor];
776+ BUG_ON(dev->magic != GNBD_MAGIC);
777+ if (dev->file)
778+ return -EBUSY;
779+ error = -EINVAL;
780+ file = fget(req.sock_fd);
781+ if (!file)
782+ return error;
783+ inode = file->f_dentry->d_inode;
784+ if (!inode->i_sock) {
785+ fput(file);
786+ return error;
787+ }
788+ if (down_trylock(&dev->do_it_lock)){
789+ fput(file);
790+ return -EBUSY;
791+ }
792+ /* FIXME -- Why do this? I connected with the
793+ server. I know what these values are */
794+ /*
795+ error = get_server_info(dev, SOCKET_I(inode));
796+ if (error){
797+ fput(file);
798+ return error;
799+ }
800+ */
801+ error = gnbd_resend_requests(dev, SOCKET_I(inode));
802+ if (error){
803+ printk("quitting NBD_DO_IT\n");
804+ up(&dev->do_it_lock);
805+ fput(file);
806+ return error;
807+ }
808+ dev->file = file;
809+ dev->sock = SOCKET_I(inode);
810+ dev->receiver_pid = current->pid;
811+ blk_run_queue(dev->disk->queue);
812+ error = gnbd_do_it(dev);
813+ /* should I kill the socket first */
814+ up(&dev->do_it_lock);
815+ down(&dev->tx_lock);
816+ if (dev->sock) {
817+ printk(KERN_WARNING "%s: shutting down socket\n",
818+ dev->disk->disk_name);
819+ dev->sock->ops->shutdown(dev->sock,
820+ SEND_SHUTDOWN|RCV_SHUTDOWN);
821+ dev->sock = NULL;
822+ }
823+ up(&dev->tx_lock);
824+ file = dev->file;
825+ dev->file = NULL;
826+ if (file)
827+ fput(file);
828+ printk("exitting GNBD_DO_IT ioctl\n");
829+ return error;
830+ case GNBD_PING:
831+ /* FIXME -- should I allow pings if everything is compeletely
832+ * shutdown */
833+ spin_lock(&dev->queue_lock);
834+ /* only one outstanding ping at a time */
835+ if (list_empty(&ping_req.queuelist)){
836+ if (list_empty(&dev->queue_head))
837+ dev->last_received = jiffies;
838+ list_add(&ping_req.queuelist, &dev->queue_head);
839+ }
840+ spin_unlock(&dev->queue_lock);
841+ gnbd_send_req(dev, &ping_req); /* ignore the errors */
842+ return 0;
843+ case GNBD_PRINT_DEBUG:
844+ printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
845+ dev->disk->disk_name,
846+ dev->queue_head.next, dev->queue_head.prev,
847+ &dev->queue_head);
848+ return 0;
849+ case GNBD_GET_TIME:
850+ if (copy_to_user((void *)arg, &insmod_time, sizeof(uint64_t))){
851+ printk(KERN_WARNING "couldn't compy time argument to user\n");
852+ return -EFAULT;
853+ }
854+ return 0;
855+ }
856+ /* FIXME -- should I print something, is EINVAL the right error */
857+ return -EINVAL;
858+}
859+
860+static int gnbd_open(struct inode *inode, struct file *file)
861+{
862+ struct gnbd_device *dev = inode->i_bdev->bd_disk->private_data;
863+ spin_lock(&dev->open_lock);
864+ if (dev->receiver_pid == -1){
865+ spin_unlock(&dev->open_lock);
866+ return -ENXIO;
867+ }
868+ spin_unlock(&dev->open_lock);
869+ if ((file->f_mode & FMODE_WRITE) && (dev->flags & GNBD_READ_ONLY)){
870+ printk(KERN_INFO "cannot open read only gnbd device read/write");
871+ return -EROFS;
872+ }
873+
874+ dev->open_count++;
875+ dev->bdev = inode->i_bdev;
876+ return 0;
877+}
878+
879+/* FIXME -- I don't sync the device at close. This means that If you write
880+ * something, and close the device, and expect that then it is written,
881+ * you are wrong.... This might cause problems */
882+static int gnbd_release(struct inode *inode, struct file *file)
883+{
884+ struct gnbd_device *dev = inode->i_bdev->bd_disk->private_data;
885+
886+ dev->open_count--;
887+ if (dev->open_count == 0)
888+ dev->bdev = NULL;
889+ return 0;
890+}
891+
892+static struct file_operations _gnbd_ctl_fops =
893+{
894+ .ioctl = gnbd_ctl_ioctl,
895+ .owner = THIS_MODULE,
896+};
897+
898+static struct miscdevice _gnbd_misc =
899+{
900+ .minor = MISC_DYNAMIC_MINOR,
901+ .name = "gnbd_ctl",
902+ .devfs_name = "gnbd_ctl",
903+ .fops = &_gnbd_ctl_fops
904+};
905+
906+/* FIXME -- I should probably do more here */
907+int __init gnbd_ctl_init(void)
908+{
909+ int err;
910+
911+ err = misc_register(&_gnbd_misc);
912+ if (err) {
913+ printk("cannot register control device\n");
914+ return err;
915+ }
916+ return 0;
917+}
918+
919+void gnbd_ctl_cleanup(void)
920+{
921+ if (misc_deregister(&_gnbd_misc) < 0)
922+ printk("cannot deregister control device\n");
923+}
924+
925+static struct block_device_operations gnbd_fops =
926+{
927+ .open = gnbd_open,
928+ .release = gnbd_release,
929+ .owner = THIS_MODULE,
930+};
931+
932+/*
933+ * And here should be modules and kernel interface
934+ * (Just smiley confuses emacs :-)
935+ */
936+
937+static int __init gnbd_init(void)
938+{
939+ int err = -ENOMEM;
940+ struct timeval tv;
941+ int i;
942+
943+ if (sizeof(struct gnbd_request) != 28) {
944+ printk(KERN_CRIT "gnbd: sizeof gnbd_request needs to be 28 in order to work!\n" );
945+ return -EIO;
946+ }
947+ shutdown_req.flags = REQ_SPECIAL;
948+ gnbd_cmd(&shutdown_req) = GNBD_CMD_DISC;
949+ shutdown_req.sector = 0;
950+ shutdown_req.nr_sectors = 0;
951+
952+ ping_req.flags = REQ_SPECIAL;
953+ gnbd_cmd(&ping_req) = GNBD_CMD_PING;
954+ ping_req.sector = 0;
955+ ping_req.nr_sectors = 0;
956+
957+ for (i = 0; i < MAX_GNBD; i++) {
958+ struct gendisk *disk = alloc_disk(1);
959+ if (!disk)
960+ goto out;
961+ gnbd_dev[i].disk = disk;
962+ /*
963+ * The new linux 2.5 block layer implementation requires
964+ * every gendisk to have its very own request_queue struct.
965+ * These structs are big so we dynamically allocate them.
966+ */
967+ disk->queue = blk_init_queue(do_gnbd_request, &gnbd_lock);
968+ if (!disk->queue) {
969+ put_disk(disk);
970+ goto out;
971+ }
972+ }
973+ major_nr = register_blkdev(major_nr, "gnbd");
974+ if (major_nr < 0) {
975+ printk("gnbd: unable to get a major number\n");
976+ err = major_nr;
977+ goto out;
978+ }
979+
980+ printk(KERN_INFO "gnbd: registered device at major %d\n", major_nr);
981+ dprintk(DBG_INIT, "gnbd: debugflags=0x%x\n", debugflags);
982+
5cdbd17b 983+ devfs_mk_dir("gnbd_minor");
4bf12011 984+ err = class_register(&gnbd_class);
985+ if (err)
986+ goto out_unregister;
987+ for (i = 0; i < MAX_GNBD; i++) {
988+ struct gendisk *disk = gnbd_dev[i].disk;
989+ gnbd_dev[i].file = NULL;
990+ gnbd_dev[i].magic = GNBD_MAGIC;
991+ gnbd_dev[i].flags = 0;
992+ gnbd_dev[i].open_count = 0;
993+ gnbd_dev[i].receiver_pid = -1;
5cdbd17b 994+ gnbd_dev[i].server_name = NULL;
4bf12011 995+ gnbd_dev[i].server_port = 0;
996+ gnbd_dev[i].name[0] = '\0';
997+ gnbd_dev[i].bdev = NULL;
998+ spin_lock_init(&gnbd_dev[i].queue_lock);
999+ spin_lock_init(&gnbd_dev[i].open_lock);
1000+ INIT_LIST_HEAD(&gnbd_dev[i].queue_head);
1001+ init_MUTEX(&gnbd_dev[i].tx_lock);
1002+ init_MUTEX(&gnbd_dev[i].do_it_lock);
1003+ gnbd_dev[i].class_dev.class = &gnbd_class;
1004+ sprintf(gnbd_dev[i].class_dev.class_id, "gnbd%d", i);
1005+ err = class_device_register(&gnbd_dev[i].class_dev);
1006+ if (err){
1007+ printk("class_device_register failed with %d\n", err);
1008+ goto out_unregister_class;
1009+ }
1010+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1011+ &class_device_attr_pid))
1012+ goto out_remove_file;
1013+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1014+ &class_device_attr_server))
1015+ goto out_remove_file;
1016+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1017+ &class_device_attr_name))
1018+ goto out_remove_file;
1019+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1020+ &class_device_attr_sectors))
1021+ goto out_remove_file;
1022+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1023+ &class_device_attr_usage))
1024+ goto out_remove_file;
1025+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1026+ &class_device_attr_flags))
1027+ goto out_remove_file;
1028+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1029+ &class_device_attr_waittime))
1030+ goto out_remove_file;
1031+ if(class_device_create_file(&gnbd_dev[i].class_dev,
1032+ &class_device_attr_connected))
1033+ goto out_remove_file;
1034+ disk->major = major_nr;
1035+ disk->first_minor = i;
1036+ disk->fops = &gnbd_fops;
1037+ disk->private_data = &gnbd_dev[i];
1038+ sprintf(disk->disk_name, "gnbd%d", i);
5cdbd17b 1039+ sprintf(disk->devfs_name, "gnbd_minor/%d", i);
4bf12011 1040+ set_capacity(disk, 0);
1041+ add_disk(disk);
1042+ if(sysfs_create_link(&gnbd_dev[i].class_dev.kobj,
1043+ &gnbd_dev[i].disk->kobj, "block"))
1044+ goto out_remove_disk;
1045+
1046+ }
1047+
1048+ err = gnbd_ctl_init();
1049+ if (err)
1050+ goto out_unregister_class;
1051+
1052+ insmod_time = (uint64_t) tv.tv_sec * 1000000 + tv.tv_usec;
1053+
1054+ return 0;
1055+out_remove_disk:
1056+ del_gendisk(gnbd_dev[i].disk);
1057+out_remove_file:
1058+ class_device_unregister(&gnbd_dev[i].class_dev);
1059+out_unregister_class:
1060+ while(i--){
1061+ del_gendisk(gnbd_dev[i].disk);
1062+ class_device_unregister(&gnbd_dev[i].class_dev);
1063+ }
1064+ i = MAX_GNBD;
1065+ class_unregister(&gnbd_class);
1066+out_unregister:
1067+ unregister_blkdev(major_nr, "gnbd");
1068+out:
1069+ while (i--) {
1070+ blk_cleanup_queue(gnbd_dev[i].disk->queue);
1071+ put_disk(gnbd_dev[i].disk);
1072+ }
1073+ return err;
1074+}
1075+
1076+static void __exit gnbd_cleanup(void)
1077+{
1078+ int i;
1079+
1080+ gnbd_ctl_cleanup();
1081+ for (i = 0; i < MAX_GNBD; i++) {
1082+ struct gendisk *disk = gnbd_dev[i].disk;
1083+ if (disk) {
1084+ del_gendisk(disk);
1085+ blk_cleanup_queue(disk->queue);
1086+ put_disk(disk);
1087+ }
5cdbd17b
AM
1088+ if (gnbd_dev[i].server_name)
1089+ kfree(gnbd_dev[i].server_name);
4bf12011 1090+ }
1091+ class_unregister(&gnbd_class);
1092+ devfs_remove("gnbd");
1093+ unregister_blkdev(major_nr, "gnbd");
1094+ printk(KERN_INFO "gnbd: unregistered device at major %d\n", major_nr);
1095+}
1096+
1097+module_init(gnbd_init);
1098+module_exit(gnbd_cleanup);
1099+
1100+MODULE_DESCRIPTION("Network Block Device");
1101+MODULE_LICENSE("GPL");
1102+
1103+#ifndef NDEBUG
1104+MODULE_PARM(debugflags, "i");
1105+MODULE_PARM_DESC(debugflags, "flags for controlling debug output");
1106+#endif
1107diff -urN linux-orig/include/linux/gnbd.h linux-patched/include/linux/gnbd.h
1108--- linux-orig/include/linux/gnbd.h 1969-12-31 18:00:00.000000000 -0600
5cdbd17b 1109+++ linux-patched/include/linux/gnbd.h 2004-06-30 16:48:06.000000000 -0500
4bf12011 1110@@ -0,0 +1,103 @@
1111+/******************************************************************************
1112+*******************************************************************************
1113+**
1114+** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
1115+** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
1116+**
1117+** This copyrighted material is made available to anyone wishing to use,
1118+** modify, copy, or redistribute it subject to the terms and conditions
1119+** of the GNU General Public License v.2.
1120+**
1121+*******************************************************************************
1122+******************************************************************************/
1123+
1124+#ifndef LINUX_GNBD_H
1125+#define LINUX_GNBD_H
1126+
1127+#define GNBD_DO_IT _IO( 0xab, 0x20 )
1128+#define GNBD_CLEAR_QUE _IO( 0xab, 0x21 )
1129+#define GNBD_PRINT_DEBUG _IO( 0xab, 0x22 )
1130+#define GNBD_DISCONNECT _IO( 0xab, 0x23 )
1131+#define GNBD_PING _IO( 0xab, 0x24 )
1132+#define GNBD_GET_TIME _IO( 0xab, 0x25 )
1133+
1134+enum {
1135+ GNBD_CMD_READ = 0,
1136+ GNBD_CMD_WRITE = 1,
1137+ GNBD_CMD_DISC = 2,
1138+ GNBD_CMD_PING = 3
1139+};
1140+
1141+#define gnbd_cmd(req) ((req)->cmd[0])
1142+#define MAX_GNBD 128
1143+
1144+/* values for flags field */
1145+#define GNBD_READ_ONLY 0x0001
1146+
1147+/* userspace doesn't need the gnbd_device structure */
1148+#ifdef __KERNEL__
1149+
1150+struct gnbd_device {
1151+ unsigned short int flags;
1152+ struct socket * sock;
1153+ struct file * file; /* If == NULL, device is not ready, yet */
1154+ int magic;
1155+ spinlock_t queue_lock;
1156+ spinlock_t open_lock;
1157+ struct list_head queue_head;/* Requests are added here... */
1158+ struct semaphore tx_lock;
1159+ struct gendisk *disk;
1160+ pid_t receiver_pid;
1161+ struct semaphore do_it_lock;
1162+ int open_count;
1163+ struct class_device class_dev;
1164+ unsigned short int server_port;
5cdbd17b 1165+ char *server_name;
4bf12011 1166+ char name[32];
1167+ unsigned long last_received;
1168+ struct block_device *bdev;
1169+};
1170+
1171+#endif /* __KERNEL__ */
1172+
1173+/* These are sent over the network in the request/reply magic fields */
1174+
1175+#define GNBD_REQUEST_MAGIC 0x37a07e00
1176+#define GNBD_REPLY_MAGIC 0x41f09370
1177+#define GNBD_KEEP_ALIVE_MAGIC 0x5B46D8C2
1178+/* Do *not* use magics: 0x12560953 0x96744668. */
1179+
1180+/*
1181+ * This is the packet used for communication between client and
1182+ * server. All data are in network byte order.
1183+ */
1184+struct gnbd_request {
1185+ uint32_t magic;
1186+ uint32_t type; /* == READ || == WRITE why so long */
1187+ char handle[8]; /* why is this a char array instead of a u64 */
1188+ uint64_t from;
1189+ uint32_t len;
1190+}
1191+#ifdef __GNUC__
1192+ __attribute__ ((packed))
1193+#endif /* __GNUC__ */
1194+;
1195+
1196+/*
1197+ * This is the reply packet that gnbd-server sends back to the client after
1198+ * it has completed an I/O request (or an error occurs).
1199+ */
1200+#define SIZE_OF_REPLY 16
1201+struct gnbd_reply {
1202+ uint32_t magic;
1203+ uint32_t error; /* 0 = ok, else error */
1204+ char handle[8]; /* handle you got from request */
1205+};
1206+
1207+struct do_it_req_s {
1208+ unsigned int minor;
1209+ int sock_fd;
1210+};
1211+typedef struct do_it_req_s do_it_req_t;
1212+
1213+#endif /* LINUX_GNBD_H */
This page took 0.751321 seconds and 4 git commands to generate.