master
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. 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 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)file.h 8.3 (Berkeley) 1/9/95
32 */
33
34#ifndef _SYS_FILE_H_
35#define _SYS_FILE_H_
36
37#ifndef _KERNEL
38#include <sys/types.h> /* XXX */
39#include <sys/fcntl.h>
40#include <sys/unistd.h>
41#else
42#include <sys/queue.h>
43#include <sys/refcount.h>
44#include <sys/_lock.h>
45#include <sys/_mutex.h>
46#include <vm/vm.h>
47
48struct filedesc;
49struct stat;
50struct thread;
51struct uio;
52struct knote;
53struct vnode;
54struct nameidata;
55
56#endif /* _KERNEL */
57
58#define DTYPE_NONE 0 /* not yet initialized */
59#define DTYPE_VNODE 1 /* file */
60#define DTYPE_SOCKET 2 /* communications endpoint */
61#define DTYPE_PIPE 3 /* pipe */
62#define DTYPE_FIFO 4 /* fifo (named pipe) */
63#define DTYPE_KQUEUE 5 /* event queue */
64#define DTYPE_CRYPTO 6 /* crypto */
65#define DTYPE_MQUEUE 7 /* posix message queue */
66#define DTYPE_SHM 8 /* swap-backed shared memory */
67#define DTYPE_SEM 9 /* posix semaphore */
68#define DTYPE_PTS 10 /* pseudo teletype master device */
69#define DTYPE_DEV 11 /* Device specific fd type */
70#define DTYPE_PROCDESC 12 /* process descriptor */
71#define DTYPE_EVENTFD 13 /* eventfd */
72#define DTYPE_TIMERFD 14 /* timerfd */
73
74#ifdef _KERNEL
75
76struct file;
77struct filecaps;
78struct kaiocb;
79struct kinfo_file;
80struct ucred;
81
82#define FOF_OFFSET 0x01 /* Use the offset in uio argument */
83#define FOF_NOLOCK 0x02 /* Do not take FOFFSET_LOCK */
84#define FOF_NEXTOFF_R 0x04 /* Also update f_nextoff[UIO_READ] */
85#define FOF_NEXTOFF_W 0x08 /* Also update f_nextoff[UIO_WRITE] */
86#define FOF_NOUPDATE 0x10 /* Do not update f_offset */
87off_t foffset_lock(struct file *fp, int flags);
88void foffset_lock_uio(struct file *fp, struct uio *uio, int flags);
89void foffset_unlock(struct file *fp, off_t val, int flags);
90void foffset_unlock_uio(struct file *fp, struct uio *uio, int flags);
91
92static inline off_t
93foffset_get(struct file *fp)
94{
95
96 return (foffset_lock(fp, FOF_NOLOCK));
97}
98
99typedef int fo_rdwr_t(struct file *fp, struct uio *uio,
100 struct ucred *active_cred, int flags,
101 struct thread *td);
102typedef int fo_truncate_t(struct file *fp, off_t length,
103 struct ucred *active_cred, struct thread *td);
104typedef int fo_ioctl_t(struct file *fp, u_long com, void *data,
105 struct ucred *active_cred, struct thread *td);
106typedef int fo_poll_t(struct file *fp, int events,
107 struct ucred *active_cred, struct thread *td);
108typedef int fo_kqfilter_t(struct file *fp, struct knote *kn);
109typedef int fo_stat_t(struct file *fp, struct stat *sb,
110 struct ucred *active_cred);
111typedef int fo_close_t(struct file *fp, struct thread *td);
112typedef int fo_chmod_t(struct file *fp, mode_t mode,
113 struct ucred *active_cred, struct thread *td);
114typedef int fo_chown_t(struct file *fp, uid_t uid, gid_t gid,
115 struct ucred *active_cred, struct thread *td);
116typedef int fo_sendfile_t(struct file *fp, int sockfd, struct uio *hdr_uio,
117 struct uio *trl_uio, off_t offset, size_t nbytes,
118 off_t *sent, int flags, struct thread *td);
119typedef int fo_seek_t(struct file *fp, off_t offset, int whence,
120 struct thread *td);
121typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif,
122 struct filedesc *fdp);
123typedef int fo_mmap_t(struct file *fp, vm_map_t map, vm_offset_t *addr,
124 vm_size_t size, vm_prot_t prot, vm_prot_t cap_maxprot,
125 int flags, vm_ooffset_t foff, struct thread *td);
126typedef int fo_aio_queue_t(struct file *fp, struct kaiocb *job);
127typedef int fo_add_seals_t(struct file *fp, int flags);
128typedef int fo_get_seals_t(struct file *fp, int *flags);
129typedef int fo_fallocate_t(struct file *fp, off_t offset, off_t len,
130 struct thread *td);
131typedef int fo_fspacectl_t(struct file *fp, int cmd,
132 off_t *offset, off_t *length, int flags,
133 struct ucred *active_cred, struct thread *td);
134typedef int fo_cmp_t(struct file *fp, struct file *fp1, struct thread *td);
135typedef int fo_spare_t(struct file *fp);
136typedef int fo_flags_t;
137
138struct fileops {
139 fo_rdwr_t *fo_read;
140 fo_rdwr_t *fo_write;
141 fo_truncate_t *fo_truncate;
142 fo_ioctl_t *fo_ioctl;
143 fo_poll_t *fo_poll;
144 fo_kqfilter_t *fo_kqfilter;
145 fo_stat_t *fo_stat;
146 fo_close_t *fo_close;
147 fo_chmod_t *fo_chmod;
148 fo_chown_t *fo_chown;
149 fo_sendfile_t *fo_sendfile;
150 fo_seek_t *fo_seek;
151 fo_fill_kinfo_t *fo_fill_kinfo;
152 fo_mmap_t *fo_mmap;
153 fo_aio_queue_t *fo_aio_queue;
154 fo_add_seals_t *fo_add_seals;
155 fo_get_seals_t *fo_get_seals;
156 fo_fallocate_t *fo_fallocate;
157 fo_fspacectl_t *fo_fspacectl;
158 fo_cmp_t *fo_cmp;
159 fo_spare_t *fo_spares[7]; /* Spare slots */
160 fo_flags_t fo_flags; /* DFLAG_* below */
161};
162
163#define DFLAG_PASSABLE 0x01 /* may be passed via unix sockets. */
164#define DFLAG_SEEKABLE 0x02 /* seekable / nonsequential */
165#endif /* _KERNEL */
166
167#if defined(_KERNEL) || defined(_WANT_FILE)
168/*
169 * Kernel descriptor table.
170 * One entry for each open kernel vnode and socket.
171 *
172 * Below is the list of locks that protects members in struct file.
173 *
174 * (a) f_vnode lock required (shared allows both reads and writes)
175 * (f) updated with atomics and blocking on sleepq
176 * (d) cdevpriv_mtx
177 * none not locked
178 */
179
180#if __BSD_VISIBLE
181struct fadvise_info {
182 int fa_advice; /* (f) FADV_* type. */
183 off_t fa_start; /* (f) Region start. */
184 off_t fa_end; /* (f) Region end. */
185};
186
187struct file {
188 volatile u_int f_flag; /* see fcntl.h */
189 volatile u_int f_count; /* reference count */
190 void *f_data; /* file descriptor specific data */
191 struct fileops *f_ops; /* File operations */
192 struct vnode *f_vnode; /* NULL or applicable vnode */
193 struct ucred *f_cred; /* associated credentials. */
194 short f_type; /* descriptor type */
195 short f_vnread_flags; /* (f) Sleep lock for f_offset */
196 /*
197 * DTYPE_VNODE specific fields.
198 */
199 union {
200 int16_t f_seqcount[2]; /* (a) Count of seq. reads and writes. */
201 int f_pipegen;
202 };
203 off_t f_nextoff[2]; /* next expected read/write offset. */
204 union {
205 struct cdev_privdata *fvn_cdevpriv;
206 /* (d) Private data for the cdev. */
207 struct fadvise_info *fvn_advice;
208 } f_vnun;
209 /*
210 * DFLAG_SEEKABLE specific fields
211 */
212 off_t f_offset;
213};
214
215#define f_cdevpriv f_vnun.fvn_cdevpriv
216#define f_advice f_vnun.fvn_advice
217
218#define FOFFSET_LOCKED 0x1
219#define FOFFSET_LOCK_WAITING 0x2
220#endif /* __BSD_VISIBLE */
221
222#endif /* _KERNEL || _WANT_FILE */
223
224/*
225 * Userland version of struct file, for sysctl
226 */
227#if __BSD_VISIBLE
228struct xfile {
229 ksize_t xf_size; /* size of struct xfile */
230 pid_t xf_pid; /* owning process */
231 uid_t xf_uid; /* effective uid of owning process */
232 int xf_fd; /* descriptor number */
233 int _xf_int_pad1;
234 kvaddr_t xf_file; /* address of struct file */
235 short xf_type; /* descriptor type */
236 short _xf_short_pad1;
237 int xf_count; /* reference count */
238 int xf_msgcount; /* references from message queue */
239 int _xf_int_pad2;
240 off_t xf_offset; /* file offset */
241 kvaddr_t xf_data; /* file descriptor specific data */
242 kvaddr_t xf_vnode; /* vnode pointer */
243 u_int xf_flag; /* flags (see fcntl.h) */
244 int _xf_int_pad3;
245 int64_t _xf_int64_pad[6];
246};
247#endif /* __BSD_VISIBLE */
248
249#ifdef _KERNEL
250
251extern struct fileops vnops;
252extern struct fileops badfileops;
253extern struct fileops path_fileops;
254extern struct fileops socketops;
255extern int maxfiles; /* kernel limit on number of open files */
256extern int maxfilesperproc; /* per process limit on number of open files */
257
258int fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp);
259int fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp,
260 vm_prot_t *maxprotp, struct file **fpp);
261int fget_read(struct thread *td, int fd, cap_rights_t *rightsp,
262 struct file **fpp);
263int fget_write(struct thread *td, int fd, cap_rights_t *rightsp,
264 struct file **fpp);
265int fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp,
266 int needfcntl, struct file **fpp);
267int _fdrop(struct file *fp, struct thread *td);
268int fget_remote(struct thread *td, struct proc *p, int fd, struct file **fpp);
269
270fo_rdwr_t invfo_rdwr;
271fo_truncate_t invfo_truncate;
272fo_ioctl_t invfo_ioctl;
273fo_poll_t invfo_poll;
274fo_kqfilter_t invfo_kqfilter;
275fo_chmod_t invfo_chmod;
276fo_chown_t invfo_chown;
277fo_sendfile_t invfo_sendfile;
278fo_stat_t vn_statfile;
279fo_sendfile_t vn_sendfile;
280fo_seek_t vn_seek;
281fo_fill_kinfo_t vn_fill_kinfo;
282fo_kqfilter_t vn_kqfilter_opath;
283int vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif);
284int file_kcmp_generic(struct file *fp1, struct file *fp2, struct thread *td);
285
286void finit(struct file *, u_int, short, void *, struct fileops *);
287void finit_vnode(struct file *, u_int, void *, struct fileops *);
288int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp,
289 struct vnode **vpp);
290int fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp,
291 struct vnode **vpp);
292int fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp,
293 struct filecaps *havecaps, struct vnode **vpp);
294int fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp,
295 struct vnode **vpp);
296int fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp,
297 struct vnode **vpp);
298int fgetvp_lookup_smr(struct nameidata *ndp, struct vnode **vpp, bool *fsearch);
299int fgetvp_lookup(struct nameidata *ndp, struct vnode **vpp);
300
301static __inline __result_use_check bool
302fhold(struct file *fp)
303{
304 return (refcount_acquire_checked(&fp->f_count));
305}
306
307#define fdrop(fp, td) ({ \
308 struct file *_fp; \
309 int _error; \
310 \
311 _error = 0; \
312 _fp = (fp); \
313 if (__predict_false(refcount_release(&_fp->f_count))) \
314 _error = _fdrop(_fp, td); \
315 _error; \
316})
317
318#define fdrop_close(fp, td) ({ \
319 struct file *_fp; \
320 int _error; \
321 \
322 _error = 0; \
323 _fp = (fp); \
324 if (__predict_true(refcount_release(&_fp->f_count))) \
325 _error = _fdrop(_fp, td); \
326 _error; \
327})
328
329static __inline fo_rdwr_t fo_read;
330static __inline fo_rdwr_t fo_write;
331static __inline fo_truncate_t fo_truncate;
332static __inline fo_ioctl_t fo_ioctl;
333static __inline fo_poll_t fo_poll;
334static __inline fo_kqfilter_t fo_kqfilter;
335static __inline fo_stat_t fo_stat;
336static __inline fo_close_t fo_close;
337static __inline fo_chmod_t fo_chmod;
338static __inline fo_chown_t fo_chown;
339static __inline fo_sendfile_t fo_sendfile;
340
341static __inline int
342fo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
343 int flags, struct thread *td)
344{
345
346 return ((*fp->f_ops->fo_read)(fp, uio, active_cred, flags, td));
347}
348
349static __inline int
350fo_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
351 int flags, struct thread *td)
352{
353
354 return ((*fp->f_ops->fo_write)(fp, uio, active_cred, flags, td));
355}
356
357static __inline int
358fo_truncate(struct file *fp, off_t length, struct ucred *active_cred,
359 struct thread *td)
360{
361
362 return ((*fp->f_ops->fo_truncate)(fp, length, active_cred, td));
363}
364
365static __inline int
366fo_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred,
367 struct thread *td)
368{
369
370 return ((*fp->f_ops->fo_ioctl)(fp, com, data, active_cred, td));
371}
372
373static __inline int
374fo_poll(struct file *fp, int events, struct ucred *active_cred,
375 struct thread *td)
376{
377
378 return ((*fp->f_ops->fo_poll)(fp, events, active_cred, td));
379}
380
381static __inline int
382fo_stat(struct file *fp, struct stat *sb, struct ucred *active_cred)
383{
384
385 return ((*fp->f_ops->fo_stat)(fp, sb, active_cred));
386}
387
388static __inline int
389fo_close(struct file *fp, struct thread *td)
390{
391
392 return ((*fp->f_ops->fo_close)(fp, td));
393}
394
395static __inline int
396fo_kqfilter(struct file *fp, struct knote *kn)
397{
398
399 return ((*fp->f_ops->fo_kqfilter)(fp, kn));
400}
401
402static __inline int
403fo_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
404 struct thread *td)
405{
406
407 return ((*fp->f_ops->fo_chmod)(fp, mode, active_cred, td));
408}
409
410static __inline int
411fo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
412 struct thread *td)
413{
414
415 return ((*fp->f_ops->fo_chown)(fp, uid, gid, active_cred, td));
416}
417
418static __inline int
419fo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
420 struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags,
421 struct thread *td)
422{
423
424 return ((*fp->f_ops->fo_sendfile)(fp, sockfd, hdr_uio, trl_uio, offset,
425 nbytes, sent, flags, td));
426}
427
428static __inline int
429fo_seek(struct file *fp, off_t offset, int whence, struct thread *td)
430{
431
432 return ((*fp->f_ops->fo_seek)(fp, offset, whence, td));
433}
434
435static __inline int
436fo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
437{
438
439 return ((*fp->f_ops->fo_fill_kinfo)(fp, kif, fdp));
440}
441
442static __inline int
443fo_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
444 vm_prot_t prot, vm_prot_t cap_maxprot, int flags, vm_ooffset_t foff,
445 struct thread *td)
446{
447
448 if (fp->f_ops->fo_mmap == NULL)
449 return (ENODEV);
450 return ((*fp->f_ops->fo_mmap)(fp, map, addr, size, prot, cap_maxprot,
451 flags, foff, td));
452}
453
454static __inline int
455fo_aio_queue(struct file *fp, struct kaiocb *job)
456{
457
458 return ((*fp->f_ops->fo_aio_queue)(fp, job));
459}
460
461static __inline int
462fo_add_seals(struct file *fp, int seals)
463{
464
465 if (fp->f_ops->fo_add_seals == NULL)
466 return (EINVAL);
467 return ((*fp->f_ops->fo_add_seals)(fp, seals));
468}
469
470static __inline int
471fo_get_seals(struct file *fp, int *seals)
472{
473
474 if (fp->f_ops->fo_get_seals == NULL)
475 return (EINVAL);
476 return ((*fp->f_ops->fo_get_seals)(fp, seals));
477}
478
479static __inline int
480fo_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td)
481{
482
483 if (fp->f_ops->fo_fallocate == NULL)
484 return (ENODEV);
485 return ((*fp->f_ops->fo_fallocate)(fp, offset, len, td));
486}
487
488static __inline int
489fo_fspacectl(struct file *fp, int cmd, off_t *offset, off_t *length,
490 int flags, struct ucred *active_cred, struct thread *td)
491{
492
493 if (fp->f_ops->fo_fspacectl == NULL)
494 return (ENODEV);
495 return ((*fp->f_ops->fo_fspacectl)(fp, cmd, offset, length, flags,
496 active_cred, td));
497}
498
499static __inline int
500fo_cmp(struct file *fp1, struct file *fp2, struct thread *td)
501{
502
503 if (fp1->f_ops->fo_cmp == NULL)
504 return (ENODEV);
505 return ((*fp1->f_ops->fo_cmp)(fp1, fp2, td));
506}
507
508#endif /* _KERNEL */
509
510#endif /* !SYS_FILE_H */