1 | /* $NetBSD: filedesc.h,v 1.63 2012/02/11 23:16:18 martin Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
28 | |
29 | /* |
30 | * Copyright (c) 1990, 1993 |
31 | * The Regents of the University of California. All rights reserved. |
32 | * |
33 | * Redistribution and use in source and binary forms, with or without |
34 | * modification, are permitted provided that the following conditions |
35 | * are met: |
36 | * 1. Redistributions of source code must retain the above copyright |
37 | * notice, this list of conditions and the following disclaimer. |
38 | * 2. Redistributions in binary form must reproduce the above copyright |
39 | * notice, this list of conditions and the following disclaimer in the |
40 | * documentation and/or other materials provided with the distribution. |
41 | * 3. Neither the name of the University nor the names of its contributors |
42 | * may be used to endorse or promote products derived from this software |
43 | * without specific prior written permission. |
44 | * |
45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
55 | * SUCH DAMAGE. |
56 | * |
57 | * @(#)filedesc.h 8.1 (Berkeley) 6/2/93 |
58 | */ |
59 | |
60 | #ifndef _SYS_FILEDESC_H_ |
61 | #define _SYS_FILEDESC_H_ |
62 | |
63 | #include <sys/param.h> |
64 | #include <sys/queue.h> |
65 | #include <sys/mutex.h> |
66 | #include <sys/rwlock.h> |
67 | #include <sys/condvar.h> |
68 | |
69 | /* |
70 | * This structure is used for the management of descriptors. It may be |
71 | * shared by multiple processes. |
72 | * |
73 | * A process is initially started out with NDFILE descriptors stored within |
74 | * this structure, selected to be enough for typical applications based on |
75 | * the historical limit of 20 open files (and the usage of descriptors by |
76 | * shells). If these descriptors are exhausted, a larger descriptor table |
77 | * may be allocated, up to a process' resource limit; the internal arrays |
78 | * are then unused. The initial expansion is set to NDEXTENT; each time |
79 | * it runs out, it is doubled until the resource limit is reached. NDEXTENT |
80 | * should be selected to be the biggest multiple of OFILESIZE (see below) |
81 | * that will fit in a power-of-two sized piece of memory. |
82 | */ |
83 | #define NDFILE 20 |
84 | #define NDEXTENT 50 /* 250 bytes in 256-byte alloc */ |
85 | #define NDENTRIES 32 /* 32 fds per entry */ |
86 | #define NDENTRYMASK (NDENTRIES - 1) |
87 | #define NDENTRYSHIFT 5 /* bits per entry */ |
88 | #define NDLOSLOTS(x) (((x) + NDENTRIES - 1) >> NDENTRYSHIFT) |
89 | #define NDHISLOTS(x) ((NDLOSLOTS(x) + NDENTRIES - 1) >> NDENTRYSHIFT) |
90 | #define NDFDFILE 6 /* first 6 descriptors are free */ |
91 | |
92 | /* |
93 | * Process-private descriptor reference, one for each descriptor slot |
94 | * in use. Locks: |
95 | * |
96 | * : unlocked |
97 | * a atomic operations + filedesc_t::fd_lock in some cases |
98 | * d filedesc_t::fd_lock |
99 | * |
100 | * Note that ff_exclose and ff_allocated are likely to be byte sized |
101 | * (bool). In general adjacent sub-word sized fields must be locked |
102 | * the same way, but in this case it's ok: ff_exclose can only be |
103 | * modified while the descriptor slot is live, and ff_allocated when |
104 | * it's invalid. |
105 | */ |
106 | typedef struct fdfile { |
107 | bool ff_exclose; /* :: close on exec flag */ |
108 | bool ff_allocated; /* d: descriptor slot is allocated */ |
109 | u_int ff_refcnt; /* a: reference count on structure */ |
110 | struct file *ff_file; /* d: pointer to file if open */ |
111 | SLIST_HEAD(,knote) ff_knlist; /* d: knotes attached to this fd */ |
112 | kcondvar_t ff_closing; /* d: notifier for close */ |
113 | } fdfile_t; |
114 | |
115 | /* Reference count */ |
116 | #define FR_CLOSING (0x80000000) /* closing: must interlock */ |
117 | #define FR_MASK (~FR_CLOSING) /* reference count */ |
118 | |
119 | /* |
120 | * Open file table, potentially many 'active' tables per filedesc_t |
121 | * in a multi-threaded process, or with a shared filedesc_t (clone()). |
122 | * nfiles is first to avoid pointer arithmetic. |
123 | */ |
124 | typedef struct fdtab { |
125 | u_int dt_nfiles; /* number of open files allocated */ |
126 | struct fdtab *dt_link; /* for lists of dtab */ |
127 | fdfile_t *dt_ff[NDFILE]; /* file structures for open fds */ |
128 | } fdtab_t; |
129 | |
130 | typedef struct filedesc { |
131 | /* |
132 | * Built-in fdfile_t records first, since they have strict |
133 | * alignment requirements. |
134 | */ |
135 | uint8_t fd_dfdfile[NDFDFILE][CACHE_LINE_SIZE]; |
136 | /* |
137 | * All of the remaining fields are locked by fd_lock. |
138 | */ |
139 | kmutex_t fd_lock; /* lock on structure */ |
140 | fdtab_t * volatile fd_dt; /* active descriptor table */ |
141 | uint32_t *fd_himap; /* each bit points to 32 fds */ |
142 | uint32_t *fd_lomap; /* bitmap of free fds */ |
143 | struct klist *fd_knhash; /* hash of attached non-fd knotes */ |
144 | int fd_lastkqfile; /* max descriptor for kqueue */ |
145 | int fd_lastfile; /* high-water mark of fd_ofiles */ |
146 | int fd_refcnt; /* reference count */ |
147 | u_long fd_knhashmask; /* size of fd_knhash */ |
148 | int fd_freefile; /* approx. next free file */ |
149 | int fd_unused; /* unused */ |
150 | bool fd_exclose; /* non-zero if >0 fd with EXCLOSE */ |
151 | /* |
152 | * This structure is used when the number of open files is |
153 | * <= NDFILE, and are then pointed to by the pointers above. |
154 | */ |
155 | fdtab_t fd_dtbuiltin; |
156 | /* |
157 | * These arrays are used when the number of open files is |
158 | * <= 1024, and are then pointed to by the pointers above. |
159 | */ |
160 | #define fd_startzero fd_dhimap /* area to zero on return to cache */ |
161 | uint32_t fd_dhimap[NDENTRIES >> NDENTRYSHIFT]; |
162 | uint32_t fd_dlomap[NDENTRIES]; |
163 | } filedesc_t; |
164 | |
165 | typedef struct cwdinfo { |
166 | struct vnode *cwdi_cdir; /* current directory */ |
167 | struct vnode *cwdi_rdir; /* root directory */ |
168 | struct vnode *cwdi_edir; /* emulation root (if known) */ |
169 | krwlock_t cwdi_lock; /* lock on entire struct */ |
170 | u_short cwdi_cmask; /* mask for file creation */ |
171 | u_int cwdi_refcnt; /* reference count */ |
172 | } cwdinfo_t; |
173 | |
174 | #ifdef _KERNEL |
175 | |
176 | struct fileops; |
177 | struct socket; |
178 | struct proc; |
179 | |
180 | /* |
181 | * Kernel global variables and routines. |
182 | */ |
183 | void fd_sys_init(void); |
184 | int fd_open(const char*, int, int, int*); |
185 | int fd_dupopen(int, int *, int, int); |
186 | int fd_alloc(struct proc *, int, int *); |
187 | void fd_tryexpand(struct proc *); |
188 | int fd_allocfile(file_t **, int *); |
189 | void fd_affix(struct proc *, file_t *, unsigned); |
190 | void fd_abort(struct proc *, file_t *, unsigned); |
191 | filedesc_t *fd_copy(void); |
192 | filedesc_t *fd_init(filedesc_t *); |
193 | void fd_share(proc_t *); |
194 | void fd_hold(lwp_t *); |
195 | void fd_free(void); |
196 | void fd_closeexec(void); |
197 | void fd_ktrexecfd(void); |
198 | int fd_checkstd(void); |
199 | file_t *fd_getfile(unsigned); |
200 | file_t *fd_getfile2(proc_t *, unsigned); |
201 | void fd_putfile(unsigned); |
202 | int fd_getvnode(unsigned, file_t **); |
203 | int fd_getsock(unsigned, struct socket **); |
204 | int fd_getsock1(unsigned, struct socket **, file_t **); |
205 | void fd_putvnode(unsigned); |
206 | void fd_putsock(unsigned); |
207 | int fd_close(unsigned); |
208 | int fd_dup(file_t *, int, int *, bool); |
209 | int fd_dup2(file_t *, unsigned, int); |
210 | int fd_clone(file_t *, unsigned, int, const struct fileops *, void *); |
211 | void fd_set_exclose(struct lwp *, int, bool); |
212 | int pipe1(struct lwp *, register_t *, int); |
213 | int dodup(struct lwp *, int, int, int, register_t *); |
214 | |
215 | void cwd_sys_init(void); |
216 | struct cwdinfo *cwdinit(void); |
217 | void cwdshare(proc_t *); |
218 | void cwdunshare(proc_t *); |
219 | void cwdfree(struct cwdinfo *); |
220 | void cwdexec(struct proc *); |
221 | |
222 | #define GETCWD_CHECK_ACCESS 0x0001 |
223 | int getcwd_common(struct vnode *, struct vnode *, char **, char *, int, |
224 | int, struct lwp *); |
225 | int vnode_to_path(char *, size_t, struct vnode *, struct lwp *, |
226 | struct proc *); |
227 | |
228 | int closef(file_t *); |
229 | file_t *fgetdummy(void); |
230 | void fputdummy(file_t *); |
231 | |
232 | struct stat; |
233 | int do_sys_fstat(int, struct stat *); |
234 | struct flock; |
235 | int do_fcntl_lock(int, int, struct flock *); |
236 | int do_posix_fadvise(int, off_t, off_t, int); |
237 | |
238 | extern kmutex_t filelist_lock; |
239 | extern filedesc_t filedesc0; |
240 | |
241 | #endif /* _KERNEL */ |
242 | |
243 | #endif /* !_SYS_FILEDESC_H_ */ |
244 | |