主要是 备忘地址转换的部分。
这个在编程的时候常用。 一定搞清楚他们之间的关系。
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); }
|
阅读(12937) | 评论(0) | 转发(1) |