1
#只看該作者 |
倒序看帖 |
列印
1 引言
很詳細地了解某個作業系統的實際工作方式是非常困難的,因為大多數作業系統的源**都是嚴格保密的。在以實際使用為目標的作業系統中,讓任何人都可以自由獲取系統源**,無論目的是要了解、學習還是修改,這樣的系統並不多。本**的主題就是這些少數作業系統中的乙個:linux。
linux是乙個效能穩定、功能強大、效率高的作業系統。它在功能特性方面與unix系統相似,同時又具有多工、多使用者、多平台等若干特性。linux的源**是開放的,閱讀linux源**,無疑是深入學習linux的最好方法。
檔案系統是linux作業系統的重要組成部分,linux檔案具有強大的功功能。檔案系統中的檔案是資料的集合,檔案系統不僅包含著檔案中的資料而且還有檔案系統的結構,所有linux 使用者和程式看到的檔案、目錄、軟連線及檔案保護資訊等都儲存在其中。
linux 最早的檔案系統是minix,但是專門為linux 設計的檔案系統——擴充套件檔案系統第二版或ext2被設計出來並新增到linux中,這對linux產生了重大影響。ext2檔案系統功能強大、易擴充、效能上進行了全面優化優化,也是現在所以linux發布和安裝的標準檔案系統型別。
每個實際檔案系統從作業系統和系統服務中分離出來,它們之間通過乙個介面層:虛擬檔案系統或vfs來通訊。vfs使得linux可以支援多個不同的檔案系統,每個表示乙個vfs 的通用介面。由於軟體將linux 檔案系統的所有細節進行了轉換,所以linux核心的其它部分及系統中執行的程式將看到統一的檔案系統。linux 的虛擬檔案系統允許使用者同時能透明地安裝許多不同的檔案系統。
在linux檔案系統中,作為一種特殊型別/proc檔案系統只存在記憶體當中,而不占用外存空間。它以檔案系統的方式為訪問系統核心資料的操作提供介面。/proc檔案系統是乙個偽檔案系統,使用者和應用程式可以通過/proc得到系統的資訊,並可以改變核心的某些引數。
在linux檔案系統中,ext2檔案系統、虛擬檔案系統、/proc檔案系統是三個具有代表性的檔案系統,本**試圖通過對他們的分析來研究linux檔案系統機制。並且在分析這三種檔案系統的基礎上對linux檔案系統操作進行了解、研究(本**選取了open和close兩種操作進行研究)。在第二部分中將介紹ext2檔案系統;第三部分論述虛擬檔案系統的特點;第四部分簡要介紹/proc檔案系統;最後,介紹兩種具體檔案系統操作的實現。
2ext2檔案系統filp_open(tmp, flags, mode);
/* 呼叫filp_open(),獲取檔案對應的filp結構。*/
error = ptr_err(f);
if (is_err(f))
goto out_error;
/* 如果所獲file結構有錯誤,跳到out_error處釋放檔案描述符,返回出錯。*/
fd_install(fd, f);
/* 呼叫fd_install()將開啟檔案的file結構裝入當前程序開啟檔案表中。*/
}out:
putname(tmp);
}return fd;
out_error:
put_unused_fd(fd);
fd = error;
goto out;
}int get_unused_fd(void)
goto out;
}/*
* check whether we need to expand the fd array.
*/if (fd >= files->max_fds)
goto out;
}fd_set(fd, files->open_fds);
/* 將files->open_fds中相應的fd位置位。*/
fd_clr(fd, files->close_on_exec);
/* 清除files->close_on_exec中的相應位。*/
files->next_fd = fd + 1;
#if 1
/* sanity check */
if (files->fd[fd] != null)
#endif
error = fd;
out:
write_unlock(&files->file_lock);
return error;
}struct file *filp_open(const char * filename, int flags, int mode)
呼叫dentry_open(),通過open_namei得到dentry與vfsmount來得到file結構。
struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
f->f_dentry = dentry;
/ *對file結構中的相關項賦值。*/
f->f_vfsmnt = mnt;
f->f_pos = 0;
f->f_reada = 0;
f->f_op = fops_get(inode->i_fop);
file_move(f, &inode->i_sb->s_files);
/* 將file結構掛到超級塊開啟檔案鍊錶上。*/
/* preallocate kiobuf for o_direct */
f->f_iobuf = null;
f->f_iobuf_lock = 0;
if (f->f_flags & o_direct)
if (f->f_op && f->f_op->open)
f->f_flags &= ~(o_creat | o_excl | o_noctty | o_trunc);
/* 改變file結構的標誌項。*/
return f;
cleanup_all:
if (f->f_iobuf)
free_kiovec(1, &f->f_iobuf);
fops_put(f->f_op);
if (f->f_mode & fmode_write)
put_write_access(inode);
file_move(f, &kill_list); /* out of the way.. */
f->f_dentry = null;
f->f_vfsmnt = null;
cleanup_file:
put_filp(f);
cleanup_dentry:
dput(dentry);
mntput(mnt);
return err_ptr(error);
}open操作用到的主要函式的呼叫關係結構如下圖所示
sys_open
get_unused_fd
file_open
fd_install
open_namei
dentry_open
path_walk
real_lookup
圖65.2 close操作
關閉檔案時要呼叫sys_close()來實現。關閉開啟的檔案描述符, int close (unsigned int fd),函式呼叫成功返回0值,否則返回-1值。由errno存放錯誤編號ebad表示引數是乙個有效的開啟的檔案描述符。
系統呼叫open()開啟乙個檔案時系統就分配給檔案乙個檔案描述符,同時為開啟檔案描述符的引用計數加1。呼叫close()關閉檔案時開啟檔案描述符的引用計數減1。引用計數為0時才徹底關閉開啟的檔案。
具體實現如下:
asmlinkage long sys_close(unsigned int fd)
int filp_close(struct file *filp, fl_owner_t id)
retval = 0;
if (filp->f_op && filp->f_op->flush)
/* 如果檔案系統有自己的操作函式flush,那直接呼叫該函式。在這個操作時要設定核心鎖。*/
fcntl_dirnotify(0, filp, 0);
locks_remove_posix(filp, id);
fput(filp);
/* 呼叫fput()釋放檔案對應的file結構。*/
return retval;
}void fput(struct file * file)
}void dput(struct dentry *dentry)
ext2檔案系統
ext2磁碟結構 ext2分割槽和ext2分組的分布圖 下圖是借用其他部落格的 塊組中的每個塊包含的資訊 超級快 1個塊 描述該分割槽中的整個檔案系統的資訊,包括有多少個快組,每個快組有多少個塊,多少個索引節點等。組描述符塊 n塊 塊點陣圖 1塊 索引節點位圖 1塊 索引節點 n塊 資料塊 n塊 塊...
Ext2檔案系統
ext2檔案系統的總體布局,如下圖。1檔案系統的最小儲存單元是塊 block 塊的大小一般為512bytes,或者是它的整數倍,塊的大小是在格式化是所確定的。不能修改除非重新格式化。上圖中顯示了檔案系統的總體布局,由乙個boot block和對個block group組成,每個block group...
linux檔案系統 ext2檔案系統
如何快速高效的尋到在硬碟儲存的資料,於是檔案系統就誕生了。檔案系統是邏輯層面的,那麼檔案系統是如何管理 件層提供的磁碟空間的?現在,大部分檔案系統採用索引分配方案 優點 1.能夠保持好大部分檔案的區域性性 2.滿足檔案插入,刪除的高效 3.隨機讀寫不需要沿著指標前行 缺點1.會有較多的磁碟尋道次數 ...