《計(jì)算機(jī)操作系統(tǒng) 》課件-6.7Linux文件系統(tǒng)_第1頁(yè)
《計(jì)算機(jī)操作系統(tǒng) 》課件-6.7Linux文件系統(tǒng)_第2頁(yè)
《計(jì)算機(jī)操作系統(tǒng) 》課件-6.7Linux文件系統(tǒng)_第3頁(yè)
《計(jì)算機(jī)操作系統(tǒng) 》課件-6.7Linux文件系統(tǒng)_第4頁(yè)
《計(jì)算機(jī)操作系統(tǒng) 》課件-6.7Linux文件系統(tǒng)_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Linux文件系統(tǒng)概述

虛擬文件系統(tǒng)VFS

文件系統(tǒng)的注冊(cè)、安裝和卸載Linux文件系統(tǒng)對(duì)文件的操作Ext2文件系統(tǒng)6.7Linux文件系統(tǒng)

6.7.1

Linux文件系統(tǒng)概述1.Linux的文件類型(1)普通文件:又稱為常規(guī)文件,存放用戶及操作系統(tǒng)的程序代碼、數(shù)據(jù)等信息。(2)目錄文件:存放所有文件的目錄項(xiàng)。(3)設(shè)備文件:所有的外部設(shè)備都當(dāng)作文件來(lái)看待,每個(gè)設(shè)備都對(duì)應(yīng)一個(gè)設(shè)備文件。(4)管道文件:為支持管道通信機(jī)制設(shè)置,又稱為FIFO文件。(5)符號(hào)鏈接文件:實(shí)現(xiàn)基于符號(hào)鏈接的文件共享機(jī)制。(6)Socket文件:用于實(shí)現(xiàn)Socket通信機(jī)制的文件。

6.7Linux文件系統(tǒng)

6.7.1

Linux文件系統(tǒng)概述2.Linux的文件存取權(quán)限Linux系統(tǒng)把文件的用戶分成3類:文件主、同組用戶和其他普通用戶,然后針對(duì)每個(gè)文件分別對(duì)3類用戶設(shè)置訪問(wèn)權(quán)限,權(quán)限包括三種操作:可讀R、可寫(xiě)W和執(zhí)行X。

6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS1.VFS支持的文件系統(tǒng)類型VFS(VirtualFileSystem,簡(jiǎn)稱VFS)作為一個(gè)通用文件系統(tǒng)模型(CommonFileModel),它把不同文件系統(tǒng)抽象后采用統(tǒng)一方式進(jìn)行操作。(1)磁盤(pán)文件系統(tǒng)Linux使用的文件系統(tǒng),例如Ext2、Ext3和ReiserFS。Unix家族的文件系統(tǒng),例如sysv、UFS、MINIX和VERITASVxFS。

微軟公司的文件系統(tǒng),例如MS-DOS、VFAT和NTFS。

其它文件系統(tǒng),例如HPFS、HFS、AFFS和ADFS。(2)網(wǎng)絡(luò)文件系統(tǒng)

NFS、Coda、AFS、CIFS以及NCP。(3)特殊文件系統(tǒng)

/proc6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS2.VFS的實(shí)現(xiàn)模型6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS3.VFS的主要對(duì)象類型(1)超級(jí)塊對(duì)象(superblockobject)存放系統(tǒng)中已安裝文件系統(tǒng)的有關(guān)信息,每個(gè)文件系統(tǒng)一個(gè),是各種具體文件系統(tǒng)在安裝時(shí)建立的,只存在于內(nèi)存中。(2)索引節(jié)點(diǎn)對(duì)象(inodeobject)存放關(guān)于具體文件的一般信息。每個(gè)打開(kāi)文件都有一個(gè)索引節(jié)點(diǎn)對(duì)象。(3)目錄項(xiàng)對(duì)象(dentryobject)存放目錄項(xiàng)與對(duì)應(yīng)文件進(jìn)行鏈接的信息。(4)文件對(duì)象(fileobject)存放打開(kāi)文件與進(jìn)程之間進(jìn)行交互的有關(guān)信息。這類信息僅當(dāng)進(jìn)程訪問(wèn)文件期間存在于內(nèi)存中。6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS3.VFS的主要對(duì)象類型

