亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? buffer.c.txt

?? linux內核學習筆記 希望想看的人可以很快下載到
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
        hash_page_buffers(page, dev, block, size);	//將這個新產生的頁加入到相應的hash表中


(3)static struct page * grow_dev_page(struct block_device *bdev, unsigned long index, int size)
        page = find_or_create_page(bdev->bd_inode->i_mapping, index, GFP_NOFS);	//首先找到一個頁面

        bh = page->buffers;	//先得到這個頁面的buffer域
        if (bh) {		//如果buffers域中有數據
                if (bh->b_size == size)		//如果正好是這個大小的,就返回這個頁面
                        return page;
                if (!try_to_free_buffers(page, GFP_NOFS))	//否則,試著釋放掉這個頁面
                        goto failed;
        }
	
        bh = create_buffers(page, size, 0);	//否則的話就在這個頁面上產生一個新的buffer
	if (!bh)
                goto failed;
        link_dev_buffers(page, bh);
        return page;

(4)static struct buffer_head * create_buffers(struct page * page, unsigned long size, int async)
        struct buffer_head *bh, *head;
        long offset;
        head = NULL;
        offset = PAGE_SIZE;
        while ((offset -= size) >= 0) {			//把這一頁都設置為size大小的buffer
                bh = get_unused_buffer_head(async);	//必須首先得到一個有效的buffer_head結構
                if (!bh)
                        goto no_grow;	//如果沒有,就釋放一些buffer_head結構

                bh->b_dev = NODEV;	
                bh->b_this_page = head;	//設置在一個頁中的buffer環
                head = bh;
		……	//對bh進行初始化
                set_bh_page(bh, page, offset);

                bh->b_list = BUF_CLEAN;
                bh->b_end_io = NULL;
        }
        return head;


void set_bh_page (struct buffer_head *bh, struct page *page, unsigned long offset)
{
        if (offset >= PAGE_SIZE)	//進行合法性檢查
                BUG();

        bh->b_data = page_address(page) + offset;	//數據的開始地址,結束地址可以使用開始
							//地址加上bh->b_size來進行計算
        bh->b_page = page;	//紀錄這個buffer所處的內存頁
}



(4)static inline void link_dev_buffers(struct page * page, struct buffer_head *head)
        struct buffer_head *bh, *tail;
        bh = head;
        do {
                tail = bh;
                bh = bh->b_this_page;	//尋找這個buffer所在的內存頁面的所有的buffer,
        } while (bh);	

        tail->b_this_page = head;	//把屬于一個內存頁面的所有的buffer連接成為一個環
        page->buffers = head;
        page_cache_get(page);


()static void free_more_memory(void)
        balance_dirty();		//計算臟塊所占的比例
        wakeup_bdflush();		//喚醒寫臟塊進程
        try_to_free_pages(GFP_NOFS);
        run_task_queue(&tq_disk);
        __set_current_state(TASK_RUNNING);
        sys_sched_yield();


(3)void balance_dirty(void)
	int state = balance_dirty_state();	//計算flush策略
        if (state < 0)				//如果臟塊比例不打,返回
                return;
        wakeup_bdflush();			//喚醒flush進程
        if (state > 0) {			//如果是同步flush的話,就等待他完成
                spin_lock(&lru_list_lock);
                write_some_buffers(NODEV);
                wait_for_some_buffers(NODEV);
        }

	

//返回值-1表示不用flush
//0-->異步flush
//1-->同步flush
(4)static int balance_dirty_state(void)
	
	……	//計算臟的比例
	
        soft_dirty_limit = tot * bdf_prm.b_un.nfract;
        hard_dirty_limit = tot * bdf_prm.b_un.nfract_sync;

	//如果臟塊數量占的比例不是很大,那么就異步flush,也就是僅僅喚醒flush進程
        if (dirty > soft_dirty_limit) {	
                if (dirty > hard_dirty_limit && !(current->flags & PF_NOIO))
                        return 1;	//如果臟塊比例過大,那么就喚醒flush進程并等待他完成
                return 0;
        }

*********************************************************************


***********************異步等待操作**********************************
相關文件
	include/linux/locks.h

