免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1570 | 回复: 0
打印 上一主题 下一主题

ll_rw_block解析Ⅱ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-16 16:20 |只看该作者 |倒序浏览

void generic_make_request (int rw, struct buffer_head * bh)
{
    int major = MAJOR(bh->b_rdev);
    request_queue_t *q;

/* 检查,当进行IO请求时,缓冲块必须安装b_end_io函数*/
    if (!bh->b_end_io)
        BUG();
   
/*
*数组blk_size[MAJOR][MINOR]在drivers/block/ll_rw_block.c中定义
*内容为各项具体设备中含有1024字节记录块的个数
*/
/* 取缓冲块所在块设备的最大扇区号*/
    if (blk_size[major]) {
        unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)]

/* 请求传送的起始扇区号 */
unsigned long sector = bh->b_rsector;

/*每块的扇区数(记录块大小除以512)*/
        unsigned int count = bh->b_size >> 9;

/* 当读写请求越界时,通过printk在系统运行日志中登记出错信息返回*/
        if (maxsector
/* 保留BH_Lock和BH_Mapped状态*/
bh->b_state &= (1
            if (blk_size[major][MINOR(bh->b_rdev)]) {
               
                /* This may well happen - the kernel calls bread()
                   without checking the size of the device, e.g.,
                   when mounting a device. */
                printk(KERN_INFO
                       "attempt to access beyond end of device\n");
                printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n",
                       kdevname(bh->b_rdev), rw,
                       (sector + count)>>1,
                       blk_size[major][MINOR(bh->b_rdev)]);
            }
            /*读写失败*/
            bh->b_end_io(bh, 0);
            return;
        }
    }

    /*
     * Resolve the mapping until finished. (drivers are
     * still free to implement/resolve their own stacking
     * by explicitly returning 0)
     */
    /* NOTE: we don't repeat the blk_size check for each new device.
     * Stacking drivers are expected to know what they are doing.
     */
    do {
/*调用blk_get_queue->__blk_get_queue取块设备的IO请求结构*/         
        q = blk_get_queue(bh->b_rdev);
        if (!q) {
            printk(KERN_ERR
                   "generic_make_request: Trying to access nonexistent block-device %s(%ld)\n",
                   kdevname(bh->b_rdev), bh->b_rsector);
           /*当出错时,块的状态为"净"和"无效"*/
            buffer_IO_error(bh);
            break;
        }
      /*调用块设备驱动程序的读写请求函数.
*即请求队列描述符q的make_request_fn 方法:
*创建一个读写数据结构并把它挂入该队列
*该方法由函数__make_request函数实现
*/
    } while (q->make_request_fn(q, rw, bh)); }
/*
*如果只是一种设备到另一种设备的映射,返回一个正整数,do-while循环再执行一遍
*如果完成的是对终极设备的操作,则返回0,结束循环
*/


request_queue_t *blk_get_queue(kdev_t dev)
{
    request_queue_t *ret;
    unsigned long flags;

    spin_lock_irqsave(&io_request_lock,flags);
    ret = __blk_get_queue(dev);
    spin_unlock_irqrestore(&io_request_lock,flags);

    return ret;
}


inline request_queue_t *__blk_get_queue(kdev_t dev)
{
/*
*
blk_dev_struct

blk_dev
[
MAX_BLKDEV
]存储块设备的描述符
* 由块设备的主设备号索引 ,可以在blk_dev中找到相应blk_dev_struct结构
*/
    struct blk_dev_struct *bdev = blk_dev + MAJOR(dev);

/*
*先检查queue字段是否为空
*如果定义了.queue方法(驱程维护几个队列),
*调用queue字段指向的一个自定义驱程方法
*/
    if (bdev->queue)
        return bdev->queue(dev);

/*否则读.request_queue字段(驱程单个队列)*/
    else
        return &blk_dev[MAJOR(dev)].request_queue;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/33412/showart_341118.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP