1 /* $OpenBSD: inode.h,v 1.27 2004/07/13 21:04:29 millert 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 <ufs/ufs/dinode.h> 42 #include <ufs/ufs/dir.h> 43 #include <ufs/ext2fs/ext2fs_dinode.h> 44 45 /* 46 * Per-filesystem inode extensions. 47 */ 48 struct ext2fs_inode_ext { 49 ufs1_daddr_t ext2fs_last_lblk; /* last logical block allocated */ 50 ufs1_daddr_t ext2fs_last_blk; /* last block allocated on disk */ 51 u_int32_t ext2fs_effective_uid; /* effective inode uid */ 52 u_int32_t ext2fs_effective_gid; /* effective inode gid */ 53 }; 54 55 /* 56 * The inode is used to describe each active (or recently active) file in the 57 * UFS filesystem. It is composed of two types of information. The first part 58 * is the information that is needed only while the file is active (such as 59 * the identity of the file and linkage to speed its lookup). The second part 60 * is * the permanent meta-data associated with the file which is read in 61 * from the permanent dinode from long term storage when the file becomes 62 * active, and is put back when the file is no longer being used. 63 */ 64 struct inode { 65 LIST_ENTRY(inode) i_hash; /* Hash chain */ 66 struct vnode *i_vnode;/* Vnode associated with this inode. */ 67 struct ufsmount *i_ump; 68 u_int32_t i_flag; /* flags, see below */ 69 dev_t i_dev; /* Device associated with the inode. */ 70 ino_t i_number; /* The identity of the inode. */ 71 int i_effnlink; /* i_nlink when I/O completes */ 72 73 union { /* Associated filesystem. */ 74 struct fs *fs; /* FFS */ 75 struct lfs *lfs; /* LFS */ 76 struct m_ext2fs *e2fs; /* EXT2FS */ 77 } inode_u; 78 #define i_fs inode_u.fs 79 #define i_lfs inode_u.lfs 80 #define i_e2fs inode_u.e2fs 81 82 struct cluster_info i_ci; 83 struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ 84 u_quad_t i_modrev; /* Revision level for NFS lease. */ 85 struct lockf *i_lockf;/* Head of byte-level lock list. */ 86 struct lock i_lock; /* Inode lock */ 87 88 /* 89 * Side effects; used during directory lookup. 90 */ 91 int32_t i_count; /* Size of free slot in directory. */ 92 doff_t i_endoff; /* End of useful stuff in directory. */ 93 doff_t i_diroff; /* Offset in dir, where we found last entry. */ 94 doff_t i_offset; /* Offset of free space in directory. */ 95 ino_t i_ino; /* Inode number of found directory. */ 96 u_int32_t i_reclen; /* Size of found directory entry. */ 97 /* 98 * Inode extensions 99 */ 100 union { 101 /* Other extensions could go here... */ 102 struct ext2fs_inode_ext e2fs; 103 struct dirhash *dirhash; 104 } inode_ext; 105 106 #define i_e2fs_last_lblk inode_ext.e2fs.ext2fs_last_lblk 107 #define i_e2fs_last_blk inode_ext.e2fs.ext2fs_last_blk 108 #define i_e2fs_uid inode_ext.e2fs.ext2fs_effective_uid 109 #define i_e2fs_gid inode_ext.e2fs.ext2fs_effective_gid 110 #define i_dirhash inode_ext.dirhash 111 112 /* 113 * The on-disk dinode itself. 114 */ 115 union { 116 struct ufs1_dinode ffs1_din; 117 struct ext2fs_dinode e2fs_din; 118 } dinode_u; 119 #define i_din1 dinode_u.ffs1_din 120 #define i_e2din dinode_u.e2fs_din 121 122 struct inode_vtbl *i_vtbl; 123 }; 124 125 struct inode_vtbl { 126 int (* iv_truncate)(struct inode *, off_t, int, 127 struct ucred *); 128 int (* iv_update)(struct inode *, struct timespec *, struct timespec *, 129 int waitfor); 130 int (* iv_inode_alloc)(struct inode *, mode_t mode, 131 struct ucred *, struct vnode **); 132 int (* iv_inode_free)(struct inode *, ino_t ino, mode_t mode); 133 int (* iv_buf_alloc)(struct inode *, off_t, int, struct ucred *, 134 int, struct buf **); 135 int (* iv_bufatoff)(struct inode *, off_t offset, char **res, 136 struct buf **bpp); 137 }; 138 139 #define UFS_TRUNCATE(ip, off, flags, cred) \ 140 ((ip)->i_vtbl->iv_truncate)((ip), (off), (flags), (cred)) 141 142 #define UFS_UPDATE(ip, sync) \ 143 ((ip)->i_vtbl->iv_update)((ip), NULL, NULL, (sync)) 144 145 #define UFS_UPDATE2(ip, atime, mtime, sync) \ 146 ((ip)->i_vtbl->iv_update)((ip), (atime), (mtime), (sync)) 147 148 #define UFS_INODE_ALLOC(pip, mode, cred, vpp) \ 149 ((pip)->i_vtbl->iv_inode_alloc)((pip), (mode), (cred), (vpp)) 150 151 #define UFS_INODE_FREE(pip, ino, mode) \ 152 ((pip)->i_vtbl->iv_inode_free)((pip), (ino), (mode)) 153 154 #define UFS_BUF_ALLOC(ip, startoffset, size, cred, flags, bpp) \ 155 ((ip)->i_vtbl->iv_buf_alloc)((ip), (startoffset), (size), (cred), \ 156 (flags), (bpp)) 157 158 #define UFS_BUFATOFF(ip, offset, res, bpp) \ 159 ((ip)->i_vtbl->iv_bufatoff)((ip), (offset), (res), (bpp)) 160 161 162 #define i_ffs_atime i_din1.di_atime 163 #define i_ffs_atimensec i_din1.di_atimensec 164 #define i_ffs_blocks i_din1.di_blocks 165 #define i_ffs_ctime i_din1.di_ctime 166 #define i_ffs_ctimensec i_din1.di_ctimensec 167 #define i_ffs_db i_din1.di_db 168 #define i_ffs_flags i_din1.di_flags 169 #define i_ffs_gen i_din1.di_gen 170 #define i_ffs_gid i_din1.di_gid 171 #define i_ffs_ib i_din1.di_ib 172 #define i_ffs_mode i_din1.di_mode 173 #define i_ffs_mtime i_din1.di_mtime 174 #define i_ffs_mtimensec i_din1.di_mtimensec 175 #define i_ffs_nlink i_din1.di_nlink 176 #define i_ffs_rdev i_din1.di_rdev 177 #define i_ffs_shortlink i_din1.di_shortlink 178 #define i_ffs_size i_din1.di_size 179 #define i_ffs_uid i_din1.di_uid 180 #define i_size i_din1.di_size 181 182 #ifndef _KERNEL 183 /* 184 * These are here purely for backwards compatibility for userland. 185 * They allow direct references to FFS structures using the old names. 186 */ 187 188 #define i_atime i_din1.di_atime 189 #define i_atimensec i_din1.di_atimensec 190 #define i_blocks i_din1.di_blocks 191 #define i_ctime i_din1.di_ctime 192 #define i_ctimensec i_din1.di_ctimensec 193 #define i_db i_din1.di_db 194 #define i_flags i_din1.di_flags 195 #define i_gen i_din1.di_gen 196 #define i_gid i_din1.di_gid 197 #define i_ib i_din1.di_ib 198 #define i_mode i_din1.di_mode 199 #define i_mtime i_din1.di_mtime 200 #define i_mtimensec i_din1.di_mtimensec 201 #define i_nlink i_din1.di_nlink 202 #define i_rdev i_din1.di_rdev 203 #define i_shortlink i_din1.di_shortlink 204 #define i_size i_din1.di_size 205 #define i_uid i_din1.di_uid 206 #endif /* _KERNEL */ 207 208 #define i_e2fs_mode i_e2din.e2di_mode 209 #define i_e2fs_size i_e2din.e2di_size 210 #define i_e2fs_atime i_e2din.e2di_atime 211 #define i_e2fs_ctime i_e2din.e2di_ctime 212 #define i_e2fs_mtime i_e2din.e2di_mtime 213 #define i_e2fs_dtime i_e2din.e2di_dtime 214 #define i_e2fs_nlink i_e2din.e2di_nlink 215 #define i_e2fs_nblock i_e2din.e2di_nblock 216 #define i_e2fs_flags i_e2din.e2di_flags 217 #define i_e2fs_blocks i_e2din.e2di_blocks 218 #define i_e2fs_gen i_e2din.e2di_gen 219 #define i_e2fs_facl i_e2din.e2di_facl 220 #define i_e2fs_dacl i_e2din.e2di_dacl 221 #define i_e2fs_faddr i_e2din.e2di_faddr 222 #define i_e2fs_nfrag i_e2din.e2di_nfrag 223 #define i_e2fs_fsize i_e2din.e2di_fsize 224 #define i_e2fs_uid_low i_e2din.e2di_uid_low 225 #define i_e2fs_gid_low i_e2din.e2di_gid_low 226 #define i_e2fs_uid_high i_e2din.e2di_uid_high 227 #define i_e2fs_gid_high i_e2din.e2di_gid_high 228 229 /* These flags are kept in i_flag. */ 230 #define IN_ACCESS 0x0001 /* Access time update request. */ 231 #define IN_CHANGE 0x0002 /* Inode change time update request. */ 232 #define IN_UPDATE 0x0004 /* Modification time update request */ 233 #define IN_MODIFIED 0x0008 /* Inode has been modified. */ 234 #define IN_RENAME 0x0010 /* Inode is being renamed. */ 235 #define IN_SHLOCK 0x0020 /* File has shared lock. */ 236 #define IN_EXLOCK 0x0040 /* File has exclusive lock. */ 237 238 #define i_devvp i_ump->um_devvp 239 240 #ifdef _KERNEL 241 242 /* 243 * The DIP macro is used to access fields in the dinode that are 244 * not cached in the inode itself. 245 */ 246 #define DIP(ip, field) \ 247 (((ip)->i_ump->um_fstype == UM_UFS1) ? \ 248 (ip)->i_din1->d##field : (ip)->i_din2->d##field) 249 250 #if 0 251 #define MAXSYMLINKLEN(ip) \ 252 ((ip)->i_ump->um_fstype == UM_UFS1) ? \ 253 ((NDADDR + NIADDR) * sizeof(ufs1_daddr_t)) : \ 254 ((NDADDR + NIADDR) * sizeof(ufs2_daddr_t)) 255 #define SHORTLINK(ip) \ 256 (((ip)->i_ump->um_fstype == UM_UFS1) ? \ 257 (caddr_t)(ip)->i_din1->di_db : (caddr_t)(ip)->i_din2->di_db) 258 #endif 259 260 /* 261 * Structure used to pass around logical block paths generated by 262 * ufs_getlbns and used by truncate and bmap code. 263 */ 264 struct indir { 265 daddr_t in_lbn; /* Logical block number. */ 266 int in_off; /* Offset in buffer. */ 267 int in_exists; /* Flag if the block exists. */ 268 }; 269 270 /* Convert between inode pointers and vnode pointers. */ 271 #define VTOI(vp) ((struct inode *)(vp)->v_data) 272 #define ITOV(ip) ((ip)->i_vnode) 273 274 #define FFS_ITIMES(ip, t1, t2) { \ 275 if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \ 276 (ip)->i_flag |= IN_MODIFIED; \ 277 if ((ip)->i_flag & IN_ACCESS) \ 278 (ip)->i_ffs_atime = (t1)->tv_sec; \ 279 if ((ip)->i_flag & IN_UPDATE) { \ 280 (ip)->i_ffs_mtime = (t2)->tv_sec; \ 281 (ip)->i_modrev++; \ 282 } \ 283 if ((ip)->i_flag & IN_CHANGE) \ 284 (ip)->i_ffs_ctime = time.tv_sec; \ 285 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \ 286 } \ 287 } 288 289 #define EXT2FS_ITIMES(ip, t1, t2) { \ 290 if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \ 291 (ip)->i_flag |= IN_MODIFIED; \ 292 if ((ip)->i_flag & IN_ACCESS) \ 293 (ip)->i_e2fs_atime = (t1)->tv_sec; \ 294 if ((ip)->i_flag & IN_UPDATE) { \ 295 (ip)->i_e2fs_mtime = (t2)->tv_sec; \ 296 (ip)->i_modrev++; \ 297 } \ 298 if ((ip)->i_flag & IN_CHANGE) \ 299 (ip)->i_e2fs_ctime = time.tv_sec; \ 300 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \ 301 } \ 302 } 303 304 #define ITIMES(ip, t1, t2) { \ 305 if (IS_EXT2_VNODE((ip)->i_vnode)) { \ 306 EXT2FS_ITIMES(ip, t1, t2); \ 307 } else { \ 308 FFS_ITIMES(ip, t1, t2); \ 309 } \ 310 } 311 312 /* Determine if soft dependencies are being done */ 313 #ifdef FFS_SOFTUPDATES 314 #define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP) 315 #else 316 #define DOINGSOFTDEP(vp) (0) 317 #endif 318 #define DOINGASYNC(vp) ((vp)->v_mount->mnt_flag & MNT_ASYNC) 319 320 /* This overlays the fid structure (see mount.h). */ 321 struct ufid { 322 u_int16_t ufid_len; /* Length of structure. */ 323 u_int16_t ufid_pad; /* Force 32-bit alignment. */ 324 ino_t ufid_ino; /* File number (ino). */ 325 int32_t ufid_gen; /* Generation number. */ 326 }; 327 #endif /* _KERNEL */ 328