jsflash: stop sharing request queue across multiple gendisks
authorOmar Sandoval <osandov@fb.com>
Tue, 28 Mar 2017 06:28:47 +0000 (23:28 -0700)
committerJens Axboe <axboe@fb.com>
Tue, 28 Mar 2017 21:06:58 +0000 (15:06 -0600)
Compile-tested only (by hacking it to compile on x86).

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/sbus/char/jsflash.c

index 6ff61da..62fed9d 100644 (file)
@@ -183,11 +183,33 @@ static void jsfd_read(char *buf, unsigned long p, size_t togo) {
        }
 }
 
-static void jsfd_do_request(struct request_queue *q)
+static int jsfd_queue;
+
+static struct request *jsfd_next_request(void)
+{
+       struct request_queue *q;
+       struct request *rq;
+       int old_pos = jsfd_queue;
+
+       do {
+               q = jsfd_disk[jsfd_queue]->queue;
+               if (++jsfd_queue == JSF_MAX)
+                       jsfd_queue = 0;
+               if (q) {
+                       rq = blk_fetch_request(q);
+                       if (rq)
+                               return rq;
+               }
+       } while (jsfd_queue != old_pos);
+
+       return NULL;
+}
+
+static void jsfd_request(void)
 {
        struct request *req;
 
-       req = blk_fetch_request(q);
+       req = jsfd_next_request();
        while (req) {
                struct jsfd_part *jdp = req->rq_disk->private_data;
                unsigned long offset = blk_rq_pos(req) << 9;
@@ -211,10 +233,15 @@ static void jsfd_do_request(struct request_queue *q)
                err = 0;
        end:
                if (!__blk_end_request_cur(req, err))
-                       req = blk_fetch_request(q);
+                       req = jsfd_next_request();
        }
 }
 
+static void jsfd_do_request(struct request_queue *q)
+{
+       jsfd_request();
+}
+
 /*
  * The memory devices use the full 32/64 bits of the offset, and so we cannot
  * check against negative addresses: they are ok. The return value is weird,
@@ -544,8 +571,6 @@ static int jsflash_init(void)
        return 0;
 }
 
-static struct request_queue *jsf_queue;
-
 static int jsfd_init(void)
 {
        static DEFINE_SPINLOCK(lock);
@@ -562,6 +587,11 @@ static int jsfd_init(void)
                struct gendisk *disk = alloc_disk(1);
                if (!disk)
                        goto out;
+               disk->queue = blk_init_queue(jsfd_do_request, &lock);
+               if (!disk->queue) {
+                       put_disk(disk);
+                       goto out;
+               }
                jsfd_disk[i] = disk;
        }
 
@@ -570,13 +600,6 @@ static int jsfd_init(void)
                goto out;
        }
 
-       jsf_queue = blk_init_queue(jsfd_do_request, &lock);
-       if (!jsf_queue) {
-               err = -ENOMEM;
-               unregister_blkdev(JSFD_MAJOR, "jsfd");
-               goto out;
-       }
-
        for (i = 0; i < JSF_MAX; i++) {
                struct gendisk *disk = jsfd_disk[i];
                if ((i & JSF_PART_MASK) >= JSF_NPART) continue;
@@ -589,7 +612,6 @@ static int jsfd_init(void)
                disk->fops = &jsfd_fops;
                set_capacity(disk, jdp->dsize >> 9);
                disk->private_data = jdp;
-               disk->queue = jsf_queue;
                add_disk(disk);
                set_disk_ro(disk, 1);
        }
@@ -619,6 +641,7 @@ static void __exit jsflash_cleanup_module(void)
        for (i = 0; i < JSF_MAX; i++) {
                if ((i & JSF_PART_MASK) >= JSF_NPART) continue;
                del_gendisk(jsfd_disk[i]);
+               blk_cleanup_queue(jsfd_disk[i]->queue);
                put_disk(jsfd_disk[i]);
        }
        if (jsf0.busy)
@@ -628,7 +651,6 @@ static void __exit jsflash_cleanup_module(void)
 
        misc_deregister(&jsf_dev);
        unregister_blkdev(JSFD_MAJOR, "jsfd");
-       blk_cleanup_queue(jsf_queue);
 }
 
 module_init(jsflash_init_module);