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