歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

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

Kernel version:2.6.14

CPU architecture:ARM920T

作為文件的使用者,進程理所當然的要將所使用的文件記錄於自己的控制塊中,也就是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和進程之間的接口。

Copyright © Linux教程網 All Rights Reserved