1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 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 #ifndef FAT_VNODE_H
32 #define FAT_VNODE_H
33
34
35 // Modified to support the Haiku FAT driver.
36
37 #ifdef FS_SHELL
38 #include "fssh_api_wrapper.h"
39 #else
40 #include <fs_interface.h>
41 #include <lock.h>
42 #endif
43
44 #include "sys/buf.h"
45 #include "sys/bufobj.h"
46 #include "sys/lockmgr.h"
47 #include "sys/namei.h"
48 #include "sys/ucred.h"
49
50 #include "fs/msdosfs/direntry.h"
51 #include "fs/msdosfs/denode.h"
52
53 #include "dosfs.h"
54
55
56 // In the Haiku port, one struct vnode per volume is set up to represent its device file.
57 // It will have type VBLK. All other struct vnodes (those that actually represent
58 // files on the volume) will have type VREG or VDIR.
59 enum vtype { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO, VBAD, VMARKER };
60 #define VLASTTYPE VMARKER
61
62 enum vstate { VSTATE_UNINITIALIZED, VSTATE_CONSTRUCTED, VSTATE_DESTROYING, VSTATE_DEAD };
63 #define VLASTSTATE VSTATE_DEAD
64
65 /*
66 * Reading or writing any of these items requires holding the appropriate lock.
67 *
68 * Lock reference:
69 * u - Only a reference to the vnode is needed to read.
70 * v - vnode lock
71 *
72 */
73 struct vnode {
74 /*
75 * Fields which define the identity of the vnode.
76 */
77 enum vtype v_type : 8; /* u vnode type */
78 enum vstate v_state : 8; /* u vnode state */
79 void* v_data; /* u private data for fs */
80
81 /*
82 * Filesystem instance stuff
83 */
84 struct mount* v_mount; /* u ptr to vfs we are in */
85
86 /*
87 * Type specific fields, only one applies to any given vnode.
88 */
89 union {
90 struct cdev* v_rdev; /* v device (VCHR, VBLK) */
91 };
92
93 /*
94 * Locking
95 */
96 struct lock v_lock; /* u (if fs don't have one) */
97 struct lock* v_vnlock; /* u pointer to vnode lock */
98
99 /*
100 * The machinery of being a vnode
101 */
102 struct bufobj v_bufobj; /* * Buffer cache object */
103
104 /*
105 * Hooks for various subsystems and features.
106 */
107 u_short v_vflag; /* v vnode flags */
108
109 // Members added for Haiku port
110 ino_t v_parent; /* v inode of parent directory */
111 const char* v_mime; /* v mime type for VREG nodes, otherwise NULL */
112 void* v_cache; /* v file cache for VREG nodes, otherwise NULL */
113 void* v_file_map; /* v file map for VREG nodes, otherwise NULL */
114 bool v_resizing; /* v disable IO (see comment in dosfs_wstat) */
115 bool v_sync; /* v use synchronous IO */
116 };
117
118
119 /*
120 * Vnode flags.
121 * VV flags are protected by the vnode lock and live in v_vflag
122 */
123 #define VV_ROOT 0x0001 /* root of its filesystem */
124
125 /*
126 * Flags for ioflag.
127 */
128 #define IO_SYNC 0x0080 /* do I/O synchronously */
129
130 /*
131 * Flags for accmode_t.
132 */
133 #define VEXEC 000000000100 /* execute/search permission */
134 #define VWRITE 000000000200 /* write permission */
135 #define VREAD 000000000400 /* read permission */
136
137 #define VREF(vp) vref(vp)
138
139 #define VN_LOCK_AREC(vp) lockallowrecurse((vp)->v_vnlock)
140
141
142 /*! Verify vp is exclusively (i.e. write) locked.
143
144 */
145 static inline void
assert_vop_elocked(struct vnode * vp,const char * str)146 assert_vop_elocked(struct vnode* vp, const char* str)
147 {
148 if (vp == NULL)
149 return;
150 ASSERT_WRITE_LOCKED_RW_LOCK(&vp->v_vnlock->haikuRW);
151 }
152
153
154 #define ASSERT_VOP_ELOCKED(vp, str) assert_vop_elocked((vp), (str))
155 // In FreeBSD, this verifies that vp is either write-locked or read-locked. In Haiku, there is no
156 // equivalent assert.
157 #define ASSERT_VOP_LOCKED(vp, str) ((void)0)
158
159 #define DOINGASYNC(vp) (((vp)->v_mount->mnt_flag & MNT_ASYNC) != 0)
160
161 // FreeBSD would generate vnode_if.h, vnode_if_typedef.h, and vnode_if_newproto.h at build time
162 // and #include them here (the latter two indirectly via the first).
163 // For the Haiku port, vnode_if.h was generated manually by running a script:
164 // sys/tools/vnode_if.awk sys/kern/vnode_if.src -h
165 // and vnode_if_typedef.h by running:
166 // sys/tools/vnode_if.awk sys/kern/vnode_if.src -q
167 // and vnode_if_newproto.h by running:
168 // sys/tools/vnode_if.awk sys/kern/vnode_if.src -p
169 // Modified excerpts from these headers are pasted below.
170
171 // This struct is referenced by the ported code but has no effect in the Haiku port.
172 struct vop_vector {
173 };
174
175
176 static inline int
VOP_ACCESS(struct vnode * vp,accmode_t accmode,struct ucred * cred,thread_id td)177 VOP_ACCESS(struct vnode* vp, accmode_t accmode, struct ucred* cred, thread_id td)
178 {
179 struct mount* bsdVolume = (struct mount*)vp->v_mount;
180
181 int mode = 0;
182 if ((accmode & VREAD) != 0)
183 mode |= R_OK;
184 if ((accmode & VWRITE) != 0)
185 mode |= W_OK;
186 if ((accmode & VEXEC) != 0)
187 mode |= X_OK;
188
189 return B_TO_POSIX_ERROR(_dosfs_access(bsdVolume, vp, mode));
190 }
191
192
193 static inline int
VOP_UNLOCK(struct vnode * vp)194 VOP_UNLOCK(struct vnode* vp)
195 {
196 lockmgr(vp->v_vnlock, LK_RELEASE, NULL);
197
198 return 0;
199 }
200
201
202 // End of vnode_if.h content
203
204 typedef int (*vn_get_ino_t)(struct mount*, void*, int, struct vnode**);
205
206 typedef int vfs_hash_cmp_t(struct vnode* vp, void* arg);
207
208 int vfs_hash_get(struct mount* mp, uint64 hash, int flags, thread_id td, struct vnode** vpp,
209 vfs_hash_cmp_t* fn, void* arg);
210
211 int vfs_hash_insert(struct vnode* vp, uint64 hash, int flags, thread_id td, struct vnode** vpp,
212 vfs_hash_cmp_t* fn, void* arg);
213 void vfs_hash_rehash(struct vnode* vp, uint64 hash);
214 void vfs_hash_remove(struct vnode* vp);
215
216 struct componentname;
217
218 void cache_enter(struct vnode* dvp, struct vnode* vp, struct componentname* cnp);
219
220 int getnewvnode(const char* tag, struct mount* mp, struct vop_vector* vops, struct vnode** vpp);
221
222
223 /*! In FreeBSD, this tells the VFS to add vp to its list of mp's nodes.
224 In Haiku, the equivalent actions are done automatically as part of get_vnode / publish_vnode.
225 */
226 static inline int
insmntque(struct vnode * vp,struct mount * mp)227 insmntque(struct vnode* vp, struct mount* mp)
228 {
229 return 0;
230 }
231
232
233 /*! In FreeBSD, this generates a serial number based on system time. The driver uses it to
234 initialize denode::de_modrev. However, in the Haiku port, de_modrev is ignored.
235 */
236 static inline u_quad_t
init_va_filerev(void)237 init_va_filerev(void)
238 {
239 return 0;
240 }
241
242
243 /*! Put a ref to vp and write-unlock it.
244
245 */
246 static inline void
vput(struct vnode * vp)247 vput(struct vnode* vp)
248 {
249 put_vnode(vp->v_mount->mnt_fsvolume, VTODE(vp)->de_inode);
250
251 rw_lock_write_unlock(&vp->v_vnlock->haikuRW);
252 }
253
254
255 /*! Put a ref to vp.
256
257 */
258 static inline void
vrele(struct vnode * vp)259 vrele(struct vnode* vp)
260 {
261 put_vnode(vp->v_mount->mnt_fsvolume, VTODE(vp)->de_inode);
262 }
263
264
265 /*! Get a ref to vp.
266
267 */
268 static inline void
vref(struct vnode * vp)269 vref(struct vnode* vp)
270 {
271 acquire_vnode(vp->v_mount->mnt_fsvolume, VTODE(vp)->de_inode);
272 }
273
274
275 /*! Get the node ref count from the VFS. Not implemented in Haiku port (function is used in
276 driver but only for debug output).
277 */
278 static __inline int
vrefcnt(struct vnode * vp)279 vrefcnt(struct vnode* vp)
280 {
281 return -1;
282 }
283
284
285 int vget(struct vnode* vp, int flags);
286
287
288 /*! Prepare the VFS to discard vp.
289
290 */
291 static inline void
vgone(struct vnode * vp)292 vgone(struct vnode* vp)
293 {
294 remove_vnode(vp->v_mount->mnt_fsvolume, VTODE(vp)->de_inode);
295 }
296
297
298 int vtruncbuf(struct vnode* vp, off_t length, int blksize);
299 int vn_fsync_buf(struct vnode* vp, int waitfor);
300
301 int vn_vget_ino_gen(struct vnode* vp, vn_get_ino_t alloc, void* alloc_arg, int lkflags,
302 struct vnode** rvp);
303 void vfs_timestamp(struct timespec* tsp);
304
305
306 static inline void
vn_set_state(struct vnode * vp,enum vstate state)307 vn_set_state(struct vnode* vp, enum vstate state)
308 {
309 vp->v_state = state;
310 }
311
312
313 #endif // FAT_VNODE_H
314