| 1 | /* $NetBSD: inode.h,v 1.75 2016/08/14 11:31:41 jdolecek Exp $ */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 1982, 1989, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. |
| 6 | * (c) UNIX System Laboratories, Inc. |
| 7 | * All or some portions of this file are derived from material licensed |
| 8 | * to the University of California by American Telephone and Telegraph |
| 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with |
| 10 | * the permission of UNIX System Laboratories, Inc. |
| 11 | * |
| 12 | * Redistribution and use in source and binary forms, with or without |
| 13 | * modification, are permitted provided that the following conditions |
| 14 | * are met: |
| 15 | * 1. Redistributions of source code must retain the above copyright |
| 16 | * notice, this list of conditions and the following disclaimer. |
| 17 | * 2. Redistributions in binary form must reproduce the above copyright |
| 18 | * notice, this list of conditions and the following disclaimer in the |
| 19 | * documentation and/or other materials provided with the distribution. |
| 20 | * 3. Neither the name of the University nor the names of its contributors |
| 21 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. |
| 23 | * |
| 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | * SUCH DAMAGE. |
| 35 | * |
| 36 | * @(#)inode.h 8.9 (Berkeley) 5/14/95 |
| 37 | */ |
| 38 | |
| 39 | #ifndef _UFS_UFS_INODE_H_ |
| 40 | #define _UFS_UFS_INODE_H_ |
| 41 | |
| 42 | #include <sys/vnode.h> |
| 43 | #include <ufs/ufs/dinode.h> |
| 44 | #include <ufs/ufs/dir.h> |
| 45 | #include <ufs/ufs/quota.h> |
| 46 | #include <ufs/ext2fs/ext2fs_dinode.h> |
| 47 | #include <ufs/ext2fs/ext2fs_extents.h> |
| 48 | #include <miscfs/genfs/genfs_node.h> |
| 49 | |
| 50 | /* |
| 51 | * Lookup result state (other than the result inode). This is |
| 52 | * currently stashed in the vnode between VOP_LOOKUP and directory |
| 53 | * operation VOPs, which is gross. |
| 54 | * |
| 55 | * XXX ulr_diroff is a lookup hint from the previos call of VOP_LOOKUP. |
| 56 | * probably it should not be here. |
| 57 | */ |
| 58 | struct ufs_lookup_results { |
| 59 | int32_t ulr_count; /* Size of free slot in directory. */ |
| 60 | doff_t ulr_endoff; /* End of useful stuff in directory. */ |
| 61 | doff_t ulr_diroff; /* Offset in dir, where we found last entry. */ |
| 62 | doff_t ulr_offset; /* Offset of free space in directory. */ |
| 63 | u_int32_t ulr_reclen; /* Size of found directory entry. */ |
| 64 | }; |
| 65 | |
| 66 | /* notyet XXX */ |
| 67 | #define UFS_CHECK_CRAPCOUNTER(dp) ((void)(dp)->i_crapcounter) |
| 68 | |
| 69 | /* |
| 70 | * Per-filesystem inode extensions. |
| 71 | */ |
| 72 | struct ffs_inode_ext { |
| 73 | daddr_t *ffs_snapblklist; /* Collect expunged snapshot blocks. */ |
| 74 | /* follow two fields are used by contiguous allocation code only. */ |
| 75 | daddr_t ffs_first_data_blk; /* first data block on disk. */ |
| 76 | daddr_t ffs_first_indir_blk; /* first indirect block on disk. */ |
| 77 | }; |
| 78 | |
| 79 | struct ext2fs_inode_ext { |
| 80 | daddr_t ext2fs_last_lblk; /* last logical block allocated */ |
| 81 | daddr_t ext2fs_last_blk; /* last block allocated on disk */ |
| 82 | struct ext4_extent_cache i_ext_cache; /* cache for ext4 extent */ |
| 83 | }; |
| 84 | |
| 85 | struct lfs_inode_ext; |
| 86 | |
| 87 | /* |
| 88 | * The inode is used to describe each active (or recently active) file in the |
| 89 | * UFS filesystem. It is composed of two types of information. The first part |
| 90 | * is the information that is needed only while the file is active (such as |
| 91 | * the identity of the file and linkage to speed its lookup). The second part |
| 92 | * is the permanent meta-data associated with the file which is read in |
| 93 | * from the permanent dinode from long term storage when the file becomes |
| 94 | * active, and is put back when the file is no longer being used. |
| 95 | */ |
| 96 | struct inode { |
| 97 | struct genfs_node i_gnode; |
| 98 | TAILQ_ENTRY(inode) i_nextsnap; /* snapshot file list. */ |
| 99 | struct vnode *i_vnode; /* Vnode associated with this inode. */ |
| 100 | struct ufsmount *i_ump; /* Mount point associated with this inode. */ |
| 101 | struct vnode *i_devvp; /* Vnode for block I/O. */ |
| 102 | u_int32_t i_flag; /* flags, see below */ |
| 103 | dev_t i_dev; /* Device associated with the inode. */ |
| 104 | ino_t i_number; /* The identity of the inode. */ |
| 105 | |
| 106 | union { /* Associated filesystem. */ |
| 107 | struct fs *fs; /* FFS */ |
| 108 | struct lfs *lfs; /* LFS */ |
| 109 | struct m_ext2fs *e2fs; /* EXT2FS */ |
| 110 | } inode_u; |
| 111 | #define i_fs inode_u.fs |
| 112 | #define i_lfs inode_u.lfs |
| 113 | #define i_e2fs inode_u.e2fs |
| 114 | |
| 115 | void *i_unused1; /* Unused. */ |
| 116 | struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ |
| 117 | u_quad_t i_modrev; /* Revision level for NFS lease. */ |
| 118 | struct lockf *i_lockf;/* Head of byte-level lock list. */ |
| 119 | |
| 120 | /* |
| 121 | * Side effects; used during (and after) directory lookup. |
| 122 | * XXX should not be here. |
| 123 | */ |
| 124 | struct ufs_lookup_results i_crap; |
| 125 | unsigned i_crapcounter; /* serial number for i_crap */ |
| 126 | |
| 127 | /* |
| 128 | * Inode extensions |
| 129 | */ |
| 130 | union { |
| 131 | /* Other extensions could go here... */ |
| 132 | struct ffs_inode_ext ffs; |
| 133 | struct ext2fs_inode_ext e2fs; |
| 134 | struct lfs_inode_ext *lfs; |
| 135 | } inode_ext; |
| 136 | #define i_snapblklist inode_ext.ffs.ffs_snapblklist |
| 137 | #define i_ffs_first_data_blk inode_ext.ffs.ffs_first_data_blk |
| 138 | #define i_ffs_first_indir_blk inode_ext.ffs.ffs_first_indir_blk |
| 139 | #define i_e2fs_last_lblk inode_ext.e2fs.ext2fs_last_lblk |
| 140 | #define i_e2fs_last_blk inode_ext.e2fs.ext2fs_last_blk |
| 141 | /* |
| 142 | * Copies from the on-disk dinode itself. |
| 143 | * |
| 144 | * These fields are currently only used by FFS and LFS, |
| 145 | * do NOT use them with ext2fs. |
| 146 | */ |
| 147 | u_int16_t i_mode; /* IFMT, permissions; see below. */ |
| 148 | int16_t i_nlink; /* File link count. */ |
| 149 | u_int64_t i_size; /* File byte count. */ |
| 150 | u_int32_t i_flags; /* Status flags (chflags). */ |
| 151 | int32_t i_gen; /* Generation number. */ |
| 152 | u_int32_t i_uid; /* File owner. */ |
| 153 | u_int32_t i_gid; /* File group. */ |
| 154 | u_int16_t i_omode; /* Old mode, for ufs_reclaim. */ |
| 155 | |
| 156 | struct dirhash *i_dirhash; /* Hashing for large directories */ |
| 157 | |
| 158 | /* |
| 159 | * The on-disk dinode itself. |
| 160 | */ |
| 161 | union { |
| 162 | struct ufs1_dinode *ffs1_din; /* 128 bytes of the on-disk dinode. */ |
| 163 | struct ufs2_dinode *ffs2_din; |
| 164 | struct ext2fs_dinode *e2fs_din; /* 128 bytes of the on-disk |
| 165 | dinode. */ |
| 166 | } i_din; |
| 167 | }; |
| 168 | |
| 169 | #define i_ffs1_atime i_din.ffs1_din->di_atime |
| 170 | #define i_ffs1_atimensec i_din.ffs1_din->di_atimensec |
| 171 | #define i_ffs1_blocks i_din.ffs1_din->di_blocks |
| 172 | #define i_ffs1_ctime i_din.ffs1_din->di_ctime |
| 173 | #define i_ffs1_ctimensec i_din.ffs1_din->di_ctimensec |
| 174 | #define i_ffs1_db i_din.ffs1_din->di_db |
| 175 | #define i_ffs1_flags i_din.ffs1_din->di_flags |
| 176 | #define i_ffs1_gen i_din.ffs1_din->di_gen |
| 177 | #define i_ffs1_gid i_din.ffs1_din->di_gid |
| 178 | #define i_ffs1_ib i_din.ffs1_din->di_ib |
| 179 | #define i_ffs1_mode i_din.ffs1_din->di_mode |
| 180 | #define i_ffs1_mtime i_din.ffs1_din->di_mtime |
| 181 | #define i_ffs1_mtimensec i_din.ffs1_din->di_mtimensec |
| 182 | #define i_ffs1_nlink i_din.ffs1_din->di_nlink |
| 183 | #define i_ffs1_rdev i_din.ffs1_din->di_rdev |
| 184 | #define i_ffs1_size i_din.ffs1_din->di_size |
| 185 | #define i_ffs1_uid i_din.ffs1_din->di_uid |
| 186 | #define i_ffs1_ouid i_din.ffs1_din->di_oldids[0] |
| 187 | #define i_ffs1_ogid i_din.ffs1_din->di_oldids[1] |
| 188 | |
| 189 | #define i_ffs2_atime i_din.ffs2_din->di_atime |
| 190 | #define i_ffs2_atimensec i_din.ffs2_din->di_atimensec |
| 191 | #define i_ffs2_birthtime i_din.ffs2_din->di_birthtime |
| 192 | #define i_ffs2_birthnsec i_din.ffs2_din->di_birthnsec |
| 193 | #define i_ffs2_blocks i_din.ffs2_din->di_blocks |
| 194 | #define i_ffs2_blksize i_din.ffs2_din->di_blksize |
| 195 | #define i_ffs2_ctime i_din.ffs2_din->di_ctime |
| 196 | #define i_ffs2_ctimensec i_din.ffs2_din->di_ctimensec |
| 197 | #define i_ffs2_db i_din.ffs2_din->di_db |
| 198 | #define i_ffs2_flags i_din.ffs2_din->di_flags |
| 199 | #define i_ffs2_gen i_din.ffs2_din->di_gen |
| 200 | #define i_ffs2_gid i_din.ffs2_din->di_gid |
| 201 | #define i_ffs2_ib i_din.ffs2_din->di_ib |
| 202 | #define i_ffs2_mode i_din.ffs2_din->di_mode |
| 203 | #define i_ffs2_mtime i_din.ffs2_din->di_mtime |
| 204 | #define i_ffs2_mtimensec i_din.ffs2_din->di_mtimensec |
| 205 | #define i_ffs2_nlink i_din.ffs2_din->di_nlink |
| 206 | #define i_ffs2_rdev i_din.ffs2_din->di_rdev |
| 207 | #define i_ffs2_size i_din.ffs2_din->di_size |
| 208 | #define i_ffs2_uid i_din.ffs2_din->di_uid |
| 209 | #define i_ffs2_kernflags i_din.ffs2_din->di_kernflags |
| 210 | #define i_ffs2_extsize i_din.ffs2_din->di_extsize |
| 211 | #define i_ffs2_extb i_din.ffs2_din->di_extb |
| 212 | |
| 213 | /* These flags are kept in i_flag. */ |
| 214 | #define IN_ACCESS 0x0001 /* Access time update request. */ |
| 215 | #define IN_CHANGE 0x0002 /* Inode change time update request. */ |
| 216 | #define IN_UPDATE 0x0004 /* Inode written to; update mtime. */ |
| 217 | #define IN_MODIFIED 0x0008 /* Inode has been modified. */ |
| 218 | #define IN_ACCESSED 0x0010 /* Inode has been accessed. */ |
| 219 | /* unused 0x0020 */ /* was IN_RENAME */ |
| 220 | #define IN_SHLOCK 0x0040 /* File has shared lock. */ |
| 221 | #define IN_EXLOCK 0x0080 /* File has exclusive lock. */ |
| 222 | /* unused 0x0100 */ /* was LFS-only IN_CLEANING */ |
| 223 | /* unused 0x0200 */ /* was LFS-only IN_ADIROP */ |
| 224 | #define IN_SPACECOUNTED 0x0400 /* Blocks to be freed in free count. */ |
| 225 | /* unused 0x0800 */ /* what was that? */ |
| 226 | /* unused 0x1000 */ /* was LFS-only IN_PAGING */ |
| 227 | #define IN_MODIFY 0x2000 /* Modification time update request. */ |
| 228 | /* unused 0x4000 */ /* was LFS-only IN_CDIROP */ |
| 229 | |
| 230 | #if defined(_KERNEL) |
| 231 | |
| 232 | /* |
| 233 | * The DIP macro is used to access fields in the dinode that are |
| 234 | * not cached in the inode itself. |
| 235 | */ |
| 236 | #define DIP(ip, field) \ |
| 237 | (((ip)->i_ump->um_fstype == UFS1) ? \ |
| 238 | (ip)->i_ffs1_##field : (ip)->i_ffs2_##field) |
| 239 | |
| 240 | #define DIP_ASSIGN(ip, field, value) \ |
| 241 | do { \ |
| 242 | if ((ip)->i_ump->um_fstype == UFS1) \ |
| 243 | (ip)->i_ffs1_##field = (value); \ |
| 244 | else \ |
| 245 | (ip)->i_ffs2_##field = (value); \ |
| 246 | } while(0) |
| 247 | |
| 248 | #define DIP_ADD(ip, field, value) \ |
| 249 | do { \ |
| 250 | if ((ip)->i_ump->um_fstype == UFS1) \ |
| 251 | (ip)->i_ffs1_##field += (value); \ |
| 252 | else \ |
| 253 | (ip)->i_ffs2_##field += (value); \ |
| 254 | } while(0) |
| 255 | |
| 256 | #define SHORTLINK(ip) \ |
| 257 | (((ip)->i_ump->um_fstype == UFS1) ? \ |
| 258 | (void *)(ip)->i_ffs1_db : (void *)(ip)->i_ffs2_db) |
| 259 | |
| 260 | |
| 261 | /* |
| 262 | * Structure used to pass around logical block paths generated by |
| 263 | * ufs_getlbns and used by truncate and bmap code. |
| 264 | */ |
| 265 | struct indir { |
| 266 | daddr_t in_lbn; /* Logical block number. */ |
| 267 | int in_off; /* Offset in buffer. */ |
| 268 | int in_exists; /* Flag if the block exists. */ |
| 269 | }; |
| 270 | |
| 271 | /* Convert between inode pointers and vnode pointers. */ |
| 272 | #define VTOI(vp) ((struct inode *)(vp)->v_data) |
| 273 | #define ITOV(ip) ((ip)->i_vnode) |
| 274 | |
| 275 | /* This overlays the fid structure (see fstypes.h). */ |
| 276 | struct ufid { |
| 277 | u_int16_t ufid_len; /* Length of structure. */ |
| 278 | u_int16_t ufid_pad; /* Force 32-bit alignment. */ |
| 279 | int32_t ufid_gen; /* Generation number. */ |
| 280 | ino_t ufid_ino; /* File number (ino). */ |
| 281 | }; |
| 282 | #endif /* _KERNEL */ |
| 283 | |
| 284 | #endif /* !_UFS_UFS_INODE_H_ */ |
| 285 | |