ZBLOG

block_device 和bio操作nvme设备实现读和写完整demo

下面是一个示例代码,展示了如何使用block_device和BIO来进行NVMe设备的读写操作:

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

#define NVME_DEVICE_NAME "nvme0n1"

struct block_device *bdev;
char buffer[512];

static void bio_complete(struct bio *bio, int error)
{
    if (error) {
        printk(KERN_ERR "I/O error: %d\n", error);
    } else {
        printk(KERN_INFO "I/O completed successfully.\n");
    }
    bio_endio(bio);
}

static void nvme_read_block(unsigned long sector)
{
    struct bio *bio;

    bio = bio_alloc(GFP_KERNEL, 1);
    if (!bio) {
        printk(KERN_ERR "Failed to allocate BIO.\n");
        return;
    }

    bio->bi_iter.bi_sector = sector;
    bio->bi_bdev = bdev;
    bio_set_dev(bio, bdev->bd_disk);

    bio_add_page(bio, virt_to_page(buffer), PAGE_SIZE, 0);

    bio->bi_end_io = bio_complete;

    submit_bio_read(bio);
}

static void nvme_write_block(unsigned long sector)
{
    struct page *page;
	struct bio *bio;

	page = virt_to_page(buffer);

	bio = bio_alloc(GFP_KERNEL, 1);
	if (!bio) {
		printk(KERN_ERR "Failed to allocate BIO.\n");
		return;
	}

	bio->bi_iter.bi_sector = sector;
	bio->bi_bdev = bdev;
	bio_set_dev(bio, bdev->bd_disk);

	bio_add_page(bio, page, PAGE_SIZE, 0);

	bio->bi_end_io = bio_complete;

	submit_bio_write(bio);
}

static int __init nvme_demo_init(void)
{
    struct block_device *bdev_temp;
    
    bdev_temp = blkdev_get_by_path("/dev/" NVME_DEVICE_NAME, FMODE_READ | FMODE_WRITE, NULL);
    if (IS_ERR(bdev_temp)) {
        printk(KERN_ERR "Failed to open block device: %s\n", NVME_DEVICE_NAME);
        return PTR_ERR(bdev_temp);
    }

    bdev = bdget_disk(bdev_temp->bd_disk, 0);
    if (!bdev) {
        printk(KERN_ERR "Failed to get block device.\n");
        blkdev_put(bdev_temp, FMODE_READ | FMODE_WRITE);
        return -ENODEV;
    }

    strcpy(buffer, "Hello World!");

    nvme_write_block(0); // 写入第一个扇区

    memset(buffer, 0, sizeof(buffer)); // 清空缓冲区

    nvme_read_block(0); // 读取第一个扇区

	return 0;
}

static void __exit nvme_demo_exit(void)
{
	if (bdev)
		bdput(bdev);

	printk(KERN_INFO "NVMe demo module unloaded.\n");
}

module_init(nvme_demo_init);
module_exit(nvme_demo_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");

请注意,此示例仅用于展示基本的NVMe设备读写操作。实际情况中,还需要进行错误处理、边界检查等。

在模块初始化期间,我们通过blkdev_get_by_path()打开指定的块设备,并通过bdget_disk()获取相应的block_device结构体。然后,我们将一个字符串写入第一个扇区,并通过nvme_write_block()函数进行写操作。

接着,我们清空缓冲区并使用nvme_read_block()函数来读取第一个扇区的内容。

需要注意的是,本示例代码仅用于说明目的,实际情况中可能需要更复杂的错误处理、边界检查和数据验证等。同时,请确保在运行此示例代码之前备份好重要的数据,以防意外情况发生。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=4186

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?