************
b_end_io()接收来自块设备驱动程序对物理块读写完成状态,必须在调用generic_make_request()提交块读写作业之前赋值。
作业块转递给块设备驱动程序时必须处于BH_Lock状态,当块的读写操作成功时,块设备驱动程序通过end_request()间接调用它的b_end_io(),
b_end_io()负责清除BH_Lock状态,设置BH_Uptodate刷新状态,以及唤醒该块的等待进程。
个别的块读写时指向end_buffer_io_sync(),读写一整页时指向end_buffer_io_async()。
(最后一句可有会有点争议。因为读里面使用了end_buffer_io_sync,是针对arr[]的bh数组而不是整页)
****************
/*
*写IO操作结束的通知函数,同步
*/
static void end_buffer_io_sync(struct buffer_head *bh, int uptodate)
{
/*
* 根据数据传送的成功还是失败,把bh的BH_Uptodate标志设置成1 or 0
* 不改变bh在lru_list中的位置
*/
mark_buffer_uptodate(bh, uptodate);
/*清除标志,见下面*/
unlock_buffer(bh);
/*完成对缓冲区头的操作之后,减少bh的引用计数*/
put_bh(bh);
}
/*
*清除BH_Wait_IO、BH_Launder、BH_Lock标志
*唤醒bh的b_wait字段所指向的等待队列中的睡眠进程
*/
void unlock_buffer(struct buffer_head *bh)
{
clear_bit(BH_Wait_IO, &bh->b_state);
clear_bit(BH_Launder, &bh->b_state);
/*
* When a locked buffer is visible to the I/O layer BH_Launder
* is set. This means before unlocking we must clear BH_Launder,
* mb() on alpha and then clear BH_Lock, so no reader can see
* BH_Launder set on an unlocked buffer and then risk to deadlock.
*/
smp_mb__after_clear_bit();
clear_bit(BH_Lock, &bh->b_state);
smp_mb__after_clear_bit();
if (waitqueue_active(&bh->b_wait))
wake_up(&bh->b_wait);
}
阅读(1986) | 评论(0) | 转发(1) |