gpt4 book ai didi

c - 使用 rmmod (del_gendisk) 卸载时 Linux block 设备模块挂起

转载 作者:太空宇宙 更新时间:2023-11-04 11:49:07 26 4
gpt4 key购买 nike

我正在为 Linux 中的 block 设备驱动程序编写一个小示例。这个例子不完整,我一步一步来。我用blkdev_register注册了 block 设备,用alloc_disk分配了gendisk结构。插入模块时一切正常。它显示在 /proc/devices 中。但是如果我想用 rmmod 卸载它,它就会挂起。

我发现,在模块卸载函数中,对 del_gendisk 的调用导致了挂起。我知道 gendisk 结构有一个嵌入的 kobject,它负责引用计数。这种机制会阻碍您在使用模块时卸载它。但是因为我没有调用 add_disk,所以应该没有对该结构的引用。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>

#define BLKDEVNAME "blkdev_test"
#define MINORS 16

struct block_device_operations bdops = {
.owner = THIS_MODULE
};

struct blkdev {
int major;
struct gendisk *disk;
struct request_queue *queue;
} dev;


static int __init blkdev_init(void)
{
dev.major = register_blkdev( 0, BLKDEVNAME );
if( dev.major < 0 )
return -EIO;

dev.disk = alloc_disk(MINORS);
if( dev.disk == NULL )
goto DISK_ERR;

dev.disk->major = dev.major;
dev.disk->first_minor = 0;
snprintf(dev.disk->disk_name, DISK_NAME_LEN, "bd0" );
dev.disk->fops = &bdops;
// dev.disk->queue = dev.queue;

// add_disk( dev.disk );

return 0;

DISK_ERR:
unregister_blkdev( dev.major, BLKDEVNAME );
return -EIO;
}

static void __exit blkdev_exit(void)
{
del_gendisk(dev.disk);
unregister_blkdev( dev.major, BLKDEVNAME );
}

module_init(blkdev_init);
module_exit(blkdev_exit);
MODULE_LICENSE("GPL");

如果我发出命令 sudo rmmod mod.ko 然后命令被系统终止。

最佳答案

Quoting :

Manipulating gendisks Once you have your gendisk structure set up, you have to add it to the list of active disks; that is done with:

void add_disk(struct gendisk *disk);

After this call, your device is active. There are a few things worth keeping in mind about add_disk():

add_disk() can create I/O to the device (to read partition tables and such). You should not call add_disk() until your driver is
sufficiently initialized to handle requests.

If you are calling add_disk() in your driver initialization routine, you should not fail the initialization process after the
first call.

The call to add_disk() increments the disk's reference count; if the disk structure is ever to be released, the driver is responsible
for decrementing that count (with put_disk()).

Should you need to remove a disk from the system, that is accomplished with:

void del_gendisk(struct gendisk *disk);

This function cleans up all of the information associated with the given disk, and generally removes it from the system. After a call to del_gendisk(), no more operations will be sent to the given device. Your driver's reference to the gendisk object remains, though; you must explicitly release it with:

void put_disk(struct gendisk *disk);

That call will cause the gendisk structure to be freed, as long as no other part of the kernel retains a reference to it.

关于c - 使用 rmmod (del_gendisk) 卸载时 Linux block 设备模块挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56611035/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com