這個函數主要是運行塊設備的運行例程,從而將傳入的buffer_head上所制定的操作完成
void __wait_on_buffer(struct buffer_head * bh)
	DECLARE_WAITQUEUE(wait, tsk);	//生命等待隊列
	get_bh(bh);			//buffer_head計數加一
	add_wait_queue(&bh->b_wait, &wait);	//把buffer_head加入到等待隊列中
	do {
		run_task_queue(&tq_disk);	//運行磁盤操作隊列,進行讀寫
		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
		if (!buffer_locked(bh))		//如果bh還是加鎖,說明沒有完成操作
			break;
		schedule();			//調度,等待
	} while (buffer_locked(bh));		//直到bh解鎖
	……					//后續處理
*********************************************************************


**************************異步讀操作**********************************
struct buffer_head * bread(kdev_t dev, int block, int size)
	bh = getblk(dev, block, size);	//的到一個buffer_head結構
	touch_buffer(bh);		
	if (buffer_uptodate(bh))	//如果的緩存結構中的buffer_head已經是更新的了,就直接返回
		return bh;
	ll_rw_block(READ, 1, &bh);	//否則進行讀操作
	wait_on_buffer(bh);		//等待讀操作完成
	if (buffer_uptodate(bh))
		return bh;
	brelse(bh);			//釋放bh
	return NULL;			//失敗的讀操作
**********************************************************************



***************************direct I/O操作*****************************
(1)
int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
		kdev_t dev, unsigned long b[], int size)
	for (i = 0; i < nr; i++) {	//對于每一個輸入的kiobuf的結構
		iobuf = iovec[i];	
		……			//都要進行合法性檢查	
	}
		
	bufind = bhind = transferred = err = 0;
	for (i = 0; i < nr; i++) {		//可以walk這些vec來進行讀寫了
		iobuf = iovec[i];
		offset = iobuf->offset;		//
		length = iobuf->length;		//取出這個kiobuf要讀寫的數據長度
		if (!bhs)
			bhs = iobuf->bh;	//取出這個kiobuf的bh池
	
		for (pageind = 0; pageind < iobuf->nr_pages; pageind++) { //遍歷kiobuf中所有的頁
			map  = iobuf->maplist[pageind];		//得到一個頁面結構
			while (length > 0) {			//如果讀寫的長度不是0
				blocknr = b[bufind];		//挨個查詢塊號
				if (blocknr == -1UL) {		//如果塊號是負數
					if (rw == READ) {
						memset(kmap(map) + offset, 0, size);
						flush_dcache_page(map);
						kunmap(map);
						transferred += size;
						goto skip_block;
					} else
						BUG();
				}				//????
				if (iobuf->dovary && (offset == 0)) {
					iosize = RAWIO_BLOCKSIZE; 
					if (iosize > length)
						iosize = length;
				}				//????
				bufind += (iosize/size);	//得到下一個讀寫的這個設備的塊號。
				tmp = bhs[bhind++];		//從kiobuf的bh池中取出一個bh結構
				
				tmp->b_size = iosize;		//設置bh的讀寫大小
				set_bh_page(tmp, map, offset);	//將取到的頁面掛在bh上
				tmp->b_this_page = tmp;		//
				
				init_buffer(tmp, end_buffer_io_kiobuf, iobuf);	//設置回調函數
				tmp->b_dev = dev;		//設置讀寫設備號
				tmp->b_blocknr = blocknr;	//設置讀寫的塊號
				……				//其它設置
					
				/*
				 * 這行代碼很重要。使用這個io_count來對這個kiobuf
				 * 中所提交的bh進行計數跟蹤。
				 */
				atomic_inc(&iobuf->io_count);	
				
				submit_bh(rw, tmp);		//進行實際讀寫
			
				/*
				 * 如果kiobuf中的bh池(kiobuf->bh)中已經沒有bh了,就等待
				 * 先前做的kiobuf的讀寫完成,釋放一部分bh。
				 */
				if (bhind >= KIO_MAX_SECTORS) {
					kiobuf_wait_for_io(iobuf); /* wake-one */
					err = wait_kio(rw, bhind, bhs, size);	
					if (err >= 0)
						transferred += err;
					else
						goto finished;
					bhind = 0;	//釋放原來的bh結構,供后續操作使用
				}
				
				length -= iosize;	//從要讀取的總長度中減去已經做過的
				offset += iosize;	//偏移量也增加相應的長度

				if (offset >= PAGE_SIZE) {	//如果偏移量已經超出了一個頁面
					offset = 0;		//偏移量置為0
					break;			//推出這個頁面的循環,取新頁面。
				}
			}
		}
	}
		
	if (bhind) {	//如果bhind不為0,說明還有剩余的bh沒有完成
		kiobuf_wait_for_io(iobuf); 
		err = wait_kio(rw, bhind, bhs, size);	//等待這些bh的完成
		if (err >= 0)
			transferred += err;
		else
			goto finished;
	}

	
