Commit 8b0c441e authored by Omar Sandoval's avatar Omar Sandoval Committed by Jens Axboe
Browse files

jsflash: stop sharing request queue across multiple gendisks



Compile-tested only (by hacking it to compile on x86).

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 103db8b2
Loading
Loading
Loading
Loading
+36 −14
Original line number Diff line number Diff line
@@ -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);