XenevaOS
Loading...
Searching...
No Matches
file.h
Go to the documentation of this file.
1#ifndef __DCL_STUB_BaseHdr_linux_file_h__
2#define __DCL_STUB_BaseHdr_linux_file_h__
3
4/*
5 * DCL <linux/file.h> -- the struct file helpers that used to live only in
6 * this scaffolding.
7 *
8 * mkh.sh created the original so clang would stop reporting a missing include
9 * and start reporting what was *used* from it, which is exactly what
10 * happened: virtio_console.c's port_fops_open() calls nonseekable_open(), and
11 * the include that resolves it upstream is <linux/fs.h> -- the one header DCL
12 * does not edit. So what this header owes is spelled here, in mainline's own
13 * home for it: mainline splits fs/open.c's file helpers out to a header
14 * rather than making every caller reach through fs.h, and DCL has one more
15 * reason than mainline does to want that split.
16 *
17 * <linux/cdev.h> includes this file, which is how a character-device driver
18 * reaches it: port_fops_open() is a .cdev open, and a driver should not have
19 * to name a second header for a helper its first one already owes it.
20 * It is safe to include anywhere -- it pulls <linux/fs.h>, <linux/fcntl.h>,
21 * <linux/capability.h>, <linux/pid.h> and nothing else, and specifically not
22 * <linux/kobject.h>, which is why the bodies live in
23 * DCL/linux_cdev_shim.c rather than somewhere that already includes cdev.h.
24 * None of the four can reach <linux/sched.h>, which is the property that
25 * matters here: see the note at the bottom of fcntl.h.
26 */
27
28#include <linux/fs.h>
29
30/*
31 * <linux/fcntl.h> for the O_* flags, and it is the same situation as
32 * nonseekable_open() below: mainline's <linux/fs.h> includes fcntl.h, and
33 * DCL's fs.h is pinned so it includes nothing.
34 *
35 * This header rather than any other is where they land, because mainline's
36 * file.h is where get_unused_fd_flags() is declared and drm_lease.c:532
37 * calls it with `get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK))`
38 * -- one line needing the function and its flag vocabulary from the same
39 * place. drm_lease.c:494 uses the two flags alone, for the same reason.
40 *
41 * It is safe here, and not only because fcntl.h has stopped including
42 * <linux/types.h> (see the note at the bottom of fcntl.h for why that
43 * mattered to <Fs/vfs.h>): this header is included by linux_cdev_shim.c at
44 * line 9, before <Fs/vfs.h> at line 11, and the flags are now a leaf -- two
45 * headers of #defines between here and nothing.
46 */
47#include <linux/fcntl.h>
48
49/*
50 * <linux/pid.h>, for the same reason fcntl.h above is here: mainline's
51 * <linux/fs.h> includes it (fs.h:20), and a drm source reaches it through
52 * that chain without naming it.
53 *
54 * The consumer is drm_file.c:1030's `pid_task(pid, PIDTYPE_TGID)`, which
55 * needs the enum constant and the function. None of the nine headers
56 * drm_file.c does name pulls pid.h in -- module.h, file.h, pci.h, slab.h and
57 * anon_inodes.h are all checked against mainline's own copies.
58 *
59 * Safe to reach from here for the reason fcntl.h is: pid.h includes nothing
60 * at all, so it cannot reach <linux/sched.h> and its `current` macro.
61 *
62 * capable() is deliberately *not* here, though mainline's fs.h carries
63 * capability.h as well. drm_ioctl.c needs capable() and does not include
64 * this header, whereas it and both other consumers do include
65 * <linux/pci.h>; so capability.h is carried once, there, rather than twice
66 * from two different justifications.
67 */
68#include <linux/pid.h>
69
70/*
71 * FMODE_LSEEK / FMODE_PREAD / FMODE_PWRITE -- the bits nonseekable_open()
72 * clears. mainline's values (include/linux/fs.h:112-116, 1<<2, 1<<3, 1<<4);
73 * they are named by nothing else in this tree, so there was no second reading
74 * of the word to reconcile against -- mem.c ORs a device's whole fmode into
75 * the same field without naming a bit.
76 */
77#define FMODE_LSEEK 0x00000004
78#define FMODE_PREAD 0x00000008
79#define FMODE_PWRITE 0x00000010
80
81/*
82 * nonseekable_open() -- clear the seek bits on a file that has no .llseek.
83 * mainline: fs/open.c:1560, declared in <linux/fs.h>, and its body is the
84 * mask and a 0. Returning 0 is the whole of its contract (mainline has no
85 * failure arm), and port_fops_open() ignores the value anyway. The inode
86 * parameter is mainline's and unused there too.
87 *
88 * Body in DCL/linux_cdev_shim.c.
89 */
90int nonseekable_open(struct inode* inode, struct file* filp);
91
92/*
93 * get_file() -- take a reference. mainline has this in <linux/fs.h> (the
94 * header this file exists to stand beside without editing); it has to be
95 * here because <linux/dma-buf.h> -- which includes this header at line 17 --
96 * spells get_dma_buf() as an inline that calls it, so the declaration must
97 * already be in scope for that parse. DCL files carry no refcount; the
98 * reference is the pointer, and nothing in the tree ever drops it.
99 */
100static inline void get_file(struct file* f)
101{
102 (void)f;
103}
104
105/*
106 * fput() -- drop one reference to a struct file. mainline's body is
107 * fs/file_table.c's delayed-teardown machinery; DCL carries no refcount for
108 * it to decrement -- the pointer is the reference, the same trade get_file()
109 * above makes -- so the body in DCL/linux_cdev_shim.c is the (void)file.
110 * Declared here because mainline declares it here (include/linux/file.h:18),
111 * and both call sites (drm_gem.c:1139, drm_atomic_uapi.c:1576) reach this
112 * header.
113 */
114void fput(struct file* file);
115
116#include <linux/cleanup.h> /* __cleanup -- the fd_destructor attribute below */
117
118/*
119 * struct fd and the CLASS(fd, ...) plumbing -- mainline's fdget() result
120 * type, carried here because drm_syncobj.c:710 uses it, and this header is
121 * where mainline puts it (include/linux/file.h).
122 *
123 * There is no file-descriptor table in this kernel: no __fdget(), no fget(),
124 * and nothing that maps an unsigned int to a struct file. So the constructor
125 * answers an empty fd for every input, which is not a stub pretending to
126 * work -- it is the correct answer, and drm_syncobj.c is written for it:
127 * :710 `if (fd_empty(f)) return -EINVAL;` is the first thing that function
128 * does after the declaration, so an fd-based syncobj import returns -EINVAL
129 * and touches nothing behind it.
130 *
131 * fd_destructor is empty for the same reason fd_constructor returns empty:
132 * there is no reference to drop, because there was never one to take. It is
133 * spelled by name rather than built with DEFINE_FREE(), because CLASS()'s
134 * expansion looks for `name##_destructor` specifically -- see the note on
135 * CLASS() in <linux/cleanup.h>.
136 *
137 * The mainline struct also carries `flags` (FMODE_PATH and friends), kept
138 * here so a later fdget() could be dropped in without the type changing.
139 */
140struct fd {
141 struct file* file;
142 unsigned int flags;
143};
144
145#define fd_empty(f) ((f).file == NULL)
146#define fd_file(f) ((f).file)
147#define fd_valid(f) (fd_file(f) != NULL)
148
149#define fd_t struct fd
150
151/*
152 * Takes a void*, not a struct fd: the compiler calls a cleanup function with
153 * the *address* of the variable it is attached to, and passing the struct by
154 * value produced "'cleanup' function 'fd_destructor' parameter has type
155 * 'struct fd' which is incompatible with type 'struct fd *'". mainline's
156 * DEFINE_FREE() spells the same thing the same way -- `_type _T = *(_type *)p`.
157 */
158static inline void fd_destructor(void* p)
159{
160 (void)p;
161}
162
163static inline struct fd fd_constructor(unsigned int fd)
164{
165 (void)fd;
166 return (struct fd){ 0 };
167}
168
169/*
170 * ── the fd table: mainline's file.h owns it, this kernel does not ───────
171 *
172 * An fd is an index into current->files; get_unused_fd_flags(),
173 * fd_install() and put_unused_fd() are the three moves mainline's VFS makes
174 * a struct file with. DCL has neither a files_struct nor an fget() that
175 * could turn an index back into a file (see the struct fd note above), so
176 * the bodies in DCL/linux_cdev_shim.c are the honest answers: the allocation
177 * answers -ENOSYS -- no table, not a full one -- and the two void calls have
178 * nothing to install into or give back. That is also what makes them safe to
179 * leave empty: every caller (drm_lease.c:532, drm_syncobj.c:669,
180 * drm_atomic_uapi.c:1400, drm_prime.c:516) tests `fd < 0` and unwinds before
181 * its install/put arm.
182 *
183 * file_clone_open() is the same missing VFS one step earlier: mainline keeps
184 * it in <linux/fs.h> (:2527) as a dentry_open() of the source file, and there
185 * is no dentry tree here to open through. Its one caller (drm_lease.c:551)
186 * checks the ERR_PTR the body in linux_cdev_shim.c returns.
187 */
189void put_unused_fd(unsigned int fd);
190void fd_install(unsigned int fd, struct file* file);
191struct file* file_clone_open(struct file* file);
192
193#endif /* __DCL_STUB_BaseHdr_linux_file_h__ */
void fd_install(unsigned int fd, struct file *file)
struct file * file_clone_open(struct file *file)
void fput(struct file *file)
int nonseekable_open(struct inode *inode, struct file *filp)
void put_unused_fd(unsigned int fd)
int get_unused_fd_flags(unsigned flags)
uint8_t flags
Definition virtio.h:0
const char * f
Definition drm_print.h:205
Definition file.h:140
struct file * file
Definition file.h:141
unsigned int flags
Definition file.h:142
Definition fs.h:142
Definition fs.h:183