zoukankan      html  css  js  c++  java
  • OSK VFS read数据流分析

    1. block_read_full_page(struct page *page, get_block_t *get_block)
    其中page是读操作的数据存放的位置, 即OS从硬盘上读取数据将会存放到page中.
    2. 为这个page分配buffer_head, head = alloc_page_buffers(page); 每个bh对应文件系统的block.
    3. 调用submit_bh(READ, bh); 此时的动作为:
    分配BIO. 即:
        if (buffer_page(bh))
            bio->bi_io_vec[0].bv_buffer = bh_page_data(bh);
        else
            bio->bi_io_vec[0].bv_buffer = bh_data(bh);
        bio->bi_io_vec[0].bv_len = bh->b_size;

        bio->bi_vcnt = 1;
        bio->bi_idx = 0;
        bio->bi_size = bh->b_size;
    即数据流为page -> buffer_head -> bio
    4. submit_bio(int rw, struct bio *bio) -> generic_make_request -> __make_request -> add_request(q, req);
    此时的动作是将此BIO作为一个request的member插入到request_queue中
    5. 在将来某个时候, SCSI命令将会执行时, 调用scsi_prep_fn(q,ret)
    scsi_init_io SCSI初始化IO操作, 它调用blk_rq_map_sg(req->q, req, cmd->request_buffer) ;此时cmd->request_buffer是数据是
    1) 是scatter-gather list
    2) 就简单的buffer.
    因此, 此时的数据流为page -> buffer_head -> bio -> request -> scsi_cmnd的request_buffer.
    6. usb_stor_Bulk_transport -> usb_stor_bulk_transfer_sg -> usb_stor_bulk_transfer_sglist or usb_stor_bulk_transfer_buf ->
    对于usb_stor_bulk_transfer_buf,
     usb_fill_bulk_urb/usb_stor_msg_common -> usb_submit_urb
    在usb_fill_bulk_urb中, urb-> transfer_buffer被设置为srb->request_buffer (注: SRB即前面的CMD)
    6. 然后在usb_submit_urb()时, 它调用HCD的usb_hcd_submit_urb(). 后者的动作将会将URB的数据转换成HC的硬件数据, 并将其加入到OHCI/UHCI/EHCI的Queue中, status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
    对于OHCI, 它的函数为ohci_urb_enqueue -> td_submit_urb (ohci, urb);
    对于bulk传输, 将调用td_fill()根据urb->transfer_dma来设置硬件的TD的buffer pointer, 最终写IO寄存器ohci_writel (ohci, OHCI_BLF, &ohci->regs->cmdstatus);
    因此, VFS的读操作的数据流为page -> buffer_head -> bio -> request -> scsi_cmnd的request_buffer -> urb的transfer_buffer/transfer_dma -> 硬件TD.

  • 相关阅读:
    【原创】VNC-view配置
    【LVM】LVM自动扩容脚本
    【linux磁盘分区--格式化】fdisk,parted,mkfs.ext3
    【原】Centos 7 下创建LVM流程
    【Spring-AOP-学习笔记-7】@Around增强处理简单示例
    【转】libvirt kvm 虚拟机上网 – Bridge桥接
    【phantomjs】使用phantomjs生成highChart的图片(待完善)
    【Redis】使用Redis Sentinel实现Redis HA
    【Redis】配置redis主从复制
    【转载】优秀博文转载
  • 原文地址:https://www.cnblogs.com/codestub/p/2287767.html
Copyright © 2011-2022 走看看