2 * Copyright (C) 2012 GRNET S.A.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/init.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.h>
29 #include <linux/slab.h>
31 #include <linux/errno.h>
32 #include <linux/timer.h>
33 #include <linux/types.h>
34 #include <linux/vmalloc.h>
35 #include <linux/genhd.h>
36 #include <linux/blkdev.h>
37 #include <linux/bio.h>
38 #include <linux/device.h>
39 #include <linux/completion.h>
40 #include <linux/wait.h>
41 #include <sys/kernel/segdev.h>
43 #include <xseg/protocol.h>
45 #define XSEGBD_MINORS 1
46 /* define max request size to be used in xsegbd */
47 #define XSEGBD_MAX_REQUEST_SIZE 4194304U
49 MODULE_DESCRIPTION("xsegbd");
50 MODULE_AUTHOR("XSEG");
51 MODULE_LICENSE("GPL");
53 static long sector_size = 0;
54 static long blksize = 512;
56 static int max_dev = 200;
57 static long start_portno = 0;
58 static long end_portno = 199;
59 static char name[XSEGBD_SEGMENT_NAMELEN] = "xsegbd";
60 static char spec[256] = "segdev:xsegbd:512:1024:12";
62 module_param(sector_size, long, 0644);
63 module_param(blksize, long, 0644);
64 module_param(start_portno, long, 0644);
65 module_param(end_portno, long, 0644);
66 module_param(major, int, 0644);
67 module_param_string(name, name, sizeof(name), 0644);
68 module_param_string(spec, spec, sizeof(spec), 0644);
70 static struct xsegbd xsegbd;
71 static struct xsegbd_device **xsegbd_devices; /* indexed by portno */
72 static DEFINE_MUTEX(xsegbd_mutex);
73 static DEFINE_SPINLOCK(xsegbd_devices_lock);
76 struct xsegbd_device *__xsegbd_get_dev(unsigned long id)
78 struct xsegbd_device *xsegbd_dev = NULL;
80 spin_lock(&xsegbd_devices_lock);
81 xsegbd_dev = xsegbd_devices[id];
82 spin_unlock(&xsegbd_devices_lock);
87 static long src_portno_to_id(xport src_portno)
89 return (src_portno - start_portno);
92 /* ************************* */
93 /* ***** sysfs helpers ***** */
94 /* ************************* */
96 static struct xsegbd_device *dev_to_xsegbd(struct device *dev)
98 return container_of(dev, struct xsegbd_device, dev);
101 static struct device *xsegbd_get_dev(struct xsegbd_device *xsegbd_dev)
104 return get_device(&xsegbd_dev->dev);
107 static void xsegbd_put_dev(struct xsegbd_device *xsegbd_dev)
109 put_device(&xsegbd_dev->dev);
112 /* ************************* */
113 /* ** XSEG Initialization ** */
114 /* ************************* */
116 static void xseg_callback(uint32_t portno);
118 int xsegbd_xseg_init(void)
123 strncpy(xsegbd.name, name, XSEGBD_SEGMENT_NAMELEN);
125 r = xseg_initialize();
127 XSEGLOG("cannot initialize 'segdev' peer");
131 r = xseg_parse_spec(spec, &xsegbd.config);
135 if (strncmp(xsegbd.config.type, "segdev", 16))
136 XSEGLOG("WARNING: unexpected segment type '%s' vs 'segdev'",
139 /* leave it here for now */
140 XSEGLOG("joining segment");
141 xsegbd.xseg = xseg_join( xsegbd.config.type,
146 XSEGLOG("cannot find segment");
157 int xsegbd_xseg_quit(void)
159 struct segdev *segdev;
161 /* make sure to unmap the segment first */
162 xseg_leave(xsegbd.xseg);
168 /* ***************************** */
169 /* ** Block Device Operations ** */
170 /* ***************************** */
172 static int xsegbd_open(struct block_device *bdev, fmode_t mode)
175 struct gendisk *disk = bdev->bd_disk;
176 struct xsegbd_device *xsegbd_dev;
177 id = (long)disk->private_data;
179 //struct xsegbd_device *xsegbd_dev = disk->private_data;
182 mutex_lock_nested(&xsegbd_mutex, SINGLE_DEPTH_NESTING);
184 spin_lock(&xsegbd_devices_lock);
185 xsegbd_dev = xsegbd_devices[id];
186 spin_unlock(&xsegbd_devices_lock);
192 xsegbd_get_dev(xsegbd_dev);
193 xsegbd_dev->user_count++;
195 mutex_unlock(&xsegbd_mutex);
199 static int xsegbd_release(struct gendisk *gd, fmode_t mode)
202 struct xsegbd_device *xsegbd_dev;
203 id = (long)gd->private_data;
205 mutex_lock_nested(&xsegbd_mutex, SINGLE_DEPTH_NESTING);
207 spin_lock(&xsegbd_devices_lock);
208 xsegbd_dev = xsegbd_devices[id];
209 spin_unlock(&xsegbd_devices_lock);
214 if (!(xsegbd_dev->user_count > 0)){
215 XSEGLOG("User count for xsebd %d not > 0", xsegbd_dev->id);
219 xsegbd_dev->user_count--;
220 xsegbd_put_dev(xsegbd_dev);
222 mutex_unlock(&xsegbd_mutex);
226 static int xsegbd_ioctl(struct block_device *bdev, fmode_t mode,
227 unsigned int cmd, unsigned long arg)
232 static const struct block_device_operations xsegbd_ops = {
233 .owner = THIS_MODULE,
235 .release = xsegbd_release,
236 .ioctl = xsegbd_ioctl
240 /* *************************** */
241 /* ** Device Initialization ** */
242 /* *************************** */
244 static void xseg_request_fn(struct request_queue *rq);
245 static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev);
246 static int xsegbd_mapclose(struct xsegbd_device *xsegbd_dev);
248 static int xsegbd_dev_init(struct xsegbd_device *xsegbd_dev)
251 struct gendisk *disk;
252 unsigned int max_request_size_bytes;
254 spin_lock_init(&xsegbd_dev->rqlock);
256 xsegbd_dev->xsegbd = &xsegbd;
258 /* allocates and initializes queue */
259 xsegbd_dev->blk_queue = blk_init_queue(xseg_request_fn, &xsegbd_dev->rqlock);
260 if (!xsegbd_dev->blk_queue)
263 xsegbd_dev->blk_queue->queuedata = xsegbd_dev;
265 blk_queue_flush(xsegbd_dev->blk_queue, REQ_FLUSH | REQ_FUA);
266 blk_queue_logical_block_size(xsegbd_dev->blk_queue, 512);
267 blk_queue_physical_block_size(xsegbd_dev->blk_queue, blksize);
268 blk_queue_bounce_limit(xsegbd_dev->blk_queue, BLK_BOUNCE_ANY);
271 max_request_size_bytes = XSEGBD_MAX_REQUEST_SIZE;
272 blk_queue_max_hw_sectors(xsegbd_dev->blk_queue, max_request_size_bytes >> 9);
273 // blk_queue_max_sectors(xsegbd_dev->blk_queue, max_request_size_bytes >> 10);
274 blk_queue_max_segments(xsegbd_dev->blk_queue, 1024);
275 blk_queue_max_segment_size(xsegbd_dev->blk_queue, max_request_size_bytes);
276 blk_queue_io_min(xsegbd_dev->blk_queue, max_request_size_bytes);
277 blk_queue_io_opt(xsegbd_dev->blk_queue, max_request_size_bytes);
279 queue_flag_set_unlocked(QUEUE_FLAG_NONROT, xsegbd_dev->blk_queue);
281 /* vkoukis says we don't need partitions */
282 xsegbd_dev->gd = disk = alloc_disk(XSEGBD_MINORS);
286 disk->major = xsegbd_dev->major;
287 disk->first_minor = xsegbd_dev->id * XSEGBD_MINORS;
288 disk->fops = &xsegbd_ops;
289 disk->queue = xsegbd_dev->blk_queue;
290 // disk->private_data = xsegbd_dev;
291 disk->private_data = (void *)xsegbd_dev->id;
292 disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
293 snprintf(disk->disk_name, 32, "xsegbd%ld", xsegbd_dev->id);
297 /* allow a non-zero sector_size parameter to override the disk size */
299 xsegbd_dev->sectors = sector_size;
301 ret = xsegbd_get_size(xsegbd_dev);
306 set_capacity(disk, xsegbd_dev->sectors);
307 XSEGLOG("xsegbd active...");
308 add_disk(disk); /* immediately activates the device */
311 /* on error, everything is cleaned up in xsegbd_dev_release */
315 static void xsegbd_dev_release(struct device *dev)
317 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
320 /* cleanup gendisk and blk_queue the right way */
321 if (xsegbd_dev->gd) {
322 if (xsegbd_dev->gd->flags & GENHD_FL_UP)
323 del_gendisk(xsegbd_dev->gd);
325 xsegbd_mapclose(xsegbd_dev);
328 spin_lock(&xsegbd_devices_lock);
329 BUG_ON(xsegbd_devices[xsegbd_dev->id] != xsegbd_dev);
330 xsegbd_devices[xsegbd_dev->id] = NULL;
331 spin_unlock(&xsegbd_devices_lock);
333 XSEGLOG("releasing id: %d", xsegbd_dev->id);
334 // xseg_cancel_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
335 xseg_quit_local_signal(xsegbd_dev->xseg, xsegbd_dev->src_portno);
337 if (xsegbd_dev->blk_queue)
338 blk_cleanup_queue(xsegbd_dev->blk_queue);
340 put_disk(xsegbd_dev->gd);
342 // if (xseg_free_requests(xsegbd_dev->xseg,
343 // xsegbd_dev->src_portno, xsegbd_dev->nr_requests) < 0)
344 // XSEGLOG("Error trying to free requests!\n");
346 if (xsegbd_dev->xseg){
347 xseg_leave(xsegbd_dev->xseg);
348 xsegbd_dev->xseg = NULL;
351 if (xsegbd_dev->blk_req_pending){
352 kfree(xsegbd_dev->blk_req_pending);
353 xsegbd_dev->blk_req_pending = NULL;
355 xq_free(&xsegbd_dev->blk_queue_pending);
357 module_put(THIS_MODULE);
360 /* ******************* */
361 /* ** Critical Path ** */
362 /* ******************* */
364 static void blk_to_xseg(struct xseg *xseg, struct xseg_request *xreq,
365 struct request *blkreq)
367 struct bio_vec *bvec;
368 struct req_iterator iter;
370 char *data = xseg_get_data(xseg, xreq);
371 rq_for_each_segment(bvec, blkreq, iter) {
372 char *bdata = kmap_atomic(bvec->bv_page) + bvec->bv_offset;
373 memcpy(data + off, bdata, bvec->bv_len);
375 kunmap_atomic(bdata);
379 static void xseg_to_blk(struct xseg *xseg, struct xseg_request *xreq,
380 struct request *blkreq)
382 struct bio_vec *bvec;
383 struct req_iterator iter;
385 char *data = xseg_get_data(xseg, xreq);
386 rq_for_each_segment(bvec, blkreq, iter) {
387 char *bdata = kmap_atomic(bvec->bv_page) + bvec->bv_offset;
388 memcpy(bdata, data + off, bvec->bv_len);
390 kunmap_atomic(bdata);
394 static void xseg_request_fn(struct request_queue *rq)
396 struct xseg_request *xreq;
397 struct xsegbd_device *xsegbd_dev = rq->queuedata;
398 struct request *blkreq;
399 struct xsegbd_pending *pending;
407 spin_unlock_irq(&xsegbd_dev->rqlock);
409 if (current_thread_info()->preempt_count || irqs_disabled()){
410 XSEGLOG("Current thread preempt_count: %d, irqs_disabled(): %lu ",
411 current_thread_info()->preempt_count, irqs_disabled());
413 //XSEGLOG("Priority: %d", current_thread_info()->task->prio);
414 //XSEGLOG("Static priority: %d", current_thread_info()->task->static_prio);
415 //XSEGLOG("Normal priority: %d", current_thread_info()->task->normal_prio);
416 //XSEGLOG("Rt_priority: %u", current_thread_info()->task->rt_priority);
417 blkreq_idx = Noneidx;
418 xreq = xseg_get_request(xsegbd_dev->xseg, xsegbd_dev->src_portno,
419 xsegbd_dev->dst_portno, X_ALLOC);
423 blkreq_idx = xq_pop_head(&xsegbd_dev->blk_queue_pending,
424 xsegbd_dev->src_portno);
425 if (blkreq_idx == Noneidx)
428 if (blkreq_idx >= xsegbd_dev->nr_requests) {
429 XSEGLOG("blkreq_idx >= xsegbd_dev->nr_requests");
435 spin_lock_irqsave(&xsegbd_dev->rqlock, flags);
436 blkreq = blk_fetch_request(rq);
438 spin_unlock_irqrestore(&xsegbd_dev->rqlock, flags);
442 if (blkreq->cmd_type != REQ_TYPE_FS) {
443 //FIXME we lose xreq here
444 XSEGLOG("non-fs cmd_type: %u. *shrug*", blkreq->cmd_type);
445 __blk_end_request_all(blkreq, 0);
446 spin_unlock_irqrestore(&xsegbd_dev->rqlock, flags);
449 spin_unlock_irqrestore(&xsegbd_dev->rqlock, flags);
450 if (current_thread_info()->preempt_count || irqs_disabled()){
451 XSEGLOG("Current thread preempt_count: %d, irqs_disabled(): %lu ",
452 current_thread_info()->preempt_count, irqs_disabled());
455 datalen = blk_rq_bytes(blkreq);
456 r = xseg_prep_request(xsegbd_dev->xseg, xreq,
457 xsegbd_dev->targetlen, datalen);
459 XSEGLOG("couldn't prep request");
460 blk_end_request_err(blkreq, r);
465 if (xreq->bufferlen - xsegbd_dev->targetlen < datalen){
466 XSEGLOG("malformed req buffers");
467 blk_end_request_err(blkreq, r);
472 target = xseg_get_target(xsegbd_dev->xseg, xreq);
473 strncpy(target, xsegbd_dev->target, xsegbd_dev->targetlen);
475 pending = &xsegbd_dev->blk_req_pending[blkreq_idx];
476 pending->dev = xsegbd_dev;
477 pending->request = blkreq;
478 pending->comp = NULL;
480 xreq->size = datalen;
481 xreq->offset = blk_rq_pos(blkreq) << 9;
482 xreq->priv = (uint64_t) blkreq_idx;
485 if (xreq->offset >= (sector_size << 9))
486 XSEGLOG("sector offset: %lu > %lu, flush:%u, fua:%u",
487 blk_rq_pos(blkreq), sector_size,
488 blkreq->cmd_flags & REQ_FLUSH,
489 blkreq->cmd_flags & REQ_FUA);
492 if (blkreq->cmd_flags & REQ_FLUSH)
493 xreq->flags |= XF_FLUSH;
495 if (blkreq->cmd_flags & REQ_FUA)
496 xreq->flags |= XF_FUA;
498 if (rq_data_dir(blkreq)) {
499 blk_to_xseg(xsegbd_dev->xseg, xreq, blkreq);
506 // XSEGLOG("%s : %lu (%lu)", xsegbd_dev->target, xreq->offset, xreq->datalen);
508 p = xseg_submit(xsegbd_dev->xseg, xreq,
509 xsegbd_dev->src_portno, X_ALLOC);
511 XSEGLOG("coundn't submit req");
513 blk_end_request_err(blkreq, r);
516 WARN_ON(xseg_signal(xsegbd_dev->xsegbd->xseg, p) < 0);
519 WARN_ON(xseg_put_request(xsegbd_dev->xsegbd->xseg, xreq,
520 xsegbd_dev->src_portno) == -1);
521 if (blkreq_idx != Noneidx)
522 WARN_ON(xq_append_head(&xsegbd_dev->blk_queue_pending,
523 blkreq_idx, xsegbd_dev->src_portno) == Noneidx);
524 spin_lock_irq(&xsegbd_dev->rqlock);
527 int update_dev_sectors_from_request( struct xsegbd_device *xsegbd_dev,
528 struct xseg_request *xreq )
531 struct xseg_reply_info *xreply;
533 XSEGLOG("Invalid xreq");
537 if (xreq->state & XS_FAILED)
540 if (!(xreq->state & XS_SERVED))
543 data = xseg_get_data(xsegbd_dev->xseg, xreq);
545 XSEGLOG("Invalid req data");
549 XSEGLOG("Invalid xsegbd_dev");
552 xreply = (struct xseg_reply_info *)data;
553 xsegbd_dev->sectors = xreply->size / 512ULL;
557 static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev)
559 struct xseg_request *xreq;
562 struct xsegbd_pending *pending;
563 struct completion comp;
567 xreq = xseg_get_request(xsegbd_dev->xseg, xsegbd_dev->src_portno,
568 xsegbd_dev->dst_portno, X_ALLOC);
572 WARN_ON(xseg_prep_request(xsegbd_dev->xseg, xreq, xsegbd_dev->targetlen,
573 sizeof(struct xseg_reply_info)));
575 init_completion(&comp);
576 blkreq_idx = xq_pop_head(&xsegbd_dev->blk_queue_pending, 1);
577 if (blkreq_idx == Noneidx)
580 pending = &xsegbd_dev->blk_req_pending[blkreq_idx];
581 pending->dev = xsegbd_dev;
582 pending->request = NULL;
583 pending->comp = ∁
586 xreq->priv = (uint64_t) blkreq_idx;
588 target = xseg_get_target(xsegbd_dev->xseg, xreq);
589 strncpy(target, xsegbd_dev->target, xsegbd_dev->targetlen);
590 xreq->size = xreq->datalen;
594 xseg_prepare_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
595 p = xseg_submit(xsegbd_dev->xseg, xreq,
596 xsegbd_dev->src_portno, X_ALLOC);
598 XSEGLOG("couldn't submit request");
602 WARN_ON(xseg_signal(xsegbd_dev->xseg, p) < 0);
603 XSEGLOG("Before wait for completion, comp %lx [%llu]", (unsigned long) pending->comp, (unsigned long long) blkreq_idx);
604 wait_for_completion_interruptible(&comp);
605 XSEGLOG("Woken up after wait_for_completion_interruptible(), comp: %lx [%llu]", (unsigned long) pending->comp, (unsigned long long) blkreq_idx);
606 ret = update_dev_sectors_from_request(xsegbd_dev, xreq);
607 XSEGLOG("get_size: sectors = %ld\n", (long)xsegbd_dev->sectors);
611 pending->comp = NULL;
612 xq_append_head(&xsegbd_dev->blk_queue_pending, blkreq_idx, 1);
614 WARN_ON(xseg_put_request(xsegbd_dev->xseg, xreq, xsegbd_dev->src_portno) == -1);
619 static int xsegbd_mapclose(struct xsegbd_device *xsegbd_dev)
621 struct xseg_request *xreq;
624 struct xsegbd_pending *pending;
625 struct completion comp;
629 xreq = xseg_get_request(xsegbd_dev->xseg, xsegbd_dev->src_portno,
630 xsegbd_dev->dst_portno, X_ALLOC);
634 WARN_ON(xseg_prep_request(xsegbd_dev->xseg, xreq, xsegbd_dev->targetlen, 0));
636 init_completion(&comp);
637 blkreq_idx = xq_pop_head(&xsegbd_dev->blk_queue_pending, 1);
638 if (blkreq_idx == Noneidx)
641 pending = &xsegbd_dev->blk_req_pending[blkreq_idx];
642 pending->dev = xsegbd_dev;
643 pending->request = NULL;
644 pending->comp = ∁
647 xreq->priv = (uint64_t) blkreq_idx;
649 target = xseg_get_target(xsegbd_dev->xseg, xreq);
650 strncpy(target, xsegbd_dev->target, xsegbd_dev->targetlen);
651 xreq->size = xreq->datalen;
655 xseg_prepare_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
656 p = xseg_submit(xsegbd_dev->xseg, xreq,
657 xsegbd_dev->src_portno, X_ALLOC);
659 XSEGLOG("couldn't submit request");
663 WARN_ON(xseg_signal(xsegbd_dev->xseg, p) < 0);
664 wait_for_completion_interruptible(&comp);
666 if (xreq->state & XS_FAILED)
667 XSEGLOG("Couldn't close disk on mapper");
671 pending->comp = NULL;
672 xq_append_head(&xsegbd_dev->blk_queue_pending, blkreq_idx, 1);
674 WARN_ON(xseg_put_request(xsegbd_dev->xseg, xreq, xsegbd_dev->src_portno) == -1);
679 static void xseg_callback(xport portno)
681 struct xsegbd_device *xsegbd_dev;
682 struct xseg_request *xreq;
683 struct request *blkreq;
684 struct xsegbd_pending *pending;
686 xqindex blkreq_idx, ridx;
688 // mayby this should be src_portno_to_id(portno)
689 xsegbd_dev = __xsegbd_get_dev(portno);
691 XSEGLOG("portno: %u has no xsegbd device assigned", portno);
697 xseg_prepare_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
698 xreq = xseg_receive(xsegbd_dev->xseg, portno, 0);
702 // xseg_cancel_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
704 blkreq_idx = (xqindex) xreq->priv;
705 if (blkreq_idx >= xsegbd_dev->nr_requests) {
707 //FIXME maybe put request?
711 pending = &xsegbd_dev->blk_req_pending[blkreq_idx];
713 /* someone is blocking on this request
714 and will handle it when we wake them up. */
715 complete(pending->comp);
716 /* the request is blocker's responsibility so
717 we will not put_request(); */
721 /* this is now treated as a block I/O request to end */
722 blkreq = pending->request;
723 pending->request = NULL;
724 if (xsegbd_dev != pending->dev) {
725 //FIXME maybe put request?
726 XSEGLOG("xsegbd_dev != pending->dev");
732 //FIXME maybe put request?
733 XSEGLOG("blkreq does not exist");
739 if (!(xreq->state & XS_SERVED))
742 if (xreq->serviced != blk_rq_bytes(blkreq))
746 if (!rq_data_dir(blkreq)){
747 xseg_to_blk(xsegbd_dev->xseg, xreq, blkreq);
750 blk_end_request_all(blkreq, err);
752 ridx = xq_append_head(&xsegbd_dev->blk_queue_pending,
753 blkreq_idx, xsegbd_dev->src_portno);
754 if (ridx == Noneidx) {
755 XSEGLOG("couldnt append blkreq_idx");
759 if (xseg_put_request(xsegbd_dev->xseg, xreq,
760 xsegbd_dev->src_portno) < 0){
761 XSEGLOG("couldn't put req");
766 spin_lock_irqsave(&xsegbd_dev->rqlock, flags);
767 xseg_request_fn(xsegbd_dev->blk_queue);
768 spin_unlock_irqrestore(&xsegbd_dev->rqlock, flags);
773 /* sysfs interface */
775 static struct bus_type xsegbd_bus_type = {
779 static ssize_t xsegbd_size_show(struct device *dev,
780 struct device_attribute *attr, char *buf)
782 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
784 return sprintf(buf, "%llu\n", (unsigned long long) xsegbd_dev->sectors * 512ULL);
787 static ssize_t xsegbd_major_show(struct device *dev,
788 struct device_attribute *attr, char *buf)
790 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
792 return sprintf(buf, "%d\n", xsegbd_dev->major);
795 static ssize_t xsegbd_srcport_show(struct device *dev,
796 struct device_attribute *attr, char *buf)
798 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
800 return sprintf(buf, "%u\n", (unsigned) xsegbd_dev->src_portno);
803 static ssize_t xsegbd_dstport_show(struct device *dev,
804 struct device_attribute *attr, char *buf)
806 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
808 return sprintf(buf, "%u\n", (unsigned) xsegbd_dev->dst_portno);
811 static ssize_t xsegbd_id_show(struct device *dev,
812 struct device_attribute *attr, char *buf)
814 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
816 return sprintf(buf, "%u\n", (unsigned) xsegbd_dev->id);
819 static ssize_t xsegbd_reqs_show(struct device *dev,
820 struct device_attribute *attr, char *buf)
822 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
824 return sprintf(buf, "%u\n", (unsigned) xsegbd_dev->nr_requests);
827 static ssize_t xsegbd_target_show(struct device *dev,
828 struct device_attribute *attr, char *buf)
830 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
832 return sprintf(buf, "%s\n", xsegbd_dev->target);
835 static ssize_t xsegbd_image_refresh(struct device *dev,
836 struct device_attribute *attr,
840 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
843 mutex_lock_nested(&xsegbd_mutex, SINGLE_DEPTH_NESTING);
845 rc = xsegbd_get_size(xsegbd_dev);
851 set_capacity(xsegbd_dev->gd, xsegbd_dev->sectors);
854 mutex_unlock(&xsegbd_mutex);
859 //maybe try callback, first and then do a more invasive cleanup
860 static ssize_t xsegbd_cleanup(struct device *dev,
861 struct device_attribute *attr,
865 struct xsegbd_device *xsegbd_dev = dev_to_xsegbd(dev);
867 struct request *blkreq = NULL;
868 struct xsegbd_pending *pending = NULL;
869 struct completion *comp = NULL;
871 mutex_lock_nested(&xsegbd_mutex, SINGLE_DEPTH_NESTING);
872 xlock_acquire(&xsegbd_dev->blk_queue_pending.lock,
873 xsegbd_dev->src_portno);
874 for (i = 0; i < xsegbd_dev->nr_requests; i++) {
875 if (!__xq_check(&xsegbd_dev->blk_queue_pending, i)) {
876 pending = &xsegbd_dev->blk_req_pending[i];
877 blkreq = pending->request;
878 pending->request = NULL;
879 comp = pending->comp;
880 pending->comp = NULL;
882 XSEGLOG("Cleaning up blkreq %lx [%d]", (unsigned long) blkreq, i);
883 blk_end_request_all(blkreq, -EIO);
886 XSEGLOG("Cleaning up comp %lx [%d]", (unsigned long) comp, i);
889 __xq_append_tail(&xsegbd_dev->blk_queue_pending, i);
892 xlock_release(&xsegbd_dev->blk_queue_pending.lock);
894 mutex_unlock(&xsegbd_mutex);
898 static DEVICE_ATTR(size, S_IRUGO, xsegbd_size_show, NULL);
899 static DEVICE_ATTR(major, S_IRUGO, xsegbd_major_show, NULL);
900 static DEVICE_ATTR(srcport, S_IRUGO, xsegbd_srcport_show, NULL);
901 static DEVICE_ATTR(dstport, S_IRUGO, xsegbd_dstport_show, NULL);
902 static DEVICE_ATTR(id , S_IRUGO, xsegbd_id_show, NULL);
903 static DEVICE_ATTR(reqs , S_IRUGO, xsegbd_reqs_show, NULL);
904 static DEVICE_ATTR(target, S_IRUGO, xsegbd_target_show, NULL);
905 static DEVICE_ATTR(refresh , S_IWUSR, NULL, xsegbd_image_refresh);
906 static DEVICE_ATTR(cleanup , S_IWUSR, NULL, xsegbd_cleanup);
908 static struct attribute *xsegbd_attrs[] = {
910 &dev_attr_major.attr,
911 &dev_attr_srcport.attr,
912 &dev_attr_dstport.attr,
915 &dev_attr_target.attr,
916 &dev_attr_refresh.attr,
917 &dev_attr_cleanup.attr,
921 static struct attribute_group xsegbd_attr_group = {
922 .attrs = xsegbd_attrs,
925 static const struct attribute_group *xsegbd_attr_groups[] = {
930 static void xsegbd_sysfs_dev_release(struct device *dev)
934 static struct device_type xsegbd_device_type = {
936 .groups = xsegbd_attr_groups,
937 .release = xsegbd_sysfs_dev_release,
940 static void xsegbd_root_dev_release(struct device *dev)
944 static struct device xsegbd_root_dev = {
945 .init_name = "xsegbd",
946 .release = xsegbd_root_dev_release,
949 static int xsegbd_bus_add_dev(struct xsegbd_device *xsegbd_dev)
954 mutex_lock_nested(&xsegbd_mutex, SINGLE_DEPTH_NESTING);
955 dev = &xsegbd_dev->dev;
957 dev->bus = &xsegbd_bus_type;
958 dev->type = &xsegbd_device_type;
959 dev->parent = &xsegbd_root_dev;
960 dev->release = xsegbd_dev_release;
961 dev_set_name(dev, "%ld", xsegbd_dev->id);
963 ret = device_register(dev);
965 mutex_unlock(&xsegbd_mutex);
969 static void xsegbd_bus_del_dev(struct xsegbd_device *xsegbd_dev)
971 device_unregister(&xsegbd_dev->dev);
974 static ssize_t xsegbd_add(struct bus_type *bus, const char *buf, size_t count)
976 struct xsegbd_device *xsegbd_dev;
977 struct xseg_port *port;
978 ssize_t ret = -ENOMEM;
980 if (!try_module_get(THIS_MODULE))
983 xsegbd_dev = kzalloc(sizeof(*xsegbd_dev), GFP_KERNEL);
987 spin_lock_init(&xsegbd_dev->rqlock);
988 INIT_LIST_HEAD(&xsegbd_dev->node);
989 xsegbd_dev->user_count = 0;
992 if (sscanf(buf, "%" __stringify(XSEGBD_TARGET_NAMELEN) "s "
993 "%d:%d:%d", xsegbd_dev->target, &xsegbd_dev->src_portno,
994 &xsegbd_dev->dst_portno, &xsegbd_dev->nr_requests) < 3) {
998 xsegbd_dev->targetlen = strlen(xsegbd_dev->target);
1000 if (xsegbd_dev->src_portno < start_portno || xsegbd_dev->src_portno > end_portno){
1001 XSEGLOG("Invadid portno");
1005 xsegbd_dev->id = src_portno_to_id(xsegbd_dev->src_portno);
1007 spin_lock(&xsegbd_devices_lock);
1008 if (xsegbd_devices[xsegbd_dev->id] != NULL) {
1012 xsegbd_devices[xsegbd_dev->id] = xsegbd_dev;
1013 spin_unlock(&xsegbd_devices_lock);
1015 xsegbd_dev->major = major;
1017 ret = xsegbd_bus_add_dev(xsegbd_dev);
1021 if (!xq_alloc_seq(&xsegbd_dev->blk_queue_pending,
1022 xsegbd_dev->nr_requests,
1023 xsegbd_dev->nr_requests))
1026 xsegbd_dev->blk_req_pending = kzalloc(
1027 xsegbd_dev->nr_requests *sizeof(struct xsegbd_pending),
1029 if (!xsegbd_dev->blk_req_pending)
1033 XSEGLOG("joining segment");
1034 //FIXME use xsebd module config for now
1035 xsegbd_dev->xseg = xseg_join( xsegbd.config.type,
1039 if (!xsegbd_dev->xseg)
1042 XSEGLOG("%s binding to source port %u (destination %u)", xsegbd_dev->target,
1043 xsegbd_dev->src_portno, xsegbd_dev->dst_portno);
1044 port = xseg_bind_port(xsegbd_dev->xseg, xsegbd_dev->src_portno, NULL);
1046 XSEGLOG("cannot bind to port");
1052 if (xsegbd_dev->src_portno != xseg_portno(xsegbd_dev->xseg, port)) {
1053 XSEGLOG("portno != xsegbd_dev->src_portno");
1058 xseg_init_local_signal(xsegbd_dev->xseg, xsegbd_dev->src_portno);
1061 /* make sure we don't get any requests until we're ready to handle them */
1062 xseg_cancel_wait(xsegbd_dev->xseg, xseg_portno(xsegbd_dev->xseg, port));
1064 ret = xsegbd_dev_init(xsegbd_dev);
1068 xseg_prepare_wait(xsegbd_dev->xseg, xseg_portno(xsegbd_dev->xseg, port));
1072 xsegbd_bus_del_dev(xsegbd_dev);
1076 spin_lock(&xsegbd_devices_lock);
1077 xsegbd_devices[xsegbd_dev->id] = NULL;
1080 spin_unlock(&xsegbd_devices_lock);
1086 module_put(THIS_MODULE);
1090 static ssize_t xsegbd_remove(struct bus_type *bus, const char *buf, size_t count)
1092 struct xsegbd_device *xsegbd_dev = NULL;
1094 unsigned long ul_id;
1096 ret = strict_strtoul(buf, 10, &ul_id);
1104 mutex_lock_nested(&xsegbd_mutex, SINGLE_DEPTH_NESTING);
1107 xsegbd_dev = __xsegbd_get_dev(id);
1112 if (xsegbd_dev->user_count > 0){
1116 xsegbd_bus_del_dev(xsegbd_dev);
1119 mutex_unlock(&xsegbd_mutex);
1123 static struct bus_attribute xsegbd_bus_attrs[] = {
1124 __ATTR(add, S_IWUSR, NULL, xsegbd_add),
1125 __ATTR(remove, S_IWUSR, NULL, xsegbd_remove),
1129 static int xsegbd_sysfs_init(void)
1133 ret = device_register(&xsegbd_root_dev);
1137 xsegbd_bus_type.bus_attrs = xsegbd_bus_attrs;
1138 ret = bus_register(&xsegbd_bus_type);
1140 device_unregister(&xsegbd_root_dev);
1145 static void xsegbd_sysfs_cleanup(void)
1147 bus_unregister(&xsegbd_bus_type);
1148 device_unregister(&xsegbd_root_dev);
1151 /* *************************** */
1152 /* ** Module Initialization ** */
1153 /* *************************** */
1155 static int __init xsegbd_init(void)
1158 max_dev = end_portno - start_portno;
1160 XSEGLOG("invalid port numbers");
1164 xsegbd_devices = kzalloc(max_dev * sizeof(struct xsegbd_devices *), GFP_KERNEL);
1165 if (!xsegbd_devices)
1168 spin_lock_init(&xsegbd_devices_lock);
1170 XSEGLOG("registering block device major %d", major);
1171 ret = register_blkdev(major, XSEGBD_NAME);
1173 XSEGLOG("cannot register block device!");
1178 XSEGLOG("registered block device major %d", major);
1181 ret = xsegbd_xseg_init();
1183 goto out_unregister;
1185 ret = xsegbd_sysfs_init();
1189 XSEGLOG("initialization complete");
1198 unregister_blkdev(major, XSEGBD_NAME);
1201 kfree(xsegbd_devices);
1206 static void __exit xsegbd_exit(void)
1208 xsegbd_sysfs_cleanup();
1210 unregister_blkdev(major, XSEGBD_NAME);
1213 module_init(xsegbd_init);
1214 module_exit(xsegbd_exit);