進(jìn)程和以上VFS對(duì)象之間的關(guān)系6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS4.VFS主要對(duì)象的數(shù)據(jù)結(jié)構(gòu),主要參考linux2.6.24內(nèi)核版本。

(1)超級(jí)塊對(duì)象超級(jí)塊對(duì)象由super_block結(jié)構(gòu)來(lái)描述(定義在文件/include/linux/fs.h中),主要數(shù)據(jù)結(jié)構(gòu)如下:structsuper_block{s_list:超級(jí)塊鏈表的指針s_dev:超級(jí)塊所在的設(shè)備描述符s_blocksize和s_blocksize_bits:指定磁盤(pán)文件系統(tǒng)的塊大小s_dirt:超級(jí)塊的“臟”位s_maxbytes:文件的最大長(zhǎng)度s_type:指向文件系統(tǒng)類型的指針s_op:指向超級(jí)塊操作集的指針s_root:指向根目錄的dentry對(duì)象s_dirty:表示“臟”(內(nèi)容被修改但尚未被刷新到磁盤(pán))的inode節(jié)點(diǎn)的鏈表s_fs_info:指向該文件系統(tǒng)私有數(shù)據(jù),一般是各文件系統(tǒng)對(duì)應(yīng)的超級(jí)塊信息。}6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS4.VFS主要對(duì)象的數(shù)據(jù)結(jié)構(gòu),主要參考linux2.6.24內(nèi)核版本。

(1)超級(jí)塊對(duì)象超級(jí)塊操作集由一組對(duì)超級(jí)塊進(jìn)行的相關(guān)操作的函數(shù)指針組成,使用super_operations結(jié)構(gòu)來(lái)描述,定義在文件/include/linux/fs.h中:structsuper_operations{viod(*read_inode)(structinode*);//讀取文件inodeviod(*write_inode)(structinode*,int);//寫(xiě)回inodeviod(*put_inode)(structinode*);//邏輯上釋放inodeviod(*delete_inode)(structinode*);//物理上釋放inodeviod(*put_super)(structsuper_block*);//釋放超級(jí)塊對(duì)象viod(*write_super)(structsuper_block*);//把超級(jí)塊信息寫(xiě)回磁盤(pán)

…}6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS4.VFS主要對(duì)象的數(shù)據(jù)結(jié)構(gòu),主要參考linux2.6.24內(nèi)核版本。