(2)
static void end_buffer_io_kiobuf(struct buffer_head *bh, int uptodate)
	mark_buffer_uptodate(bh, uptodate);	//標志數據塊已經更新

	kiobuf = bh->b_private;			//取出kiobuf結構
	end_kio_request(kiobuf, uptodate);	//完成kiobuf請求
	unlock_buffer(bh);			//解鎖bh。
			


(3)
/*
 * 這個函數很簡單,就是對于參數指定數目nr的bh結構數據,遍歷這些bh結構,等待,
 * 直到所有的bh都更新了。
 */
static int wait_kio(int rw, int nr, struct buffer_head *bh[], int size)
	
**********************************************************************


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99综合电影在线视频| 亚洲欧美另类综合偷拍| 久久久精品黄色| 亚洲欧洲日韩av| 亚洲大片一区二区三区| 韩国一区二区视频| av中文字幕亚洲| 欧美久久久久久蜜桃| 久久色视频免费观看| 国产成人免费在线视频| 91丨porny丨在线| 欧美一区二区三区喷汁尤物| 国产人成一区二区三区影院| 亚洲一区二区视频在线观看| 国产一区 二区 三区一级| 91啦中文在线观看| 精品美女被调教视频大全网站| 亚洲欧美在线高清| 麻豆精品新av中文字幕| 色婷婷综合久色| 欧美精品一区二区三区蜜桃视频| 亚洲女同ⅹxx女同tv| 黄色日韩网站视频| 欧美亚洲动漫另类| 国产精品网曝门| 日本va欧美va精品发布| 91尤物视频在线观看| 精品国产3级a| 亚洲国产视频在线| 波多野结衣亚洲一区| 日韩欧美一区二区不卡| 一二三四社区欧美黄| 国产盗摄一区二区三区| 51精品秘密在线观看| 亚洲日本青草视频在线怡红院| 久久99国产精品麻豆| 精品污污网站免费看| 国产精品网站在线观看| 久久超级碰视频| 欧美日韩高清在线| 亚洲久本草在线中文字幕| 国产乱国产乱300精品| 7777精品伊人久久久大香线蕉 | 亚洲尤物视频在线| 欧美成人精品高清在线播放| 亚洲乱码中文字幕| 懂色一区二区三区免费观看| 日韩久久久久久| 偷拍日韩校园综合在线| 色欧美片视频在线观看在线视频| 国产欧美视频一区二区三区| 麻豆国产精品777777在线| 欧美日韩性生活| 尤物视频一区二区| av影院午夜一区| 国产欧美精品一区二区三区四区 | 精品久久久久久久久久久久久久久久久| 亚洲品质自拍视频| 成人免费毛片片v| 久久久午夜精品理论片中文字幕| 蜜臀av性久久久久av蜜臀妖精 | 亚洲国产欧美另类丝袜| av一区二区不卡| 国产精品国产自产拍在线| 国产aⅴ精品一区二区三区色成熟| 欧美成人一区二区三区片免费 | 欧美videos大乳护士334| 午夜精品一区二区三区免费视频| 91色综合久久久久婷婷| 亚洲欧洲制服丝袜| 91毛片在线观看| 伊人色综合久久天天| 91美女片黄在线观看91美女| 亚洲色图在线播放| 色婷婷精品大在线视频| 亚洲柠檬福利资源导航| 色综合天天综合给合国产| ㊣最新国产の精品bt伙计久久| 波多野结衣精品在线| 一色桃子久久精品亚洲| 91麻豆6部合集magnet| 一区二区三区国产精华| 精品视频1区2区3区| 五月婷婷色综合| 欧美一区二区福利视频| 美女一区二区三区| 亚洲国产成人高清精品| 欧美一区二区三区在| 麻豆精品在线播放| 久久久精品综合| 成人精品亚洲人成在线| 亚洲欧美福利一区二区| 欧美日韩在线综合| 麻豆国产精品官网| 国产精品毛片大码女人| 色综合亚洲欧洲| 香蕉加勒比综合久久| 欧美久久一二三四区| 麻豆精品一区二区综合av| 国产女人18毛片水真多成人如厕 | 久久综合狠狠综合| 国产福利一区二区三区视频在线| 国产精品久久久久影院色老大| 91婷婷韩国欧美一区二区| 洋洋成人永久网站入口| 日韩一区二区三区在线观看| 国产一区免费电影| 亚洲男同性恋视频| 欧美一区二视频| 丁香激情综合国产| 一区二区三区高清在线| 337p日本欧洲亚洲大胆精品| a美女胸又www黄视频久久| 亚洲成av人片在线| 久久综合av免费| 色偷偷成人一区二区三区91| 日本系列欧美系列| 国产精品青草综合久久久久99| 在线中文字幕一区| 狠狠色狠狠色综合系列| 亚洲乱码中文字幕| 久久只精品国产| 欧美日韩中文字幕精品| 风间由美性色一区二区三区| 亚洲午夜三级在线| 国产亚洲成aⅴ人片在线观看| 在线看不卡av| 国产精品一区2区| 亚洲成国产人片在线观看| 国产清纯白嫩初高生在线观看91 | 色婷婷精品久久二区二区蜜臂av| 日韩精品1区2区3区| 中文字幕不卡在线观看| 欧美精品在线一区二区三区| 成人手机电影网| 久久99精品久久只有精品| 亚洲最新视频在线观看| 国产日韩精品久久久| 欧美丰满美乳xxx高潮www| 波多野结衣欧美| 国产乱人伦偷精品视频不卡| 日日夜夜精品视频天天综合网| 中文字幕在线视频一区| 欧美成人猛片aaaaaaa| 欧美日韩情趣电影| 91污在线观看| 国产精品一级黄| 欧美aaa在线| 亚洲国产成人av好男人在线观看| 欧美国产激情一区二区三区蜜月 | 国产sm精品调教视频网站| 秋霞成人午夜伦在线观看| 中文字幕一区二区三区不卡 | 不卡一卡二卡三乱码免费网站| 日韩av中文字幕一区二区三区| 亚洲乱码日产精品bd| 中文字幕精品—区二区四季| 精品日韩欧美在线| 7777精品伊人久久久大香线蕉超级流畅| 91免费版在线| 成人99免费视频| 国产99一区视频免费 | 国产精品久久久久影院色老大| 精品国免费一区二区三区| 在线播放中文一区| 欧美亚洲免费在线一区| 99久久国产综合精品麻豆| 国产成人免费网站| 国产一区二区三区久久悠悠色av| 免播放器亚洲一区| 肉丝袜脚交视频一区二区| 亚洲成av人片观看| 亚洲影院在线观看| 一区二区三区欧美久久| 亚洲男女毛片无遮挡| 中文字幕一区在线观看| 亚洲国产成人午夜在线一区| 久久综合久久久久88| 久久久久国产免费免费| 日日摸夜夜添夜夜添亚洲女人| 一区二区三区成人| 亚洲制服欧美中文字幕中文字幕| 亚洲欧美一区二区三区久本道91| 亚洲欧美激情在线| 伊人夜夜躁av伊人久久| 亚洲一区二区影院| 日韩成人一级片| 男人操女人的视频在线观看欧美| 蜜臀久久99精品久久久久久9| 免费高清不卡av| 久久成人麻豆午夜电影| 国产一区二区在线观看视频| 国产精品综合一区二区| 福利电影一区二区三区| 不卡av电影在线播放| 日本久久一区二区| 欧美日韩在线一区二区| 在线不卡免费av| 久久久久久久久久久久久久久99| 国产女人aaa级久久久级 |