Linux内核分析:打开文件描述符实现
在Linux中每一个进程的数据是存储在一个task_struct结构(定义在sched.h中)中的。
1 struct task_struct { 2 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 3 struct thread_info *thread_info; 4 atomic_t usage; 5 unsigned long flags; /* per process flags, defined below */ 6 unsigned long ptrace; 7 8 int lock_depth; /* Lock depth */ 9 10 int prio, static_prio; 11 struct list_head run_list; 12 prio_array_t *array; 13 14 unsigned long sleep_avg; 15 unsigned long long timestamp, last_ran; 16 int activated; 17 18 unsigned long policy; 19 cpumask_t cpus_allowed; 20 unsigned int time_slice, first_time_slice; 21 22 #ifdef CONFIG_SCHEDSTATS 23 struct sched_info sched_info; 24 #endif 25 26 struct list_head tasks; 27 /* 28 * ptrace_list/ptrace_children forms the list of my children 29 * that were stolen by a ptracer. 30 */ 31 struct list_head ptrace_children; 32 struct list_head ptrace_list; 33 34 struct mm_struct *mm, *active_mm; 35 36 /* task state */ 37 struct linux_binfmt *binfmt; 38 long exit_state; 39 int exit_code, exit_signal; 40 int pdeath_signal; /* The signal sent when the parent dies */ 41 /* ??? */ 42 unsigned long personality; 43 unsigned did_exec:1; 44 pid_t pid; 45 pid_t tgid; 46 /* 47 * pointers to (original) parent process, youngest child, younger sibling, 48 * older sibling, respectively. (p->father can be replaced with 49 * p->parent->pid) 50 */ 51 struct task_struct *real_parent; /* real parent process (when being debugged) */ 52 struct task_struct *parent; /* parent process */ 53 /* 54 * children/sibling forms the list of my children plus the 55 * tasks I'm ptracing. 56 */ 57 struct list_head children; /* list of my children */ 58 struct list_head sibling; /* linkage in my parent's children list */ 59 struct task_struct *group_leader; /* threadgroup leader */ 60 61 /* PID/PID hash table linkage. */ 62 struct pid pids[PIDTYPE_MAX]; 63 64 struct completion *vfork_done; /* for vfork() */ 65 int __user *set_child_tid; /* CLONE_CHILD_SETTID */ 66 int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ 67 68 unsigned long rt_priority; 69 unsigned long it_real_value, it_real_incr; 70 cputime_t it_virt_value, it_virt_incr; 71 cputime_t it_prof_value, it_prof_incr; 72 struct timer_list real_timer; 73 cputime_t utime, stime; 74 unsigned long nvcsw, nivcsw; /* context switch counts */ 75 struct timespec start_time; 76 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ 77 unsigned long min_flt, maj_flt; 78 /* process credentials */ 79 uid_t uid,euid,suid,fsuid; 80 gid_t gid,egid,sgid,fsgid; 81 struct group_info *group_info; 82 kernel_cap_t cap_effective, cap_inheritable, cap_permitted; 83 unsigned keep_capabilities:1; 84 struct user_struct *user; 85 #ifdef CONFIG_KEYS 86 struct key *session_keyring; /* keyring inherited over fork */ 87 struct key *process_keyring; /* keyring private to this process (CLONE_THREAD) */ 88 struct key *thread_keyring; /* keyring private to this thread */ 89 #endif 90 int oomkilladj; /* OOM kill score adjustment (bit shift). */ 91 char comm[TASK_COMM_LEN]; 92 /* file system info */ 93 int link_count, total_link_count; 94 /* ipc stuff */ 95 struct sysv_sem sysvsem; 96 /* CPU-specific state of this task */ 97 struct thread_struct thread; 98 /* filesystem information */ 99 struct fs_struct *fs; 100 /* open file information */ 101 struct files_struct *files; 102 /* namespace */ 103 struct namespace *namespace; 104 /* signal handlers */ 105 struct signal_struct *signal; 106 struct sighand_struct *sighand; 107 108 sigset_t blocked, real_blocked; 109 struct sigpending pending; 110 111 unsigned long sas_ss_sp; 112 size_t sas_ss_size; 113 int (*notifier)(void *priv); 114 void *notifier_data; 115 sigset_t *notifier_mask; 116 117 void *security; 118 struct audit_context *audit_context; 119 120 /* Thread group tracking */ 121 u32 parent_exec_id; 122 u32 self_exec_id; 123 /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ 124 spinlock_t alloc_lock; 125 /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */ 126 spinlock_t proc_lock; 127 /* context-switch lock */ 128 spinlock_t switch_lock; 129 130 /* journalling filesystem info */ 131 void *journal_info; 132 133 /* VM state */ 134 struct reclaim_state *reclaim_state; 135 136 struct dentry *proc_dentry; 137 struct backing_dev_info *backing_dev_info; 138 139 struct io_context *io_context; 140 141 unsigned long ptrace_message; 142 siginfo_t *last_siginfo; /* For ptrace use. */ 143 /* 144 * current io wait handle: wait queue entry to use for io waits 145 * If this thread is processing aio, this points at the waitqueue 146 * inside the currently handled kiocb. It may be NULL (i.e. default 147 * to a stack based synchronous wait) if its doing sync IO. 148 */ 149 wait_queue_t *io_wait; 150 /* i/o counters(bytes read/written, #syscalls */ 151 u64 rchar, wchar, syscr, syscw; 152 #if defined(CONFIG_BSD_PROCESS_ACCT) 153 u64 acct_rss_mem1; /* accumulated rss usage */ 154 u64 acct_vm_mem1; /* accumulated virtual memory usage */ 155 clock_t acct_stimexpd; /* clock_t-converted stime since last update */ 156 #endif 157 #ifdef CONFIG_NUMA 158 struct mempolicy *mempolicy; 159 short il_next; 160 #endif 161 };
该结构中有一个用于保存打开文件信息的成员:files,该成员类型是:struct files_struct*(定义在file.h)。
1 /*
2 * Open file table structure
3 */
4 struct files_struct {
5 atomic_t count;
6 spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */
7 int max_fds;
8 int max_fdset;
9 int next_fd;
10 struct file ** fd; /* current fd array */
11 fd_set *close_on_exec;
12 fd_set *open_fds;
13 fd_set close_on_exec_init;
14 fd_set open_fds_init;
15 struct file * fd_array[NR_OPEN_DEFAULT];
16 };
可以看到该结构中保存了所有与进程打开文件相关的信息,其中fd_array是一个struct file*(定义在file.h)类型的数组。
1 struct file {
2 struct list_head f_list;
3 struct dentry *f_dentry;
4 struct vfsmount *f_vfsmnt;
5 struct file_operations *f_op;
6 atomic_t f_count;
7 unsigned int f_flags;
8 mode_t f_mode;
9 int f_error;
10 loff_t f_pos;
11 struct fown_struct f_owner;
12 unsigned int f_uid, f_gid;
13 struct file_ra_state f_ra;
14
15 size_t f_maxcount;
16 unsigned long f_version;
17 void *f_security;
18
19 /* needed for tty driver, and maybe others */
20 void *private_data;
21
22 #ifdef CONFIG_EPOLL
23 /* Used by fs/eventpoll.c to link all the hooks to this file */
24 struct list_head f_ep_links;
25 spinlock_t f_ep_lock;
26 #endif /* #ifdef CONFIG_EPOLL */
27 struct address_space *f_mapping;
28 };
struct file就是保存了每个打开文件信息的数据结构。