1 file.h |
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
3 |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions are met: |
|
6 |
|
7 * Redistributions of source code must retain the above copyright notice, this |
|
8 * list of conditions and the following disclaimer. |
|
9 * Redistributions in binary form must reproduce the above copyright notice, |
|
10 * this list of conditions and the following disclaimer in the documentation |
|
11 * and/or other materials provided with the distribution. |
|
12 * Neither the name of Nokia Corporation nor the names of its contributors |
|
13 * may be used to endorse or promote products derived from this software |
|
14 * without specific prior written permission. |
|
15 |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
|
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
26 * |
|
27 * Description: |
|
28 * |
|
29 */ |
|
30 |
|
31 |
|
32 #ifndef _SYS_FILE_H_ |
|
33 #define _SYS_FILE_H_ |
|
34 |
|
35 #ifndef _KERNEL |
|
36 #include <sys/types.h> /* XXX */ |
|
37 #include <sys/fcntl.h> |
|
38 #include <sys/unistd.h> |
|
39 #else |
|
40 #include <sys/queue.h> |
|
41 #include <sys/_lock.h> |
|
42 #include <sys/_mutex.h> |
|
43 |
|
44 struct stat; |
|
45 struct thread; |
|
46 struct uio; |
|
47 struct knote; |
|
48 struct vnode; |
|
49 struct socket; |
|
50 |
|
51 |
|
52 #endif /* _KERNEL */ |
|
53 |
|
54 #define DTYPE_VNODE 1 /* file */ |
|
55 #define DTYPE_SOCKET 2 /* communications endpoint */ |
|
56 #define DTYPE_PIPE 3 /* pipe */ |
|
57 #define DTYPE_FIFO 4 /* fifo (named pipe) */ |
|
58 #define DTYPE_KQUEUE 5 /* event queue */ |
|
59 #define DTYPE_CRYPTO 6 /* crypto */ |
|
60 |
|
61 #ifdef _KERNEL |
|
62 |
|
63 struct file; |
|
64 struct ucred; |
|
65 |
|
66 typedef int fo_rdwr_t(struct file *fp, struct uio *uio, |
|
67 struct ucred *active_cred, int flags, |
|
68 struct thread *td); |
|
69 #define FOF_OFFSET 1 /* Use the offset in uio argument */ |
|
70 typedef int fo_ioctl_t(struct file *fp, u_long com, void *data, |
|
71 struct ucred *active_cred, struct thread *td); |
|
72 typedef int fo_poll_t(struct file *fp, int events, |
|
73 struct ucred *active_cred, struct thread *td); |
|
74 typedef int fo_kqfilter_t(struct file *fp, struct knote *kn); |
|
75 typedef int fo_stat_t(struct file *fp, struct stat *sb, |
|
76 struct ucred *active_cred, struct thread *td); |
|
77 typedef int fo_close_t(struct file *fp, struct thread *td); |
|
78 typedef int fo_flags_t; |
|
79 |
|
80 struct fileops { |
|
81 fo_rdwr_t *fo_read; |
|
82 fo_rdwr_t *fo_write; |
|
83 fo_ioctl_t *fo_ioctl; |
|
84 fo_poll_t *fo_poll; |
|
85 fo_kqfilter_t *fo_kqfilter; |
|
86 fo_stat_t *fo_stat; |
|
87 fo_close_t *fo_close; |
|
88 fo_flags_t fo_flags; /* DFLAG_* below */ |
|
89 }; |
|
90 |
|
91 #define DFLAG_PASSABLE 0x01 /* may be passed via unix sockets. */ |
|
92 #define DFLAG_SEEKABLE 0x02 /* seekable / nonsequential */ |
|
93 |
|
94 /* |
|
95 * Kernel descriptor table. |
|
96 * One entry for each open kernel vnode and socket. |
|
97 * |
|
98 * Below is the list of locks that protects members in struct file. |
|
99 * |
|
100 * (fl) filelist_lock |
|
101 * (f) f_mtx in struct file |
|
102 * none not locked |
|
103 */ |
|
104 |
|
105 struct file { |
|
106 LIST_ENTRY(file) f_list;/* (fl) list of active files */ |
|
107 short f_type; /* descriptor type */ |
|
108 void *f_data; /* file descriptor specific data */ |
|
109 u_int f_flag; /* see fcntl.h */ |
|
110 struct mtx *f_mtxp; /* mutex to protect data */ |
|
111 struct fileops *f_ops; /* File operations */ |
|
112 struct ucred *f_cred; /* credentials associated with descriptor */ |
|
113 int f_count; /* (f) reference count */ |
|
114 struct vnode *f_vnode; /* NULL or applicable vnode */ |
|
115 |
|
116 /* DFLAG_SEEKABLE specific fields */ |
|
117 off_t f_offset; |
|
118 |
|
119 /* DTYPE_SOCKET specific fields */ |
|
120 short f_gcflag; /* used by thread doing fd garbage collection */ |
|
121 #define FMARK 0x1 /* mark during gc() */ |
|
122 #define FDEFER 0x2 /* defer for next gc pass */ |
|
123 int f_msgcount; /* (f) references from message queue */ |
|
124 |
|
125 /* DTYPE_VNODE specific fields */ |
|
126 int f_seqcount; /* |
|
127 * count of sequential accesses -- cleared |
|
128 * by most seek operations. |
|
129 */ |
|
130 off_t f_nextoff; /* |
|
131 * offset of next expected read or write |
|
132 */ |
|
133 void *f_label; /* Place-holder for struct label pointer. */ |
|
134 }; |
|
135 |
|
136 #endif /* _KERNEL */ |
|
137 |
|
138 /* |
|
139 * Userland version of struct file, for sysctl |
|
140 */ |
|
141 struct xfile { |
|
142 size_t xf_size; /* size of struct xfile */ |
|
143 pid_t xf_pid; /* owning process */ |
|
144 uid_t xf_uid; /* effective uid of owning process */ |
|
145 int xf_fd; /* descriptor number */ |
|
146 void *xf_file; /* address of struct file */ |
|
147 short xf_type; /* descriptor type */ |
|
148 int xf_count; /* reference count */ |
|
149 int xf_msgcount; /* references from message queue */ |
|
150 off_t xf_offset; /* file offset */ |
|
151 void *xf_data; /* file descriptor specific data */ |
|
152 void *xf_vnode; /* vnode pointer */ |
|
153 u_int xf_flag; /* flags (see fcntl.h) */ |
|
154 }; |
|
155 |
|
156 #ifdef _KERNEL |
|
157 extern struct filelist filehead; /* (fl) head of list of open files */ |
|
158 extern struct fileops vnops; |
|
159 extern struct fileops badfileops; |
|
160 extern struct fileops socketops; |
|
161 extern int maxfiles; /* kernel limit on number of open files */ |
|
162 extern int maxfilesperproc; /* per process limit on number of open files */ |
|
163 extern int openfiles; /* (fl) actual number of open files */ |
|
164 extern struct sx filelist_lock; /* sx to protect filelist and openfiles */ |
|
165 |
|
166 /* |
|
167 * The socket operations are used a couple of places. |
|
168 * XXX: This is wrong, they should go through the operations vector for |
|
169 * XXX: sockets instead of going directly for the individual functions. /phk |
|
170 */ |
|
171 fo_rdwr_t soo_read; |
|
172 fo_rdwr_t soo_write; |
|
173 fo_ioctl_t soo_ioctl; |
|
174 fo_poll_t soo_poll; |
|
175 fo_kqfilter_t soo_kqfilter; |
|
176 fo_stat_t soo_stat; |
|
177 fo_close_t soo_close; |
|
178 |
|
179 /* Lock a file. */ |
|
180 #define FILE_LOCK(f) mtx_lock((f)->f_mtxp) |
|
181 #define FILE_UNLOCK(f) mtx_unlock((f)->f_mtxp) |
|
182 #define FILE_LOCKED(f) mtx_owned((f)->f_mtxp) |
|
183 #define FILE_LOCK_ASSERT(f, type) mtx_assert((f)->f_mtxp, (type)) |
|
184 |
|
185 #define fhold_locked(fp) \ |
|
186 do { \ |
|
187 FILE_LOCK_ASSERT(fp, MA_OWNED); \ |
|
188 (fp)->f_count++; \ |
|
189 } while (0) |
|
190 |
|
191 #define fhold(fp) \ |
|
192 do { \ |
|
193 FILE_LOCK(fp); \ |
|
194 (fp)->f_count++; \ |
|
195 FILE_UNLOCK(fp); \ |
|
196 } while (0) |
|
197 |
|
198 static __inline fo_rdwr_t fo_read; |
|
199 static __inline fo_rdwr_t fo_write; |
|
200 static __inline fo_ioctl_t fo_ioctl; |
|
201 static __inline fo_poll_t fo_poll; |
|
202 static __inline fo_kqfilter_t fo_kqfilter; |
|
203 static __inline fo_stat_t fo_stat; |
|
204 static __inline fo_close_t fo_close; |
|
205 |
|
206 static __inline int |
|
207 fo_read(fp, uio, active_cred, flags, td) |
|
208 struct file *fp; |
|
209 struct uio *uio; |
|
210 struct ucred *active_cred; |
|
211 int flags; |
|
212 struct thread *td; |
|
213 { |
|
214 |
|
215 return ((*fp->f_ops->fo_read)(fp, uio, active_cred, flags, td)); |
|
216 } |
|
217 |
|
218 static __inline int |
|
219 fo_write(fp, uio, active_cred, flags, td) |
|
220 struct file *fp; |
|
221 struct uio *uio; |
|
222 struct ucred *active_cred; |
|
223 int flags; |
|
224 struct thread *td; |
|
225 { |
|
226 |
|
227 return ((*fp->f_ops->fo_write)(fp, uio, active_cred, flags, td)); |
|
228 } |
|
229 |
|
230 static __inline int |
|
231 fo_ioctl(fp, com, data, active_cred, td) |
|
232 struct file *fp; |
|
233 u_long com; |
|
234 void *data; |
|
235 struct ucred *active_cred; |
|
236 struct thread *td; |
|
237 { |
|
238 |
|
239 return ((*fp->f_ops->fo_ioctl)(fp, com, data, active_cred, td)); |
|
240 } |
|
241 |
|
242 static __inline int |
|
243 fo_poll(fp, events, active_cred, td) |
|
244 struct file *fp; |
|
245 int events; |
|
246 struct ucred *active_cred; |
|
247 struct thread *td; |
|
248 { |
|
249 |
|
250 return ((*fp->f_ops->fo_poll)(fp, events, active_cred, td)); |
|
251 } |
|
252 |
|
253 static __inline int |
|
254 fo_stat(fp, sb, active_cred, td) |
|
255 struct file *fp; |
|
256 struct stat *sb; |
|
257 struct ucred *active_cred; |
|
258 struct thread *td; |
|
259 { |
|
260 |
|
261 return ((*fp->f_ops->fo_stat)(fp, sb, active_cred, td)); |
|
262 } |
|
263 |
|
264 static __inline int |
|
265 fo_close(fp, td) |
|
266 struct file *fp; |
|
267 struct thread *td; |
|
268 { |
|
269 |
|
270 return ((*fp->f_ops->fo_close)(fp, td)); |
|
271 } |
|
272 |
|
273 static __inline int |
|
274 fo_kqfilter(fp, kn) |
|
275 struct file *fp; |
|
276 struct knote *kn; |
|
277 { |
|
278 |
|
279 return ((*fp->f_ops->fo_kqfilter)(fp, kn)); |
|
280 } |
|
281 |
|
282 #endif /* _KERNEL */ |
|
283 |
|
284 #endif /* !SYS_FILE_H */ |