Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3547330
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类:

2011-12-21 09:21:34

 


主要是 备忘地址转换的部分。

 

这个在编程的时候常用。 一定搞清楚他们之间的关系。

    struct page * buffer_page;
    unsigned long buffer_virt;
    buffer_virt = get_zeroed_page(GFP_ATOMIC))) {
    buffer_page = virt_to_page(buffer_virt);


    unsigned long get_zeroed_page(unsigned int gfp_mask)
{
    struct page * page;

    page = alloc_pages(gfp_mask, 0);
    if (page) {
        void *address = page_address(page);
        clear_page(address);
        return (unsigned long) address;
    }
    return 0;
}
/*
 * Common helper functions.
 */

unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
{
    struct page * page;

    page = alloc_pages(gfp_mask, order);
    if (!page)
        return 0;
    return (unsigned long) page_address(page);
}

#define TryLockPage(page)    test_and_set_bit(PG_locked, &(page)->flags)
#define PageChecked(page)    test_bit(PG_checked, &(page)->flags)
#define SetPageChecked(page)    set_bit(PG_checked, &(page)->flags)
#define PageLaunder(page)    test_bit(PG_launder, &(page)->flags)
#define SetPageLaunder(page)    set_bit(PG_launder, &(page)->flags)
#define ClearPageLaunder(page)    clear_bit(PG_launder, &(page)->flags)

//关于调用wait函数的代码

/*
 * 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.
 */

static inline void 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));
    
    tsk->state = TASK_RUNNING;
    remove_wait_queue(&bh->b_wait, &wait);
    put_bh(bh);
}


阅读(508) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~