亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

linux內核中的文件描述符(一)--基礎知識簡介

系統 2401 0

linux內核中的文件描述符(一)--基礎知識簡介

Kernel version: 2.6.14

CPU architecture: ARM920T

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

作為文件的使用者,進程理所當然的要將所使用的文件記錄于自己的控制塊中,也就是task_struct。另外,由于進程所對應的程序也是一個文件,因此進程控制塊還必須記錄這個文件的相關信息。由于OS要對所有進程提供服務,因此OS還要維護一個記錄所有進程打開的文件的總表。

1.文件對象

當進程通過open系統調用打開一個文件時,該系統調用找到這個文件后,會把文件封裝到一個file結構的實例中提供給進程,這個實例稱為file對象。file結構的定義如下:

    struct file {
	struct list_head	f_list;         //所有打開文件的鏈表
	struct dentry		*f_dentry;      //文件的dentry
	struct vfsmount         *f_vfsmnt;      //文件目錄的VFS安裝點指針
	struct file_operations	*f_op;          //指向文件操作函數集的指針
	atomic_t		f_count;        //記錄訪問本文件的進程數目的計數器
	unsigned int 		f_flags;        //訪問類型
	mode_t			f_mode;         //訪問模式
	loff_t			f_pos;          //文件當前的讀寫位置
	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;
};
  

結構中的域f_uid為文件所有者的ID,f_gid為文件所有者所在組的ID。這樣就使得一個文件可能面臨三種用戶的訪問:

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

內核在處理一個進程或用戶訪問一個文件的請求時,要根據進程的f_uid和f_gid以及訪問模式來確定該進程是否具有訪問這個文件的權限。對于一個用戶來說,可以有讀、寫和執行三種文件權限,這三種權限和三種用戶就共有9中組合,即文件的訪問權限可以用9個bit來表示,并將其保存在文件的dentry中。

結構中的域f_pos記錄了進程對文件讀寫位置的當前值,可以通過調用函數llseek進程移動。

結構中的f_op執向結構file_operations,該結構封裝了對文件進行操作的函數,定義如下:

    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 *);
};
  
從上面的代碼可以看到,結構中是一系列函數的指針,這里有我們比較熟悉的read、open、write和close等函數的指針。進程就是通過這些函數訪問一個文件的,file_operations是linux虛擬文件系統VFS和進程之間的接口。

2.文件描述符

下面進一步介紹進程對自己所訪問的file對象的管理方法。linux中使用一個數組來管理進程打開的文件的file對象,數組中的每個元素都存放一個紙箱進程所打開的文件的file對象。既然用一個數組來存放file對象,那么用數組的下標來訪問文件就是一件順理成章的方法,于是,linux就把數組元素的下標叫做該數組元素所對應的文件的文件描述符,該描述符就是系統對文件的標識,這個數組也叫文件描述符數組,如下圖所示:

linux內核中的文件描述符(一)--基礎知識簡介

內核通過系統調用dup、dup2和fctl可以使數組中的多個元素指向同一個文件的file對象,也就是說,在linux中,同一個文件可以有多個文件描述符。

3.進程打開文件表

進程描述符數組中存放了一個進程所訪問的所有文件,把這個文件描述符數組和這個數組在系統中的一些動態信息組合到一起,就形成了一個新的數據結構——進程打開文件表,即file_struct,其定義如下:

    /*
 * Open file table structure
 */
struct files_struct {
        atomic_t count;                               //引用計數
        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];      //文件描述符數組
};
  
顯然,這個結構應該屬于進程的私有數據,所以進程控制塊task_struct用指針files指向它。

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

  
進程與其打開文件之間的關系如下圖所示。

linux內核中的文件描述符(一)--基礎知識簡介

4.文件描述符的管理

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

    struct fdtable {
	unsigned int max_fds;               //可以代開的最大文件數
	int max_fdset;                      //位圖的最大長度
	int next_fd;                        //下一個可用的fd
	struct file ** fd;      /* current fd array 指向files_struct的fd_array */
	fd_set *close_on_exec;
	fd_set *open_fds;                   //打開的文件標記,比如第2位為0,則打開了2號文件
	struct rcu_head rcu;
	struct files_struct *free_files;
	struct fdtable *next;
};
  

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

linux內核中的文件描述符(一)--基礎知識簡介

linux內核中的文件描述符(一)--基礎知識簡介


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲国产欧美久久香综合 | 日本aa在线 | 日韩经典一区 | 欧美乱大交xxxxxx喷潮免费 | 波多野结衣一二三区 | 嘿嘿嘿视频免费网站在线观看 | 青青影院在线观看 | 国产乱码精品一区二区三上 | 4hu在线| 九九九影院 | 久久r8这里只精品99re66 | 国产在线观看91精品一区 | 亚洲一区精品视频在线 | 好吊妞乱淫欧美 | 人妖粗暴刺激videos | 综合爱爱网 | a在线观看免费视频 | 日日拍夜夜嗷嗷叫狠狠 | 一区二区视频在线观看 | 亚欧成人在线 | 欧美黑人猛xxxxbbbb | 日本欧美中文字幕 | 亚洲国产天堂久久九九九 | 欧美一区二区三区东南亚 | 欧美日韩影视 | 久久精品国产免费观看99 | 成人精品一级毛片 | 日韩中文字幕在线观看视频 | 青青久在线视频免费视频 | 国产午夜亚洲精品国产 | 九九视频在线看精品 | 亚洲成a人片在线v观看 | www.色av.com| 久久看免费视频 | 亚洲国产天堂久久综合9999 | 亚洲精品香蕉一区二区在线观看 | 四虎精品国产一区二区三区 | 五月激情综合婷婷 | 免费一级毛片视频 | 毛片免费观看久久欧美 | 狠狠色丁香婷婷综合久久来 |