/* * Calling wait_on_buffer() for a zero-ref buffer is illegal, so we call into * __wait_on_buffer() just to trip a debug check. Because debug code in inline * functions is bloaty. */ staticinlinevoid wait_on_buffer(struct buffer_head *bh) { might_sleep(); if(buffer_locked(bh)|| atomic_read(&bh->b_count)== 0) /* if a block is locked , it says kernel is transfering data into it * so we must wait for the bit has been cleared successfully * bob */ __wait_on_buffer(bh); }
/* * Note that the real wait_on_buffer() is an inline function that checks * that the buffer is locked before calling this, so that unnecessary disk * unplugging does not occur. */ void __wait_on_buffer(struct buffer_head * bh) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk);
get_bh(bh); add_wait_queue(&bh->b_wait,&wait);
/* in fact , here we use do {} while(condition) is better than for(;;) * because ,after "schedule()" ,maybe condition(buffer_locked()) has been applied * then the loop can directly break * --bob */ do{ run_task_queue(&tq_disk); set_task_state(tsk, TASK_UNINTERRUPTIBLE); if(!buffer_locked(bh)) break; schedule(); }while(buffer_locked(bh));