?? block_dev.c
字號:
/** linux/fs/block_dev.c** (C) 1991 Linus Torvalds*/#include <errno.h> // 錯誤號頭文件。包含系統(tǒng)中各種出錯號。(Linus 從minix 中引進的)。#include <linux/sched.h> // 調(diào)度程序頭文件,定義了任務(wù)結(jié)構(gòu)task_struct、初始任務(wù)0 的數(shù)據(jù),// 還有一些有關(guān)描述符參數(shù)設(shè)置和獲取的嵌入式匯編函數(shù)宏語句。#include <linux/kernel.h> // 內(nèi)核頭文件。含有一些內(nèi)核常用函數(shù)的原形定義。#include <asm/segment.h> // 段操作頭文件。定義了有關(guān)段寄存器操作的嵌入式匯編函數(shù)。#include <asm/system.h> // 系統(tǒng)頭文件。定義了設(shè)置或修改描述符/中斷門等的嵌入式匯編宏。//// 數(shù)據(jù)塊寫函數(shù) - 向指定設(shè)備從給定偏移處寫入指定長度字節(jié)數(shù)據(jù)。// 參數(shù):dev - 設(shè)備號;pos - 設(shè)備文件中偏移量指針;buf - 用戶地址空間中緩沖區(qū)地址;// count - 要傳送的字節(jié)數(shù)。// 對于內(nèi)核來說,寫操作是向高速緩沖區(qū)中寫入數(shù)據(jù),什么時候數(shù)據(jù)最終寫入設(shè)備是由高速緩沖管理// 程序決定并處理的。另外,因為設(shè)備是以塊為單位進行讀寫的,因此對于寫開始位置不處于塊起始// 處時,需要先將開始字節(jié)所在的整個塊讀出,然后將需要寫的數(shù)據(jù)從寫開始處填寫滿該塊,再將完// 整的一塊數(shù)據(jù)寫盤(即交由高速緩沖程序去處理)。intblock_write (int dev, long *pos, char *buf, int count){// 由pos 地址換算成開始讀寫塊的塊序號block。并求出需讀第1 字節(jié)在該塊中的偏移位置offset。 int block = *pos >> BLOCK_SIZE_BITS; int offset = *pos & (BLOCK_SIZE - 1); int chars; int written = 0; struct buffer_head *bh; register char *p;// 針對要寫入的字節(jié)數(shù)count,循環(huán)執(zhí)行以下操作,直到全部寫入。 while (count > 0) {// 計算在該塊中可寫入的字節(jié)數(shù)。如果需要寫入的字節(jié)數(shù)填不滿一塊,則只需寫count 字節(jié)。 chars = BLOCK_SIZE - offset; if (chars > count) chars = count;// 如果正好要寫1 塊數(shù)據(jù),則直接申請1 塊高速緩沖塊,否則需要讀入將被修改的數(shù)據(jù)塊,并預讀// 下兩塊數(shù)據(jù),然后將塊號遞增1。 if (chars == BLOCK_SIZE) bh = getblk (dev, block); else bh = breada (dev, block, block + 1, block + 2, -1); block++;// 如果緩沖塊操作失敗,則返回已寫字節(jié)數(shù),如果沒有寫入任何字節(jié),則返回出錯號(負數(shù))。 if (!bh) return written ? written : -EIO;// p 指向讀出數(shù)據(jù)塊中開始寫的位置。若最后寫入的數(shù)據(jù)不足一塊,則需從塊開始填寫(修改)所需// 的字節(jié),因此這里需置offset 為零。 p = offset + bh->b_data; offset = 0;// 將文件中偏移指針前移已寫字節(jié)數(shù)。累加已寫字節(jié)數(shù)chars。傳送計數(shù)值減去此次已傳送字節(jié)數(shù)。 *pos += chars; written += chars; count -= chars;// 從用戶緩沖區(qū)復制chars 字節(jié)到p 指向的高速緩沖區(qū)中開始寫入的位置。 while (chars-- > 0) *(p++) = get_fs_byte (buf++);// 置該緩沖區(qū)塊已修改標志,并釋放該緩沖區(qū)(也即該緩沖區(qū)引用計數(shù)遞減1)。 bh->b_dirt = 1; brelse (bh); } return written; // 返回已寫入的字節(jié)數(shù),正常退出。}//// 數(shù)據(jù)塊讀函數(shù) - 從指定設(shè)備和位置讀入指定字節(jié)數(shù)的數(shù)據(jù)到高速緩沖中。intblock_read (int dev, unsigned long *pos, char *buf, int count){// 由pos 地址換算成開始讀寫塊的塊序號block。并求出需讀第1 字節(jié)在該塊中的偏移位置offset。 int block = *pos >> BLOCK_SIZE_BITS; int offset = *pos & (BLOCK_SIZE - 1); int chars; int read = 0; struct buffer_head *bh; register char *p;// 針對要讀入的字節(jié)數(shù)count,循環(huán)執(zhí)行以下操作,直到全部讀入。 while (count > 0) {// 計算在該塊中需讀入的字節(jié)數(shù)。如果需要讀入的字節(jié)數(shù)不滿一塊,則只需讀count 字節(jié)。 chars = BLOCK_SIZE - offset; if (chars > count) chars = count;// 讀入需要的數(shù)據(jù)塊,并預讀下兩塊數(shù)據(jù),如果讀操作出錯,則返回已讀字節(jié)數(shù),如果沒有讀入任何// 字節(jié),則返回出錯號。然后將塊號遞增1。 if (!(bh = breada (dev, block, block + 1, block + 2, -1))) return read ? read : -EIO; block++;// p 指向從設(shè)備讀出數(shù)據(jù)塊中需要讀取的開始位置。若最后需要讀取的數(shù)據(jù)不足一塊,則需從塊開始// 讀取所需的字節(jié),因此這里需將offset 置零。 p = offset + bh->b_data; offset = 0;// 將文件中偏移指針前移已讀出字節(jié)數(shù)chars。累加已讀字節(jié)數(shù)。傳送計數(shù)值減去此次已傳送字節(jié)數(shù)。 *pos += chars; read += chars; count -= chars;// 從高速緩沖區(qū)中p 指向的開始位置復制chars 字節(jié)數(shù)據(jù)到用戶緩沖區(qū),并釋放該高速緩沖區(qū)。 while (chars-- > 0) put_fs_byte (*(p++), buf++); brelse (bh); } return read; // 返回已讀取的字節(jié)數(shù),正常退出。}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -