Linux-0.11 文件系統(tǒng)file_dev.c詳解
模塊簡介
該文件主要提供了普通文件的讀寫方法file_read和file_write,這兩個函數(shù)在系統(tǒng)調(diào)用_sys_read和sys_write中被調(diào)用。
函數(shù)詳解
file_read
int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
該函數(shù)是文件讀的函數(shù)。
首先定義了一些參數(shù),這里不做介紹,下面用到時,再詳解。
int left,chars,nr;
struct buffer_head * bh;
接著進行參數(shù)的校驗, 如果入?yún)ount等于0, 代表不讀任何數(shù)據(jù),則直接返回0。
if ((left=count)<=0)
return 0;
接下來,只要left值不為0,那么首先調(diào)用bmap函數(shù)(inode.c)獲取當(dāng)前文件指針指向的數(shù)據(jù)塊磁盤上的位置nr(nr是絕對位置)。得到nr值之后,調(diào)用bread函數(shù)讀取一個盤塊的數(shù)據(jù)到bh塊中。
while (left) {
if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) {
if (!(bh=bread(inode->i_dev,nr)))
break;
} else
bh = NULL;
接下來計算文件指針指向的數(shù)據(jù)塊中還剩下多少內(nèi)容,將其和left相比,計算出兩者較小值賦值給chars。接著將文件指針加上chars,將left減去chars。
nr = filp->f_pos % BLOCK_SIZE;
chars = MIN( BLOCK_SIZE-nr , left );
filp->f_pos += chars;
left -= chars;
接下來便開始本輪的文件讀,調(diào)用put_fs_bytes拷貝數(shù)據(jù)到buf中。本輪讀寫之后,如果left不為0,則還會進入下一輪循環(huán)。
if (bh) {
char * p = nr + bh->b_data;
while (chars-->0)
put_fs_byte(*(p++),buf++);
brelse(bh);
} else {
while (chars-->0)
put_fs_byte(0,buf++);
}
程序運行到此,代表已經(jīng)讀完了要讀的數(shù)據(jù)。最后修改了文件的atime屬性。返回讀取的字節(jié)數(shù)。
inode->i_atime = CURRENT_TIME;//更新訪問時間
return (count-left)?(count-left):-ERROR;
file_write
int file_write(struct m_inode * inode, struct file * filp, char * buf, int count)
該函數(shù)是文件寫的函數(shù)。
首先定義了一些參數(shù),這里不做介紹,下面用到時,再詳解。
off_t pos;
int block,c;
struct buffer_head * bh;
char * p;
int i=0;
當(dāng)flag中設(shè)置了O_APPEND
參數(shù)時,將pos指針指向文件尾。否則指向當(dāng)前文件指針的位置。
if (filp->f_flags & O_APPEND)
pos = inode->i_size;
else
pos = filp->f_pos;
接下來,當(dāng)i小于count時進入循環(huán),首先調(diào)用create_block從磁盤上獲取一個邏輯塊號,調(diào)用bread將磁盤塊中的內(nèi)容拷貝到bh中。
while (i<count) {
if (!(block = create_block(inode,pos/BLOCK_SIZE)))//該block是絕對位置
break;
if (!(bh=bread(inode->i_dev,block)))
break;
對于當(dāng)前的邏輯塊,其已經(jīng)寫 pos % BLOCK_SIZE個字節(jié), 其距離數(shù)據(jù)塊的末尾還有(BLOCK_SIZE - c)個字節(jié)。
c = pos % BLOCK_SIZE;
p = c + bh->b_data;
bh->b_dirt = 1;
c = BLOCK_SIZE-c;//當(dāng)前數(shù)據(jù)塊還剩多少空間
if (c > count-i) c = count-i;
pos += c;
if (pos > inode->i_size) {
inode->i_size = pos;
inode->i_dirt = 1;
}
i += c;
最后調(diào)用get_fs_bytes指針將buf中的數(shù)據(jù)拷貝到bh塊中。
while (c-->0)
*(p++) = get_fs_byte(buf++);
brelse(bh);
程序的最后,更新i節(jié)點的m_time。如果本次操作不是在文件尾添加數(shù)據(jù),則將讀寫指針調(diào)整到當(dāng)前讀寫位置pos處。修改i節(jié)點的change time為當(dāng)前時間。
inode->i_mtime = CURRENT_TIME;
if (!(filp->f_flags & O_APPEND)) {
filp->f_pos = pos;
inode->i_ctime = CURRENT_TIME;
}
Q & A
1.i_atime/i_ctime/i_mtime的區(qū)別是什么?
i_atime:文件最后訪問時間,即是文件最后的讀取時間,例如:用命令cat filename
,此時間修改,其他兩個時間不修改。
i_ctime:結(jié)點最后修改時間,即是修改inode結(jié)構(gòu)的時間,例如:用命令ln filename1 filename2
,此時間修改,其他兩個時間不修改。文章來源:http://www.zghlxwxcb.cn/news/detail-464694.html
i_mtime:文件最后修改時間,即是對文件內(nèi)容的修改時間,例如:用命令echo aaa >filename
,以上三個時間都修改。文章來源地址http://www.zghlxwxcb.cn/news/detail-464694.html
到了這里,關(guān)于Linux-0.11 文件系統(tǒng)file_dev.c詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!