(2)索引節(jié)點(diǎn)對(duì)象索引節(jié)點(diǎn)對(duì)象由inode結(jié)構(gòu)來(lái)描述,定義在文件/include/linux/fs.h中:structinode{i_hash:已經(jīng)分配好的inode雙向鏈表i_list:未分配的inode資源的雙向鏈表i_dentry:dentry的鏈表,當(dāng)多個(gè)dentry指向同一個(gè)inode時(shí),通過(guò)identry將這些dentry連接起來(lái)。i_ino:inode的編號(hào)i_count:當(dāng)前inode的引用計(jì)數(shù)器i_blksize和i_blocks:表明文件系統(tǒng)塊的大小以及當(dāng)前的文件占用多少個(gè)塊i_version:版本塊i_op:指向inode的操作i_fop:inode所代表的文件的操作函數(shù)i_sb:指向當(dāng)前的超級(jí)塊i_flock:對(duì)當(dāng)前的文件所加的文件鎖i_state:當(dāng)前inode的狀態(tài),當(dāng)i_state為I_DIRTY時(shí),表示inode已“臟”,也就是數(shù)據(jù)已經(jīng)被修改過(guò),那么磁盤(pán)的inode需要寫(xiě)回至磁盤(pán)中更新?!瓆6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS4.VFS主要對(duì)象的數(shù)據(jù)結(jié)構(gòu),主要參考linux2.6.24內(nèi)核版本。

(3)目錄項(xiàng)對(duì)象目錄項(xiàng)對(duì)象由dentry結(jié)構(gòu)描述,定義在文件/include/linux/dcache.h中:structdentry{d_count:當(dāng)前dentry的引用數(shù)d_flags:dentry的標(biāo)志,用來(lái)標(biāo)識(shí)出dentry的狀態(tài)d_inode:與此dentry相對(duì)應(yīng)的inode,可以為空d_hash:作為接口鏈入dentry的哈希表d_parent:父目錄的dentry結(jié)構(gòu)。但對(duì)于根節(jié)點(diǎn),該指針指回自己d_name:包含了該dentry的名稱以及hash值d_lru:作為接口為引用數(shù)為零的dentry結(jié)構(gòu)構(gòu)成一個(gè)雙向鏈表。d_child:該雙向鏈表包含所有該dentry的d_parent的兒子,也就是該dentry的所有兄弟。d_subdirs:該雙向鏈表包含所有該dentry的兒子d_alias:在文件系統(tǒng)中可以通過(guò)硬連接使幾個(gè)不同的文件名指向同一個(gè)文件,這就使多個(gè)dentry指向同一個(gè)inode。d_time:為d_revalidate使用,作時(shí)間記錄d_op:一組dentry的操作函數(shù)d_sb:指向該dentry所在的超級(jí)塊d_mounted:當(dāng)前的目錄項(xiàng)被mount的次數(shù),由于內(nèi)核允許一個(gè)目錄被mount多次,所以需要記錄當(dāng)前目錄被mount的情況d_iname:保存文件名的前36個(gè)字符,適合短名字的目錄項(xiàng)。}6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS4.VFS主要對(duì)象的數(shù)據(jù)結(jié)構(gòu),主要參考linux2.6.24內(nèi)核版本。

(4)文件對(duì)象文件對(duì)象由file結(jié)構(gòu)描述,定義在文件/include/linux/fs.h中:structfile{fu_list:文件對(duì)象鏈表指針f_dentry:文件相對(duì)應(yīng)的dentry結(jié)構(gòu)f_vfsmnt:文件相對(duì)應(yīng)的vfsmount結(jié)構(gòu)f_op:文件操作函數(shù)集的指針f_count:文件打開(kāi)的引用計(jì)數(shù)f_flags:文件標(biāo)志,如O_RDONLY、O_NONBLOCK、O_SYNCf_mode:文件的讀寫(xiě)權(quán)限,在打開(kāi)文件的時(shí)候根據(jù)這個(gè)屬性來(lái)判斷是否進(jìn)程有讀寫(xiě)該文件的能力f_ops:文件指針的位置f_owner:進(jìn)程id和發(fā)送給該進(jìn)程的信號(hào)f_uid,f_gid:打開(kāi)文件的進(jìn)程的uid和gidprivate_data:每個(gè)文件的私有數(shù)據(jù)區(qū),為文件系統(tǒng)或設(shè)備驅(qū)動(dòng)程序使用。}6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS5.進(jìn)程中與文件相關(guān)的數(shù)據(jù)結(jié)構(gòu)進(jìn)程描述符task_struct結(jié)構(gòu)中與文件相關(guān)的字段有fs_struct和files_struct兩項(xiàng)信息,其中fs_struct結(jié)構(gòu)用來(lái)記錄進(jìn)程工作時(shí)的文件系統(tǒng)信息,files_struct結(jié)構(gòu)用來(lái)記錄進(jìn)程打開(kāi)的文件信息。structtask_struct(定義在文件/include/linux/sched.h中){structfs_struct*fs;//文件系統(tǒng)信息structfiles_struct*files;//打開(kāi)文件信息};structfs_struct//定義在文件/include/linux/fs_struct.h中{atomic_tcount;//用戶數(shù)目rwlock_tlock;//保護(hù)該結(jié)構(gòu)體的鎖intumask;//文件權(quán)限掩碼intin_exec;//當(dāng)前正在執(zhí)行的文件structdentry*root;//根目錄的dentrystructdentry*pwd;//當(dāng)前工作目錄的dentrystructvfsmount*rootmnt;//根目錄mount的文件系統(tǒng)信息umask=0022//初始打開(kāi)文件的權(quán)限};6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS5.進(jìn)程中與文件相關(guān)的數(shù)據(jù)結(jié)構(gòu)structfiles_struct//用戶打開(kāi)表,定義在文件/include/linux/file.h中{atomic_tcount;//結(jié)構(gòu)的使用計(jì)數(shù)/structfdtable*fdt;//文件表指針structfdtablefdtab;//文件表spinlockfile_lock;//單個(gè)文件的鎖intnext_fd;//下一個(gè)可用的文件描述符fdstructembedded_fd_setopen_fds_init;//當(dāng)前已打開(kāi)文件的文件描述符的位圖,//1024位structembedded_fd_setclose_on_exec_init;//執(zhí)行exec()時(shí)需關(guān)閉的文件描述符的//位圖structfile*fd_arry[NR_OPEN_DEFAULT];//系統(tǒng)打開(kāi)文件表數(shù)組,默認(rèn)64個(gè)};6.7Linux文件系統(tǒng)

6.7.2虛擬文件系統(tǒng)VFS6.主要數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系

進(jìn)程和文件系統(tǒng)主要數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載1.注冊(cè)文件系統(tǒng)實(shí)際上是為該文件系統(tǒng)在內(nèi)存中生成一個(gè)file_system_type結(jié)構(gòu),該結(jié)構(gòu)包含了所注冊(cè)文件系統(tǒng)的類型名稱以及讀取該文件系統(tǒng)超級(jí)塊的服務(wù)例程的指針,定義在文件/include/linux/fs.h中structfile_system_type{constchar*name;//文件系統(tǒng)類型名intfs_flags;//文件系統(tǒng)的具體特性int(*get_sb)(structfile_system_type*,int,constchar*,void*,structvfsmount*);//讀入相應(yīng)文件系統(tǒng)的超級(jí)塊的服務(wù)例程structmodule*owner;//具體可安裝模塊的module結(jié)構(gòu)structfile_system_type*next;//文件系統(tǒng)類型鏈表的下一個(gè)指針structlist_headfs_supers;//該類型文件系統(tǒng)所安裝的所有超級(jí)塊鏈表

…}

6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載1.注冊(cè)文件系統(tǒng)

內(nèi)核注冊(cè)文件系統(tǒng)有以下兩種方式:系統(tǒng)引導(dǎo)時(shí)在VFS中注冊(cè),系統(tǒng)關(guān)閉時(shí)注銷。把文件系統(tǒng)作為內(nèi)核可裝載的模塊,在實(shí)際安裝時(shí)進(jìn)行注冊(cè),并在模塊卸載時(shí)注銷。系統(tǒng)把當(dāng)前所有已經(jīng)注冊(cè)到內(nèi)核的文件系統(tǒng)的file_system_type結(jié)構(gòu)組織成一個(gè)鏈表。

6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載2.安裝文件系統(tǒng)

(1)基本原理安裝文件系統(tǒng)的主要工作是為該文件系統(tǒng)在內(nèi)存中建立一個(gè)VFS超級(jí)塊,并生成一個(gè)vfsmount結(jié)構(gòu),該結(jié)構(gòu)定義在文件/include/linux/mount.h中。structvfsmount{structlist_headmnt_hash;//哈希表的指針structvfsmount*mnt_parent;//安裝點(diǎn)所隸屬的文件系統(tǒng)

structdentry*mnt_mountpoint;//該文件系統(tǒng)安裝點(diǎn)目錄的dentrystructdentry*mnt_root;//該文件系統(tǒng)根目錄的dentrystructsuper_block*mnt_sb;//該文件系統(tǒng)的超級(jí)塊對(duì)象

structlist_headmnt_mounts;//該安裝點(diǎn)安裝的所有文件系統(tǒng)鏈表structlist_headmnt_child;//已安裝文件系統(tǒng)鏈表mnt_mounts的指針atomic_tmnt_count;//該vfsmount結(jié)構(gòu)被引用的次數(shù)intmnt_flags;//安裝選項(xiàng)char*mnt_devname;//設(shè)備文件名structlist_headmnt_list;//在vfsmount結(jié)構(gòu)鏈表中的位置}6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載2.安裝文件系統(tǒng)

(1)基本原理超級(jí)塊、安裝點(diǎn)和具體的文件系統(tǒng)的關(guān)系6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載2.安裝文件系統(tǒng)

(2)安裝命令mount文件系統(tǒng)的安裝由mount命令完成,命令格式是:mount[-tvfstype][-ooptions]devicedir例如命令:mount-tiso9660/dev/hdc/mnt/cdrom其中iso9660是文件系統(tǒng)的類型名,/dev/hdc是包含待安裝文件系統(tǒng)的物理設(shè)備,/mnt/cdrom是將要安裝到的目錄,即安裝點(diǎn)。安裝一個(gè)文件系統(tǒng)實(shí)際上是安裝一個(gè)物理設(shè)備,即將不同分區(qū)中的單獨(dú)的文件系統(tǒng)作為可裝卸模塊按一定方式形成整個(gè)樹(shù)形目錄結(jié)構(gòu)中的一個(gè)分支。若指定的安裝目錄中原本就存在文件或下級(jí)子目錄,則安裝新的文件系統(tǒng)后,該目錄下原有的文件和子目錄將被掩蓋,直到所安裝的文件系統(tǒng)卸載后,安裝目錄中原來(lái)的文件會(huì)再次出現(xiàn)。6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載2.安裝文件系統(tǒng)

6.7Linux文件系統(tǒng)

6.7.3文件系統(tǒng)的注冊(cè)、安裝和卸載3.卸載文件系統(tǒng)卸載一個(gè)文件系統(tǒng)主要應(yīng)完成如下工作:

如果文件系統(tǒng)中的文件當(dāng)前正在使用,則卸載失敗返回;

如果該文件系統(tǒng)的VFS超級(jí)塊標(biāo)志為“臟”,則必須將超級(jí)塊信息寫(xiě)回磁盤(pán);

釋放該文件系統(tǒng)的VFS超級(jí)塊;

從vfsmntlist鏈表中斷開(kāi)vfsmount數(shù)據(jù)結(jié)構(gòu),并將其釋放。6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作1.open操作在linux中,open操作是由open系統(tǒng)調(diào)用完成的;而open系統(tǒng)調(diào)用的服務(wù)例程是sys_open()(在文件/fs/open.c中實(shí)現(xiàn))。longdo_sys_open(intdfd,constchar__user*filename,intflags,intmode){ char*tmp=getname(filename); intfd=PTR_ERR(tmp); if(!IS_ERR(tmp)){ fd=get_unused_fd_flags(flags); if(fd>=0){ structfile*f=do_filp_open(dfd,tmp,flags,mode); if(IS_ERR(f)){ put_unused_fd(fd); fd=PTR_ERR(f); }else{ fsnotify_open(f->f_path.dentry); fd_install(fd,f); } } putname(tmp); } returnfd;}6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作1.open操作asmlinkagelongsys_open(constchar__user*filename,intflags,intmode){ longret; if(force_o_largefile()) flags|=O_LARGEFILE; ret=do_sys_open(AT_FDCWD,filename,flags,mode); prevent_tail_call(ret); returnret;}主要算法步驟:getname()函數(shù)做路徑名的合法性檢測(cè)。getname()在檢查名字合法性的同時(shí)要把filename從用戶數(shù)據(jù)區(qū)拷貝到內(nèi)核數(shù)據(jù)區(qū)。它會(huì)檢驗(yàn)給出的地址是否在當(dāng)前進(jìn)程中的虛存段內(nèi);在內(nèi)核空間中申請(qǐng)一頁(yè);并把filename字符的內(nèi)容拷貝到該頁(yè)中去。get_unused_fd_flags()根據(jù)flag得到空的文件描述符指針。do_filp_open()按照指定的讀寫(xiě)方式和用戶權(quán)限打開(kāi)文件,并返回文件描述符指針f。

如果所獲file結(jié)構(gòu)有錯(cuò)誤,則釋放文件描述符,設(shè)置fd為返回出錯(cuò)信息。fd_install()將打開(kāi)文件的文件描述符指針f裝入當(dāng)前進(jìn)程打開(kāi)文件表中。

返回打開(kāi)的文件描述符。6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作1.open操作staticstructfile*do_filp_open(intdfd,constchar*filename,intflags,intmode){ intnamei_flags,error; structnameidatand; namei_flags=flags; if((namei_flags+1)&O_ACCMODE) namei_flags++; error=open_namei(dfd,filename,namei_flags,mode,&nd); if(!error) returnnameidata_to_filp(&nd,flags); returnERR_PTR(error);}下面是sys_oepn流程中重要函數(shù)do_filp_open函數(shù)實(shí)現(xiàn)的分析主要算法步驟:

根據(jù)參數(shù)flags計(jì)算namei_flagsopen_namei()通過(guò)路徑名獲取其相應(yīng)的dentry和vfsmount結(jié)構(gòu)。

如果open_namei正常返回,則調(diào)用nameidata_to_filp(),通過(guò)open_namei()得到的dentry和vfsmount來(lái)得到file結(jié)構(gòu)。否則返回錯(cuò)誤信息。6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作2.close操作在Linux中,close操作是由close系統(tǒng)調(diào)用完成的。close系統(tǒng)調(diào)用的服務(wù)例程是sys_close()(在文件/fs/open.c中實(shí)現(xiàn))。下面是對(duì)sys_close函數(shù)實(shí)現(xiàn)的分析。6.7Linux文件系統(tǒng)rcu_assign_pointer(fdt->fd[fd],NULL);FD_CLR(fd,fdt->close_on_exec);__put_unused_fd(files,fd);spin_unlock(&files->file_lock);retval=filp_close(filp,files);if(unlikely(retval==-ERESTARTSYS||retval==-ERESTARTNOINTR||retval==-ERESTARTNOHAND||retval==-ERESTART_RESTARTBLOCK))retval=-EINTR;returnretval;out_unlock:spin_unlock(&files->file_lock);return-EBADF;}asmlinkagelongsys_close(unsignedintfd){ structfile*filp;structfiles_struct*files=current->files; structfdtable*fdt; intretval; spin_lock(&files->file_lock); fdt=files_fdtable(files); if(fd>=fdt->max_fds)gotoout_unlock; filp=fdt->fd[fd]; if(!filp)gotoout_unlock;

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作2.close操作主要算法步驟:

檢查所要關(guān)閉的fd的合法性,是否小于進(jìn)程可使用最大文件max_fds。如果不合法,則跳轉(zhuǎn)到out_unlock段釋放file_lock并返回。

根據(jù)fd獲得文件描述符filp指針并對(duì)filp的合法性進(jìn)行檢查。如果不合法,同樣跳轉(zhuǎn)到out_unlock段釋放file_lock并返回。

將當(dāng)前進(jìn)程使用文件結(jié)構(gòu)files中文件描述符指針數(shù)組fd的對(duì)應(yīng)指針置為空,清除對(duì)應(yīng)文件描述符的索引位。put_unused_fd將對(duì)應(yīng)的文件描述符的索引位重新置為可用。filp_close釋放文件描述符,關(guān)閉文件。6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作3.read操作在linux中,read操作是通過(guò)sys_read系統(tǒng)調(diào)用實(shí)現(xiàn)的(在文件/fs/read_write.c中實(shí)現(xiàn))。下面是sys_read函數(shù)asmlinkagessize_tsys_read(unsignedintfd,char__user*buf,size_tcount){ structfile*file; ssize_tret=-EBADF; intfput_needed; file=fget_light(fd,&fput_needed); if(file){loff_tpos=file_pos_read(file);ret=vfs_read(file,buf,count,&pos);file_pos_write(file,pos); fput_light(file,fput_needed); } returnret;}6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作3.read操作ssize_tvfs_read(structfile*file,char__user*buf,size_tcount,loff_t*pos){ssize_tret;

if(!(file->f_mode&FMODE_READ))return-EBADF; if(!file->f_op||(!file->f_op->read&&!file->f_op->aio_read))return-EINVAL; if(unlikely(!access_ok(VERIFY_WRITE,buf,count)))return-EFAULT; ret=rw_verify_area(READ,file,pos,count); if(ret>=0){count=ret;ret=security_file_permission(file,MAY_READ);if(!ret){ if(file->f_op->read) ret=file->f_op->read(file,buf,count,pos); else ret=do_sync_read(file,buf,count,pos); if(ret>0){ fsnotify_access(file->f_path.dentry); add_rchar(current,ret); }inc_syscr(current); } } returnret;}6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作3.read操作主要算法步驟:根據(jù)文件描述符fd調(diào)用fget_light()函數(shù)獲得要讀取文件的file結(jié)構(gòu)變量指針。fget_light()會(huì)判斷打開(kāi)文件表是否多個(gè)進(jìn)程共享,如果不是的話,沒(méi)有必要增加對(duì)應(yīng)file結(jié)構(gòu)的引用計(jì)數(shù)。得到讀文件開(kāi)始時(shí)候的文件偏移量。調(diào)用vfs_read()函數(shù)判斷訪問(wèn)模式是否為讀模式在vfs_read()函數(shù)中,rw_verify_area()以讀模式READ訪問(wèn)區(qū)域,返回負(fù)數(shù)表示不能訪問(wèn)。如果file->f_op->read函數(shù)不為空,則調(diào)用read,從文件位置指針file開(kāi)始讀取count個(gè)字節(jié)的內(nèi)容到用戶緩沖區(qū)buf。File->f_op->read就是具體文件系統(tǒng)的read函數(shù)的實(shí)現(xiàn)。調(diào)用fsnotify_access()通知感興趣的進(jìn)程,該文件已經(jīng)被訪問(wèn)過(guò)。vfs_read()函數(shù)結(jié)束返回。重新寫(xiě)文件偏移量。執(zhí)行fput_light(),如果需要會(huì)釋放file結(jié)構(gòu)的引用計(jì)數(shù)。6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作4.write操作在linux中,write操作是通過(guò)sys_write系統(tǒng)調(diào)用實(shí)現(xiàn)(在文件/fs/read_write.c中實(shí)現(xiàn))。下面是對(duì)sys_write函數(shù)實(shí)現(xiàn)的分析。asmlinkagessize_tsys_write(unsignedintfd,constchar__user*buf,size_tcount){ structfile*file; ssize_tret=-EBADF; intfput_needed; file=fget_light(fd,&fput_needed); if(file){ loff_tpos=file_pos_read(file); ret=vfs_write(file,buf,count,&pos); file_pos_write(file,pos); fput_light(file,fput_needed); } returnret;}6.7Linux文件系統(tǒng)

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作4.write操作6.7Linux文件系統(tǒng)ssize_tvfs_write(structfile*file,constchar__user*buf,size_tcount,loff_t*pos){ ssize_tret; if(!(file->f_mode&FMODE_WRITE)) return-EBADF; if(!file->f_op||(!file->f_op->write&&!file->f_op->aio_write)) return-EINVAL; if(unlikely(!access_ok(VERIFY_READ,buf,count))) return-EFAULT; ret=rw_verify_area(WRITE,file,pos,count); if(ret>=0){ count=ret; ret=security_file_permission(file,MAY_WRITE); if(!ret){ if(file->f_op->write) ret=file->f_op->write(file,buf,count,pos); else ret=do_sync_write(file,buf,count,pos); if(ret>0){ fsnotify_modify(file->f_path.dentry); add_wchar(current,ret); } inc_syscw(current); } }returnret;}

6.7.4

Linux文件系統(tǒng)對(duì)文件的操作4.write操作文件write操作和read操作非常類似,主要算法步驟:

根據(jù)fd調(diào)用fget_light()函數(shù)得到要寫(xiě)文件的file結(jié)構(gòu)變量指針。fget_light()會(huì)判斷打開(kāi)文件表是否多個(gè)進(jìn)程共享,如果不是的話,沒(méi)有必要增加對(duì)應(yīng)file結(jié)構(gòu)的引用計(jì)數(shù)。

得到寫(xiě)文件開(kāi)始時(shí)候的文件偏移量。

調(diào)用vfs_write()函數(shù)。判斷訪問(wèn)模式是否為寫(xiě)模式在vfs_write()函數(shù)中,rw_verify_area()以寫(xiě)模式WRITE訪問(wèn)區(qū)域,返回負(fù)數(shù)表示不能訪問(wèn)。如果file->f_op->write函數(shù)不為空,則調(diào)用write,把用戶緩沖區(qū)buf中的count個(gè)字節(jié)的內(nèi)容寫(xiě)入文件偏移量位置。調(diào)用fsnotify_modify()通知感興趣的進(jìn)程,該文件已經(jīng)被修改過(guò)。vfs_write()函數(shù)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論