日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

linux內(nèi)核中的文件描述符(一)--基礎(chǔ)知識(shí)簡(jiǎn)介

系統(tǒng) 2711 0

linux內(nèi)核中的文件描述符(一)--基礎(chǔ)知識(shí)簡(jiǎn)介

Kernel version: 2.6.14

CPU architecture: ARM920T

Author: ce123(http://blog.csdn.net/ce123)

作為文件的使用者,進(jìn)程理所當(dāng)然的要將所使用的文件記錄于自己的控制塊中,也就是task_struct。另外,由于進(jìn)程所對(duì)應(yīng)的程序也是一個(gè)文件,因此進(jìn)程控制塊還必須記錄這個(gè)文件的相關(guān)信息。由于OS要對(duì)所有進(jìn)程提供服務(wù),因此OS還要維護(hù)一個(gè)記錄所有進(jìn)程打開(kāi)的文件的總表。

1.文件對(duì)象

當(dāng)進(jìn)程通過(guò)open系統(tǒng)調(diào)用打開(kāi)一個(gè)文件時(shí),該系統(tǒng)調(diào)用找到這個(gè)文件后,會(huì)把文件封裝到一個(gè)file結(jié)構(gòu)的實(shí)例中提供給進(jìn)程,這個(gè)實(shí)例稱(chēng)為file對(duì)象。file結(jié)構(gòu)的定義如下:

    struct file {
	struct list_head	f_list;         //所有打開(kāi)文件的鏈表
	struct dentry		*f_dentry;      //文件的dentry
	struct vfsmount         *f_vfsmnt;      //文件目錄的VFS安裝點(diǎn)指針
	struct file_operations	*f_op;          //指向文件操作函數(shù)集的指針
	atomic_t		f_count;        //記錄訪問(wèn)本文件的進(jìn)程數(shù)目的計(jì)數(shù)器
	unsigned int 		f_flags;        //訪問(wèn)類(lèi)型
	mode_t			f_mode;         //訪問(wèn)模式
	loff_t			f_pos;          //文件當(dāng)前的讀寫(xiě)位置
	struct fown_struct	f_owner;
	unsigned int		f_uid, f_gid;   //文件所有者ID和用戶組ID
	struct file_ra_state	f_ra;

	unsigned long		f_version;
	void			*f_security;

	/* needed for tty driver, and maybe others */
	void			*private_data;

#ifdef CONFIG_EPOLL
	/* Used by fs/eventpoll.c to link all the hooks to this file */
	struct list_head	f_ep_links;
	spinlock_t		f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
	struct address_space	*f_mapping;
	struct rcu_head 	f_rcuhead;
};
  

結(jié)構(gòu)中的域f_uid為文件所有者的ID,f_gid為文件所有者所在組的ID。這樣就使得一個(gè)文件可能面臨三種用戶的訪問(wèn):

  • 文件所有者;
  • 同組用戶;
  • 其他用戶。

內(nèi)核在處理一個(gè)進(jìn)程或用戶訪問(wèn)一個(gè)文件的請(qǐng)求時(shí),要根據(jù)進(jìn)程的f_uid和f_gid以及訪問(wèn)模式來(lái)確定該進(jìn)程是否具有訪問(wèn)這個(gè)文件的權(quán)限。對(duì)于一個(gè)用戶來(lái)說(shuō),可以有讀、寫(xiě)和執(zhí)行三種文件權(quán)限,這三種權(quán)限和三種用戶就共有9中組合,即文件的訪問(wèn)權(quán)限可以用9個(gè)bit來(lái)表示,并將其保存在文件的dentry中。

結(jié)構(gòu)中的域f_pos記錄了進(jìn)程對(duì)文件讀寫(xiě)位置的當(dāng)前值,可以通過(guò)調(diào)用函數(shù)llseek進(jìn)程移動(dòng)。

結(jié)構(gòu)中的f_op執(zhí)向結(jié)構(gòu)file_operations,該結(jié)構(gòu)封裝了對(duì)文件進(jìn)行操作的函數(shù),定義如下:

    struct file_operations {
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
	ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
	ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
	int (*readdir) (struct file *, void *, filldir_t);
	unsigned int (*poll) (struct file *, struct poll_table_struct *);
	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
	int (*mmap) (struct file *, struct vm_area_struct *);
	int (*open) (struct inode *, struct file *);
	int (*flush) (struct file *);
	int (*release) (struct inode *, struct file *);
	int (*fsync) (struct file *, struct dentry *, int datasync);
	int (*aio_fsync) (struct kiocb *, int datasync);
	int (*fasync) (int, struct file *, int);
	int (*lock) (struct file *, int, struct file_lock *);
	ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
	ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
	ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
	int (*check_flags)(int);
	int (*dir_notify)(struct file *filp, unsigned long arg);
	int (*flock) (struct file *, int, struct file_lock *);
};
  
從上面的代碼可以看到,結(jié)構(gòu)中是一系列函數(shù)的指針,這里有我們比較熟悉的read、open、write和close等函數(shù)的指針。進(jìn)程就是通過(guò)這些函數(shù)訪問(wèn)一個(gè)文件的,file_operations是linux虛擬文件系統(tǒng)VFS和進(jìn)程之間的接口。

2.文件描述符

下面進(jìn)一步介紹進(jìn)程對(duì)自己所訪問(wèn)的file對(duì)象的管理方法。linux中使用一個(gè)數(shù)組來(lái)管理進(jìn)程打開(kāi)的文件的file對(duì)象,數(shù)組中的每個(gè)元素都存放一個(gè)紙箱進(jìn)程所打開(kāi)的文件的file對(duì)象。既然用一個(gè)數(shù)組來(lái)存放file對(duì)象,那么用數(shù)組的下標(biāo)來(lái)訪問(wèn)文件就是一件順理成章的方法,于是,linux就把數(shù)組元素的下標(biāo)叫做該數(shù)組元素所對(duì)應(yīng)的文件的文件描述符,該描述符就是系統(tǒng)對(duì)文件的標(biāo)識(shí),這個(gè)數(shù)組也叫文件描述符數(shù)組,如下圖所示:

linux內(nèi)核中的文件描述符(一)--基礎(chǔ)知識(shí)簡(jiǎn)介

內(nèi)核通過(guò)系統(tǒng)調(diào)用dup、dup2和fctl可以使數(shù)組中的多個(gè)元素指向同一個(gè)文件的file對(duì)象,也就是說(shuō),在linux中,同一個(gè)文件可以有多個(gè)文件描述符。

3.進(jìn)程打開(kāi)文件表

進(jìn)程描述符數(shù)組中存放了一個(gè)進(jìn)程所訪問(wèn)的所有文件,把這個(gè)文件描述符數(shù)組和這個(gè)數(shù)組在系統(tǒng)中的一些動(dòng)態(tài)信息組合到一起,就形成了一個(gè)新的數(shù)據(jù)結(jié)構(gòu)——進(jìn)程打開(kāi)文件表,即file_struct,其定義如下:

    /*
 * Open file table structure
 */
struct files_struct {
        atomic_t count;                               //引用計(jì)數(shù)
        spinlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
	struct fdtable *fdt;                          //管理文件描述符
	struct fdtable fdtab;                         //管理文件描述符
        fd_set close_on_exec_init;                    //位圖
        fd_set open_fds_init;                         //位圖
        struct file * fd_array[NR_OPEN_DEFAULT];      //文件描述符數(shù)組
};
  
顯然,這個(gè)結(jié)構(gòu)應(yīng)該屬于進(jìn)程的私有數(shù)據(jù),所以進(jìn)程控制塊task_struct用指針files指向它。

    struct task_struct {
	...
/* open file information */
	struct files_struct *files;
	...
};

  
進(jìn)程與其打開(kāi)文件之間的關(guān)系如下圖所示。

linux內(nèi)核中的文件描述符(一)--基礎(chǔ)知識(shí)簡(jiǎn)介

4.文件描述符的管理

file_struct中的fdt和fdtab用于管理文件文件描述符,一個(gè)是fdtable類(lèi)型,另一個(gè)是其指針類(lèi)型。fdtable的定義如下:

    struct fdtable {
	unsigned int max_fds;               //可以代開(kāi)的最大文件數(shù)
	int max_fdset;                      //位圖的最大長(zhǎng)度
	int next_fd;                        //下一個(gè)可用的fd
	struct file ** fd;      /* current fd array 指向files_struct的fd_array */
	fd_set *close_on_exec;
	fd_set *open_fds;                   //打開(kāi)的文件標(biāo)記,比如第2位為0,則打開(kāi)了2號(hào)文件
	struct rcu_head rcu;
	struct files_struct *free_files;
	struct fdtable *next;
};
  

下圖可以很直觀的說(shuō)明文件描述符fd的管理。

linux內(nèi)核中的文件描述符(一)--基礎(chǔ)知識(shí)簡(jiǎn)介

linux內(nèi)核中的文件描述符(一)--基礎(chǔ)知識(shí)簡(jiǎn)介


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!?。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 新平| 阜南县| 九寨沟县| 水富县| 平谷区| 醴陵市| 台山市| 潞城市| 广平县| 武川县| 娄底市| 兴和县| 中超| 海阳市| 马公市| 阳新县| 咸阳市| 罗源县| 固原市| 江都市| 天峨县| 高邑县| 西乌珠穆沁旗| 柞水县| 深水埗区| 碌曲县| 西乡县| 霸州市| 出国| 繁峙县| 康保县| 涞水县| 满城县| 清水县| 册亨县| 慈溪市| 彰化县| 炉霍县| 西乡县| 仙游县| 宁陕县|