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

原文地址:https://www.cnblogs.com/lit10050528/p/6258656.html