【问题标题】:How does Linux md driver write data to SATA disk?Linux md驱动如何将数据写入SATA磁盘?
【发布时间】:2016-01-04 03:12:10
【问题描述】:

an Intel white paper 中,它说:

Linux中的MD RAID是一个块驱动,在Linux之间过滤数据 文件系统驱动程序,如 ext2 文件系统,以及低级硬盘 磁盘驱动程序,例如 AHCI 驱动程序和 SAS 驱动程序。

在内核代码drivers/md/md.c中,我只找到了这个file_operations

static const struct file_operations md_seq_fops = {
    .owner          = THIS_MODULE,
    .open           = md_seq_open,
    .read           = seq_read,
    .llseek         = seq_lseek,
    .release        = seq_release_private,
    .poll           = mdstat_poll,

};

md_fops 既不读也不写:

static const struct block_device_operations md_fops =
{
        .owner          = THIS_MODULE,
        .open           = md_open,
        .release        = md_release,
        .ioctl          = md_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = md_compat_ioctl,
#endif
        .getgeo         = md_getgeo,
        .media_changed  = md_media_changed,
        .revalidate_disk= md_revalidate,
};

这就是MD驱动执行的file_operations open, read...? MD驱动如何写入数据?使用 AHCI 驱动?

当调用 write 系统调用时,写入数据的步骤是什么?

sys_write -> vfs_write -> 文件->f_op->write 还是 do_sync_write? md_seq_fops 既没有 write 也没有 aio_write

【问题讨论】:

    标签: linux-kernel drivers raid


    【解决方案1】:

    函数调用的确切顺序将取决于各种情况,例如 I/O 是否直接,I/O 是同步还是异步等。根据这些情况,最后 MD 层的 make_request() 方法是调用该方法,该方法由 MD 层在创建 RAID 设备时通过 blk_queue_make_request() 调用自行注册,如下 md.c 文件所示:

    blk_queue_make_request(mddev->queue, md_make_request);
    

    这个 md_make_request() 函数将在内部调用特定于该 RAID 设备特性的 make_request() 方法,如下所示:

    mddev->pers->make_request(mddev, bio);
    

    您可以在源代码中各个 RAID 文件中给出的 RAID 个性方法列表中找到特定的 make_request() 方法,即对于 raid0 个性,这里是在 raid0.c 中使用 raid0_make_request() 初始化 make_request 的方法列表文件。

    static struct md_personality raid0_personality=
    {
             .name           = "raid0",
             .level          = 0,
             .owner          = THIS_MODULE,
             .make_request   = raid0_make_request,
             .run            = raid0_run,
             .free           = raid0_free,
             .status         = raid0_status,
             .size           = raid0_size,
             .takeover       = raid0_takeover,
             .quiesce        = raid0_quiesce,
             .congested      = raid0_congested,
    };
    

    此 raid0_make_request() 函数将在 raid0 设备上执行读取或写入。

    【讨论】:

    • 非常感谢。 raid0_make_request -> generic_make_request -> q->make_request_fn(q, bio);正确的? make_request_fn如何调用AHCI驱动写入数据? (假设 sata 驱动连接到 AHCI 控制器)。
    • @siyuan:是的。您提到的函数调用顺序是正确的。关于你的第二个问题,我主要研究 SCSI 或 SCSI 相关协议。我不确定 AHCI,但如果它的设备注册为 SCSI 设备,那么 scsi_request_fn -> scsi_dispatch_cmd 然后由您的 AHCI 驱动程序注册的 queuecommand 函数指针,我不确定,但可能是 ata_scsi_queuecmd()。但如果它不通过 SCSI 路径,那么您将需要为 AHCI 驱动程序找到类似的流程。
    【解决方案2】:

    struct file_operations 有更多成员。根据 C99,未列出的成员被初始化为 NULL,这意味着它们不是专门实现的。这对于 filter 驱动程序来说是正常的;它们只替换了一些操作。

    【讨论】:

    • MD raid 是过滤驱动吗?
    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2012-08-12
    相关资源
    最近更新 更多