2

In an Intel white paper, it says:

MD RAID in linux is a block driver that filters data between the Linux File System driver, such as ext2 file system, and the low level hard disk drivers, such as the AHCI driver and SAS driver.

In kernel code drivers/md/md.c, I only find this 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 has neither read nor write:

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,
};

Is this the file_operations that MD driver performs open, read...? How does MD driver writes data? Use AHCI driver?

When a write syscall is called, what is the steps to write data?

sys_write -> vfs_write -> file->f_op->write or do_sync_write? The md_seq_fops has neither write nor aio_write

siyuan
  • 113
  • 7

2 Answers2

1

The exact sequence of function calls will depend on various situations like whether I/O is direct or not, whether I/O is synchronous or asynchronous etc. Depending on these situations, at the end make_request() method of MD layer is called and this method is registered by MD layer itself at the time of RAID device creation by blk_queue_make_request() call as shown below in md.c file:

blk_queue_make_request(mddev->queue, md_make_request);

This md_make_request() function will internally calls make_request() method specific to that RAID device personality as shown below:

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

You can find specific make_request() method in the list of RAID personality methods given in individual RAID files in source code, i.e., for raid0 personality, here is list of methods where make_request is initialized with raid0_make_request() in raid0.c file.

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,
};

This raid0_make_request() function will perform read or write on raid0 device.

pratik
  • 434
  • 2
  • 8
  • Thank you very much. raid0_make_request -> generic_make_request -> q->make_request_fn(q, bio); right? How make_request_fn call AHCI driver to write data? (suppose sata drive connect to AHCI controller). – siyuan Jan 04 '16 at 16:42
  • @siyuan: Yes. the sequence of function calls mentioned by you are correct. Regarding your second question, I have mostly worked on SCSI or SCSI related protocols. I am not sure about AHCI, but if its devices are registered as SCSI devices then scsi_request_fn -> scsi_dispatch_cmd and then queuecommand function pointer registered by your AHCI driver, which I am not sure but might be ata_scsi_queuecmd(). But if it is not going through SCSI path then you will need to find similar flow for AHCI driver. – pratik Jan 06 '16 at 12:18
0

struct file_operations has many more members. Per C99, members not listed are initialized to NULL which means they're not specially implemented. That's normal for filter drivers; they replace only some operations.

MSalters
  • 173,980
  • 10
  • 155
  • 350