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