?? block_dev.c
字號:
/* passed * linux/fs/block_dev.c * * (C) 1991 Linus Torvalds
* * block_dev.c 程序?qū)儆趬K設(shè)備文件數(shù)據(jù)訪問操作類程序。該文件包括block_read()和
* block_write()兩個塊設(shè)備讀寫函數(shù)。這兩個函數(shù)是供系統(tǒng)調(diào)用函數(shù)read()和write()調(diào)用的,
* 其它地方?jīng)]有引用。
*/#include <set_seg.h>
// 錯誤號頭文件。包含系統(tǒng)中各種出錯號。(Linus 從minix 中引進的)。#include <errno.h>
// 調(diào)度程序頭文件,定義了任務(wù)結(jié)構(gòu)task_struct、初始任務(wù)0 的數(shù)據(jù),
// 還有一些有關(guān)描述符參數(shù)設(shè)置和獲取的嵌入式匯編函數(shù)宏語句。#include <linux/sched.h>
// 內(nèi)核頭文件。含有一些內(nèi)核常用函數(shù)的原形定義。#include <linux/kernel.h>
// 段操作頭文件。定義了有關(guān)段寄存器操作的嵌入式匯編函數(shù)。#include <asm/segment.h>
// 系統(tǒng)頭文件。定義了設(shè)置或修改描述符/中斷門等的嵌入式匯編宏。#include <asm/system.h>
//// 數(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ù)寫盤(即交由高速緩沖程序去處理)。int block_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ù)塊,并預(yù)讀
// 下兩塊數(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ū)復(fù)制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ù)到高速緩沖中。int block_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ù)塊,并預(yù)讀下兩塊數(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 指向的開始位置復(fù)制chars 字節(jié)數(shù)據(jù)到用戶緩沖區(qū),并釋放該高速緩沖區(qū)。 while (chars-->0) put_fs_byte(*(p++),buf++); brelse(bh); } return read; // 返回已讀取的字節(jié)數(shù),正常退出。}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -