Kernel block block

I'm currently trying to implement a simple (wrong?) Simple kernel block driver.

I was inspired mainly from the book "Linux Device Drivers", 3rd Edition , which is not completely updated since it was published in 2005.

In any case, logic still exists, and I learned a lot from it. However, the examples are not very effective, as many things have changed since 2005.

I found the github repository where the examples should be updated to work with the latest kernels, but I think there is something else to update as I cannot adapt the examples to make it work with the 4.9.0 kernel

This is how my module was created:

Upon initialization:

  • Register the module as a block device with register_blkdev
  • Highlight device data buffer
  • Spin Lock Initialization
  • Initialize the request queue
  • Request Queue Setting
  • Select structure gendisk
  • Fill in the structure gendisk
  • Create a disk using add_disk

Then I implemented the function of processing request events from the request queue and processing read and write events on the block device.

Here is the function: (it was very inspired by LLD-3rd with some changes in line with the current kernel functions)

static void block_mod_request(struct request_queue *queue)
{
    printk(KERN_NOTICE "Entering request function\n");
    struct request *request;

    while(NULL != (request = blk_fetch_request(queue)))
    {
        blk_mod_t *self = request->rq_disk->private_data;
        // Check if request is a filesystem request (i.e. moves block of data)
        if(REQ_TYPE_FS != request->cmd_type)
        {
            // Close request with unsuccessful status
            printk(KERN_WARNING "Skip non-fs request\n");
            __blk_end_request_cur(request, -EIO);
            continue;
        }
        // Treat request
        block_mod_transfer(self, blk_rq_pos(request), blk_rq_cur_sectors(request), request->buffer, rq_data_dir(request));
        // Close request with successful status
        __blk_end_request_cur(request, 0);
    }
    return;
}

However, when compiling, I received the following error:

block_mod.c:82:91: error: ‘struct requesthas no member namedbufferblock_mod_transfer(self, blk_rq_pos(request), blk_rq_cur_sectors(request), request->buffer, rq_data_dir(request));

After checking the file blkdev.hin the v4.9.0 kernel headers, it seems that the field bufferno longer exists in struct request.
However, I can’t find any information on how everything turned out and how to change the code to make it work.

, buffer . , ​​ / .

, , , .

, ?

+4
1

, , Ming Lei:

block:

,    .    . , highmem ,     , rq->buffer     - .

, bio_data().

BIO, lwn. :

char *bio_data(struct bio *bio)

  .

, , , bio_data(rq->bio) rq->buffer.

:
, -, - .

+2

Source: https://habr.com/ru/post/1696073/


All Articles