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就是保存了每个打开文件信息的数据结构。