目次
機能
BUSEのキューを読み取り、read, write関数を呼び出し。
方針
API
関数構造体を登録。
struct buse_ops = {
.read
.write
}
BUSE修正
ビルドを通す
diff --git a/kernel/buse-blkdev.c b/kernel/buse-blkdev.c
index ee97b03..e679c52 100644
--- a/kernel/buse-blkdev.c
+++ b/kernel/buse-blkdev.c
@@ -17,7 +17,7 @@
*/
static int buse_init_hctx(struct blk_mq_hw_ctx *hw_ctx, void *driver_data, unsigned int hw_ctx_id)
{
- struct buse *buse = hw_ctx->queue->queuedata;
+ struct buse *buse = driver_data;
struct buse_queue *q = buse->queues;
q[hw_ctx_id].id = hw_ctx_id;
@@ -47,7 +47,6 @@ static blk_status_t buse_queue_rq(struct blk_mq_hw_ctx *hw_ctx, const struct blk
switch (req_op(r)) {
case REQ_OP_DISCARD:
- case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE_ZEROES:
case REQ_OP_SECURE_ERASE:
case REQ_OP_WRITE:
@@ -56,6 +55,8 @@ static blk_status_t buse_queue_rq(struct blk_mq_hw_ctx *hw_ctx, const struct blk
return buse_flush(cmd);
case REQ_OP_READ:
return buse_read(cmd);
+ default:
+ break;
}
pr_warn("Unsupported request no. %d\n", req_op(r));
@@ -71,7 +72,7 @@ static const struct block_device_operations buse_blkdev_ops = {
* When io request times out we just print warning to the dmesg a give it another chance. This is
* the best we can do. If the device is eventually stopped, these requests will be canceled.
*/
-static enum blk_eh_timer_return buse_timeout(struct request *rq, bool b)
+static enum blk_eh_timer_return buse_timeout(struct request *rq)
{
pr_warn("Request timed out! Is userspace connected? (rq = %p)\n", rq);
@@ -118,24 +119,28 @@ int buse_blkdev_init(struct buse *buse)
size_t writelist_size = max_writes * sizeof(struct writelist_item);
unsigned int max_hw_sectors;
- blkdev->disk = alloc_disk_node(1, NUMA_NO_NODE);
- if (!blkdev->disk) {
- ret = -ENOMEM;
- goto err;
- }
-
buse_set_tag_set(buse);
ret = blk_mq_alloc_tag_set(tag_set);
if (ret)
goto err_disk;
- blkdev->request_queue = blk_mq_init_queue_data(tag_set, buse);
+ blkdev->disk = blk_mq_alloc_disk(&buse->blkdev.tag_set, buse);
+ if (!blkdev->disk) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ //blkdev->request_queue = blk_mq_init_queue(tag_set);
+ //blkdev->request_queue->queuedata = buse;
+ blkdev->request_queue = blkdev->disk->queue;
+
if (IS_ERR(blkdev->request_queue)) {
ret = PTR_ERR(blkdev->request_queue);
goto err_tag;
}
+
blk_queue_write_cache(blkdev->request_queue, true, false);
max_hw_sectors = (buse->write_chunk_size - writelist_size) / SECTOR_SIZE;
@@ -159,23 +164,23 @@ int buse_blkdev_init(struct buse *buse)
blk_queue_max_segments(blkdev->request_queue, USHRT_MAX);
blk_queue_max_segment_size(blkdev->request_queue, UINT_MAX);
- if (buse->can_write_same)
- blk_queue_max_write_same_sectors(blkdev->request_queue, UINT_MAX);
+ //if (buse->can_write_same)
+ // blk_queue_max_write_same_sectors(blkdev->request_queue, UINT_MAX);
if (buse->can_write_zeroes)
blk_queue_max_write_zeroes_sectors(blkdev->request_queue, UINT_MAX);
- if (buse->can_discard) {
+ /*if (buse->can_discard) {
blk_queue_flag_set(QUEUE_FLAG_DISCARD, blkdev->request_queue);
blkdev->request_queue->limits.discard_granularity = buse->block_size;
blkdev->request_queue->limits.discard_alignment = buse->block_size;
blk_queue_max_discard_sectors(blkdev->request_queue, UINT_MAX);
blk_queue_max_discard_segments(blkdev->request_queue, USHRT_MAX);
- }
+ }*/
- if (buse->can_secure_erase)
- blk_queue_flag_set(QUEUE_FLAG_SECERASE, blkdev->request_queue);
+ //if (buse->can_secure_erase)
+ // blk_queue_flag_set(QUEUE_FLAG_SECERASE, blkdev->request_queue);
return 0;
@@ -197,7 +202,7 @@ void buse_blkdev_exit(struct buse *buse)
put_disk(buse->blkdev.disk);
}
- blk_cleanup_queue(buse->blkdev.request_queue);
+ blk_mq_destroy_queue(buse->blkdev.request_queue);
blk_mq_free_tag_set(&buse->blkdev.tag_set);
buse->blkdev.created = false;
}
@@ -212,7 +217,6 @@ void buse_gendisk_register(struct buse *buse)
disk->major = buse_blkdev_major;
disk->minors = buse_blkdev_max_minors;
disk->first_minor = buse->index * disk->minors;
- disk->flags |= GENHD_FL_EXT_DEVT;
disk->fops = &buse_blkdev_ops;
disk->private_data = buse;
disk->queue = buse->blkdev.request_queue;
diff --git a/kernel/buse-chrdev.c b/kernel/buse-chrdev.c
index 0082242..ad493e0 100644
--- a/kernel/buse-chrdev.c
+++ b/kernel/buse-chrdev.c
@@ -113,6 +113,7 @@ static int chrdev_release_rqueue(struct inode *inode, struct file *file)
*/
static int chrdev_open_wqueue(struct inode *inode, struct file *file)
{
+ printk("open_wqueue....");
struct buse_wqueue *wq = inode_get_wqueue(inode);
if (!wq || atomic_read(&wq->bound) == 1)
return -EFAULT;
@@ -128,6 +129,7 @@ static int chrdev_open_wqueue(struct inode *inode, struct file *file)
*/
static int chrdev_open_rqueue(struct inode *inode, struct file *file)
{
+ printk("open_rqueue....");
struct buse_rqueue *rq = inode_get_rqueue(inode);
if (!rq || atomic_read(&rq->bound) == 1)
return -EFAULT;
@@ -156,7 +158,7 @@ static struct vm_operations_struct vm_ops_rqueue = {
static int chrdev_mmap_wqueue(struct file *file, struct vm_area_struct *vma)
{
vma->vm_ops = &vm_ops_wqueue;
- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
vma->vm_private_data = file->private_data;
vm_open(vma);
@@ -169,7 +171,7 @@ static int chrdev_mmap_wqueue(struct file *file, struct vm_area_struct *vma)
static int chrdev_mmap_rqueue(struct file *file, struct vm_area_struct *vma)
{
vma->vm_ops = &vm_ops_rqueue;
- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
vma->vm_private_data = file->private_data;
vm_open(vma);
diff --git a/kernel/buse-wqueue.c b/kernel/buse-wqueue.c
index 2b4f12f..911d476 100644
--- a/kernel/buse-wqueue.c
+++ b/kernel/buse-wqueue.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
+#include <linux/sched/task.h>
#include "buse-blkdev.h"
#include "buse-chrdev.h"
@@ -446,7 +447,8 @@ static int wqueue_flush(void *data)
mutex_unlock(&wq->lock);
kfree(data);
- do_exit(0);
+ return 0;
+ //do_exit(0); // TODO: Fix this
}
/*
@@ -614,6 +616,7 @@ static int wqueue_init(struct buse_wqueue *wq)
for (i = 0; i < w_chunks; i++)
init_write_chunk(wq, &wq->chunks[i]);
+ printk("wqueue_init:%p\n", wq);
open_chunk(wq);
return 0;
@@ -629,6 +632,7 @@ err:
*/
int buse_wqueues_init(struct buse *buse)
{
+ printk("buse_wqueues_init\n");
int ret, i;
struct buse_queue *q;
size_t collisions_areas = buse->size / buse->collision_area_size;
diff --git a/kernel/main.c b/kernel/main.c
index c78ea6d..b2021e8 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -61,6 +61,7 @@ void buse_blkdev_init_cond(struct buse *buse)
{
int ret;
+ printk("wq_bound=%d, rq_bound=%d, created=%d\n", buse_wqueues_bound(buse), buse_rqueues_bound(buse), buse->blkdev.created);
if (!buse_wqueues_bound(buse) ||
!buse_rqueues_bound(buse) ||
buse->blkdev.created)
@@ -194,7 +195,7 @@ static int __init buse_init(void)
goto err;
}
- buse_chrdev_class = class_create(THIS_MODULE, buse_blkdev_name);
+ buse_chrdev_class = class_create(buse_blkdev_name);
if (IS_ERR(buse_chrdev_class)) {
ret = PTR_ERR(buse_chrdev_class);
goto err_blk;
modprobe
takayuki@takayuki-VirtualBox:~/repos/buse/kernel$ sudo make install
takayuki@takayuki-VirtualBox:~/repos/buse/kernel$ sudo modprobe buse
BUSE構成
BUSEをmodprobeしただけではBUSEデバイスは作成されない。BUSEデバイスを使用するにはconfigfs経由でBUSEデバイスを宣言する必要がある。BUSEデバイスの作成は、/sys/kernel/config/buse以下にファイルを作成する。
root@takayuki-VirtualBox:/home/takayuki/repos/buse/kernel# mkdir /sys/kernel/config/buse/0
root@takayuki-VirtualBox:/home/takayuki/repos/buse/kernel# ls /sys/kernel/config/buse/0/
blocksize can_discard can_secure_erase can_write_same can_write_zeroes collision_area_size hw_queues io_min io_opt no_scheduler power queue_depth read_shm_size size write_chunk_size write_shm_size
PowerOn
root@takayuki-VirtualBox:/home/takayuki/repos/buse/kernel# echo 1 > /sys/kernel/config/buse/0/power
buse app実行
takayuki@takayuki-VirtualBox:~/repos/spdk$ sudo ./scripts/setup.sh
takayuki@takayuki-VirtualBox:~/repos/spdk$ sudo ./test/app/buse/buse -i 1