1 /* $OpenBSD: inode.h,v 1.54 2024/02/03 18:51:58 beck Exp $ */ 2 /* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * (c) UNIX System Laboratories, Inc. 8 * All or some portions of this file are derived from material licensed 9 * to the University of California by American Telephone and Telegraph 10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 11 * the permission of UNIX System Laboratories, Inc. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)inode.h 8.5 (Berkeley) 7/8/94 38 */ 39 40 #include <sys/buf.h> 41 #include <sys/lock.h> 42 #include <ufs/ufs/dinode.h> 43 #include <ufs/ufs/dir.h> 44 #include <ufs/ext2fs/ext2fs_dinode.h> 45 #include <ufs/ext2fs/ext2fs_extents.h> 46 47 48 /* 49 * Per-filesystem inode extensions. 50 */ 51 struct ext2fs_inode_ext { 52 u_int32_t ext2fs_last_lblk; /* last logical blk allocated */ 53 u_int32_t ext2fs_last_blk; /* last blk allocated on disk */ 54 u_int32_t ext2fs_effective_uid; /* effective inode uid */ 55 u_int32_t ext2fs_effective_gid; /* effective inode gid */ 56 struct ext4_extent_cache ext2fs_extent_cache; 57 }; 58 59 /* 60 * The inode is used to describe each active (or recently active) file in the 61 * UFS filesystem. It is composed of two types of information. The first part 62 * is the information that is needed only while the file is active (such as 63 * the identity of the file and linkage to speed its lookup). The second part 64 * is * the permanent meta-data associated with the file which is read in 65 * from the permanent dinode from long term storage when the file becomes 66 * active, and is put back when the file is no longer being used. 67 */ 68 struct inode { 69 LIST_ENTRY(inode) i_hash; /* Hash chain */ 70 struct vnode *i_vnode;/* Vnode associated with this inode. */ 71 struct ufsmount *i_ump; 72 u_int32_t i_flag; /* flags, see below */ 73 dev_t i_dev; /* Device associated with the inode. */ 74 ufsino_t i_number; /* The identity of the inode. */ 75 int i_effnlink; /* i_nlink when I/O completes */ 76 77 union { /* Associated filesystem. */ 78 struct fs *fs; /* FFS */ 79 struct m_ext2fs *e2fs; /* EXT2FS */ 80 } inode_u; 81 82 #define i_fs inode_u.fs 83 #define i_e2fs inode_u.e2fs 84 85 struct cluster_info i_ci; 86 struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ 87 u_quad_t i_modrev; /* Revision level for NFS lease. */ 88 struct lockf_state *i_lockf; /* Byte-level lock state. */ 89 struct rrwlock i_lock;/* Inode lock */ 90 91 /* 92 * Side effects; used during directory lookup. 93 */ 94 int32_t i_count; /* Size of free slot in directory. */ 95 doff_t i_endoff; /* End of useful stuff in directory. */ 96 doff_t i_diroff; /* Offset in dir, where we found last entry. */ 97 doff_t i_offset; /* Offset of free space in directory. */ 98 ufsino_t i_ino; /* Inode number of found directory. */ 99 u_int32_t i_reclen; /* Size of found directory entry. */ 100 /* 101 * Inode extensions 102 */ 103 union { 104 /* Other extensions could go here... */ 105 struct ext2fs_inode_ext e2fs; 106 struct dirhash *dirhash; 107 } inode_ext; 108 109 #define i_e2fs_last_lblk inode_ext.e2fs.ext2fs_last_lblk 110 #define i_e2fs_last_blk inode_ext.e2fs.ext2fs_last_blk 111 #define i_e2fs_uid inode_ext.e2fs.ext2fs_effective_uid 112 #define i_e2fs_gid inode_ext.e2fs.ext2fs_effective_gid 113 #define i_e2fs_ext_cache inode_ext.e2fs.ext2fs_extent_cache 114 #define i_dirhash inode_ext.dirhash 115 116 /* 117 * The on-disk dinode itself. 118 */ 119 union { 120 struct ufs1_dinode *ffs1_din; 121 struct ufs2_dinode *ffs2_din; 122 struct ext2fs_dinode *e2fs_din; 123 } dinode_u; 124 125 #define i_din1 dinode_u.ffs1_din 126 #define i_din2 dinode_u.ffs2_din 127 #define i_e2din dinode_u.e2fs_din 128 129 struct inode_vtbl *i_vtbl; 130 }; 131 132 struct inode_vtbl { 133 int (* iv_truncate)(struct inode *, off_t, int, 134 struct ucred *); 135 int (* iv_update)(struct inode *, int waitfor); 136 int (* iv_inode_alloc)(struct inode *, mode_t mode, 137 struct ucred *, struct vnode **); 138 int (* iv_inode_free)(struct inode *, ufsino_t ino, mode_t mode); 139 int (* iv_buf_alloc)(struct inode *, off_t, int, struct ucred *, 140 int, struct buf **); 141 int (* iv_bufatoff)(struct inode *, off_t offset, char **res, 142 struct buf **bpp); 143 }; 144 145 #define UFS_TRUNCATE(ip, off, flags, cred) \ 146 ((ip)->i_vtbl->iv_truncate)((ip), (off), (flags), (cred)) 147 148 #define UFS_UPDATE(ip, sync) \ 149 ((ip)->i_vtbl->iv_update)((ip), (sync)) 150 151 #define UFS_INODE_ALLOC(pip, mode, cred, vpp) \ 152 ((pip)->i_vtbl->iv_inode_alloc)((pip), (mode), (cred), (vpp)) 153 154 #define UFS_INODE_FREE(pip, ino, mode) \ 155 ((pip)->i_vtbl->iv_inode_free)((pip), (ino), (mode)) 156 157 #define UFS_BUF_ALLOC(ip, startoffset, size, cred, flags, bpp) \ 158 ((ip)->i_vtbl->iv_buf_alloc)((ip), (startoffset), (size), (cred), \ 159 (flags), (bpp)) 160 161 #define UFS_BUFATOFF(ip, offset, res, bpp) \ 162 ((ip)->i_vtbl->iv_bufatoff)((ip), (offset), (res), (bpp)) 163 164 #define i_ffs1_atime i_din1->di_atime 165 #define i_ffs1_atimensec i_din1->di_atimensec 166 #define i_ffs1_blocks i_din1->di_blocks 167 #define i_ffs1_ctime i_din1->di_ctime 168 #define i_ffs1_ctimensec i_din1->di_ctimensec 169 #define i_ffs1_db i_din1->di_db 170 #define i_ffs1_flags i_din1->di_flags 171 #define i_ffs1_gen i_din1->di_gen 172 #define i_ffs1_gid i_din1->di_gid 173 #define i_ffs1_ib i_din1->di_ib 174 #define i_ffs1_mode i_din1->di_mode 175 #define i_ffs1_mtime i_din1->di_mtime 176 #define i_ffs1_mtimensec i_din1->di_mtimensec 177 #define i_ffs1_nlink i_din1->di_nlink 178 #define i_ffs1_rdev i_din1->di_rdev 179 #define i_ffs1_shortlink i_din1->di_shortlink 180 #define i_ffs1_size i_din1->di_size 181 #define i_ffs1_uid i_din1->di_uid 182 183 #define i_ffs2_atime i_din2->di_atime 184 #define i_ffs2_atimensec i_din2->di_atimensec 185 #define i_ffs2_blocks i_din2->di_blocks 186 #define i_ffs2_blksize i_din2->di_blksize 187 #define i_ffs2_ctime i_din2->di_ctime 188 #define i_ffs2_ctimensec i_din2->di_ctimensec 189 #define i_ffs2_db i_din2->di_db 190 #define i_ffs2_flags i_din2->di_flags 191 #define i_ffs2_gen i_din2->di_gen 192 #define i_ffs2_gid i_din2->di_gid 193 #define i_ffs2_ib i_din2->di_ib 194 #define i_ffs2_mode i_din2->di_mode 195 #define i_ffs2_mtime i_din2->di_mtime 196 #define i_ffs2_mtimensec i_din2->di_mtimensec 197 #define i_ffs2_nlink i_din2->di_nlink 198 #define i_ffs2_rdev i_din2->di_rdev 199 #define i_ffs2_size i_din2->di_size 200 #define i_ffs2_uid i_din2->di_uid 201 202 #ifndef _KERNEL 203 /* 204 * These are here purely for backwards compatibility for userland. 205 * They allow direct references to FFS structures using the old names. 206 */ 207 #define i_atime i_din1->di_atime 208 #define i_atimensec i_din1->di_atimensec 209 #define i_blocks i_din1->di_blocks 210 #define i_ctime i_din1->di_ctime 211 #define i_ctimensec i_din1->di_ctimensec 212 #define i_db i_din1->di_db 213 #define i_flags i_din1->di_flags 214 #define i_gen i_din1->di_gen 215 #define i_gid i_din1->di_gid 216 #define i_ib i_din1->di_ib 217 #define i_mode i_din1->di_mode 218 #define i_mtime i_din1->di_mtime 219 #define i_mtimensec i_din1->di_mtimensec 220 #define i_nlink i_din1->di_nlink 221 #define i_rdev i_din1->di_rdev 222 #define i_shortlink i_din1->di_shortlink 223 #define i_size i_din1->di_size 224 #define i_uid i_din1->di_uid 225 #endif /* _KERNEL */ 226 227 #define i_e2fs_mode i_e2din->e2di_mode 228 #define i_e2fs_size i_e2din->e2di_size 229 #define i_e2fs_atime i_e2din->e2di_atime 230 #define i_e2fs_ctime i_e2din->e2di_ctime 231 #define i_e2fs_mtime i_e2din->e2di_mtime 232 #define i_e2fs_dtime i_e2din->e2di_dtime 233 #define i_e2fs_nlink i_e2din->e2di_nlink 234 #define i_e2fs_nblock i_e2din->e2di_nblock 235 #define i_e2fs_flags i_e2din->e2di_flags 236 #define i_e2fs_blocks i_e2din->e2di_blocks 237 #define i_e2fs_gen i_e2din->e2di_gen 238 #define i_e2fs_facl i_e2din->e2di_facl 239 #define i_e2fs_size_hi i_e2din->e2di_size_hi 240 #define i_e2fs_faddr i_e2din->e2di_faddr 241 #define i_e2fs_nblock_hi i_e2din->e2di_nblock_hi 242 #define i_e2fs_faddr_hi i_e2din->e2di_faddr_hi 243 #define i_e2fs_uid_low i_e2din->e2di_uid_low 244 #define i_e2fs_gid_low i_e2din->e2di_gid_low 245 #define i_e2fs_uid_high i_e2din->e2di_uid_high 246 #define i_e2fs_gid_high i_e2din->e2di_gid_high 247 248 /* These flags are kept in i_flag. */ 249 #define IN_ACCESS 0x0001 /* Access time update request. */ 250 #define IN_CHANGE 0x0002 /* Inode change time update request. */ 251 #define IN_UPDATE 0x0004 /* Modification time update request */ 252 #define IN_MODIFIED 0x0008 /* Inode has been modified. */ 253 #define IN_RENAME 0x0010 /* Inode is being renamed. */ 254 #define IN_SHLOCK 0x0020 /* File has shared lock. */ 255 #define IN_EXLOCK 0x0040 /* File has exclusive lock. */ 256 #define IN_LAZYMOD 0x0080 /* Modified, but don't write yet. */ 257 #define IN_HASHED 0x0100 /* Inode is on the hash chain */ 258 259 #define i_devvp i_ump->um_devvp 260 261 #ifdef _KERNEL 262 263 /* 264 * The DIP macros are used to access fields in the dinode. 265 */ 266 267 #ifdef FFS2 268 #define DIP(ip, field) \ 269 (((ip)->i_ump->um_fstype == UM_UFS1) ? \ 270 (ip)->i_ffs1_##field : (ip)->i_ffs2_##field) 271 #else 272 #define DIP(ip, field) \ 273 ((ip)->i_ffs1_##field) 274 #endif 275 276 #ifdef FFS2 277 #define DIP_OP(ip, field, op, value) \ 278 do { \ 279 if ((ip)->i_ump->um_fstype == UM_UFS1) \ 280 (ip)->i_ffs1_##field op (value); \ 281 else \ 282 (ip)->i_ffs2_##field op (value); \ 283 } while (0) 284 #else 285 #define DIP_OP(ip, field, op, value) \ 286 do { \ 287 (ip)->i_ffs1_##field op (value); \ 288 } while (0) 289 #endif 290 291 #define DIP_ASSIGN(ip, field, value) DIP_OP(ip, field, =, value) 292 #define DIP_ADD(ip, field, value) DIP_OP(ip, field, +=, value) 293 #define DIP_AND(ip, field, value) DIP_OP(ip, field, &=, value) 294 #define DIP_OR(ip, field, value) DIP_OP(ip, field, |=, value) 295 296 #ifdef FFS2 297 #define SHORTLINK(ip) \ 298 (((ip)->i_ump->um_fstype == UM_UFS1) ? \ 299 (caddr_t)(ip)->i_ffs1_db : (caddr_t)(ip)->i_ffs2_db) 300 #else 301 #define SHORTLINK(ip) \ 302 ((caddr_t)(ip)->i_ffs1_db) 303 #endif 304 305 /* 306 * Structure used to pass around logical block paths generated by 307 * ufs_getlbns and used by truncate and bmap code. 308 */ 309 struct indir { 310 daddr_t in_lbn; /* Logical block number. */ 311 int in_off; /* Offset in buffer. */ 312 int in_exists; /* Flag if the block exists. */ 313 }; 314 315 /* Convert between inode pointers and vnode pointers. */ 316 #define VTOI(vp) ((struct inode *)(vp)->v_data) 317 #define ITOV(ip) ((ip)->i_vnode) 318 319 #define EXT2FS_ITIMES(ip) do { \ 320 if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \ 321 (ip)->i_flag |= IN_MODIFIED; \ 322 if ((ip)->i_flag & IN_ACCESS) \ 323 (ip)->i_e2fs_atime = gettime(); \ 324 if ((ip)->i_flag & IN_UPDATE) \ 325 (ip)->i_e2fs_mtime = gettime(); \ 326 if ((ip)->i_flag & IN_CHANGE) { \ 327 (ip)->i_e2fs_ctime = gettime(); \ 328 (ip)->i_modrev++; \ 329 } \ 330 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \ 331 } \ 332 } while (0) 333 334 /* Determine if soft dependencies are being done */ 335 #define DOINGASYNC(vp) ((vp)->v_mount->mnt_flag & MNT_ASYNC) 336 337 /* This overlays the fid structure (see mount.h). */ 338 struct ufid { 339 u_int16_t ufid_len; /* Length of structure. */ 340 u_int16_t ufid_pad; /* Force 32-bit alignment. */ 341 ufsino_t ufid_ino; /* File number (ino). */ 342 u_int32_t ufid_gen; /* Generation number. */ 343 }; 344 #endif /* _KERNEL */ 345