xref: /haiku/src/add-ons/kernel/file_systems/fat/bsd/sys/vnode.h (revision 909af08f4328301fbdef1ffb41f566c3b5bec0c7)
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
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
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
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
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
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
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
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
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
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
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
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