APP:read write 文件 保存到磁盘
--------------------------------
(文件系统)VFS虚拟文件层
--------------------------------
block块驱动 core核心驱动程序
--------------------------------
硬件相关的驱动程序,完成扇区的读写
文件系统调用底层驱动:
ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
struct buffer_head *bh = bhs[i];
>submit_bh(WRITE, bh);
struct bio *bio = bio_alloc(GFP_NOIO, 1);//分配bio,并根据bh填充bio
>submit_bio(rw, bio);
>generic_make_request(bio);
current->bio_list = bio->bi_next;//把bio加入到请求链表中
>__generic_make_request(bio);
request_queue_t *q = bdev_get_queue(bio->bi_bdev);//获得请求队列
>q->make_request_fn(q, bio);//调用请求队列中的指针函数
/*
*如是用户使用blk_alloc_queue来分配一个请求队列queue
*使用blk_queue_make_request函数来初始化这个请求队列,则该函数会把第二个参数:函数指针
*赋值给 q->make_request_fn,那么调用到q->make_request_fn时,就会调用用户自定义的函数
*来处理请求。
*/
>do_ramdisk_make_request_fn(request_queue_t *q,struct bio *bio)(=q->make_request_fn)
/*磁盘数据源*/
tmp_addr = v_ramdisk+bio->bi_sector*512;
bio_for_each_segment(bvl, bio, i)
{
/*根据bio中的页与偏移地址来映射内存 数据源缓冲区*/
pbuff = kmap(bvl->bv_page) + bvl->bv_offset;
/*数据传输的长度由 bio->bvl->bv_len 来确定一次bio数据转移的长度*/
/*调用数据转移函数*/
kunmap(bvl->bv_page);
tmp_addr += bvl->bv_len;//修改磁盘数据源下一次读写时的地址
}
bio_endio(bio,bio->bi_size,0);//一次请求结束,要上报
return 0;
/*
*如是用户使用blk_init_queue(do_ramdisk_request_rfn, &ramblock_lock);
*来分配一个请求队列queue,函数的第一个参数:函数指针,会赋值给q->request_fn,别外需要
*给该函数传入一个