1 /*        $NetBSD: inode.h,v 1.79 2022/03/23 13:06:06 andvar 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 previous 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 dinode.h. */
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            * Data for extended attribute modification.
160            */
161           u_char      *i_ea_area;       /* Pointer to malloced copy of EA area */
162           unsigned  i_ea_len; /* Length of i_ea_area */
163           int         i_ea_error;       /* First errno in transaction */
164           int         i_ea_refs;        /* Number of users of EA area */
165 
166           /*
167            * The on-disk dinode itself.
168            */
169           union {
170                     struct    ufs1_dinode *ffs1_din;        /* 128 bytes of the on-disk dinode. */
171                     struct    ufs2_dinode *ffs2_din;
172                     struct    ext2fs_dinode *e2fs_din; /* 128 bytes of the on-disk
173                                                                dinode. */
174           } i_din;
175 };
176 
177 #define   i_ffs1_atime                  i_din.ffs1_din->di_atime
178 #define   i_ffs1_atimensec    i_din.ffs1_din->di_atimensec
179 #define   i_ffs1_blocks                 i_din.ffs1_din->di_blocks
180 #define   i_ffs1_ctime                  i_din.ffs1_din->di_ctime
181 #define   i_ffs1_ctimensec    i_din.ffs1_din->di_ctimensec
182 #define   i_ffs1_db           i_din.ffs1_din->di_db
183 #define   i_ffs1_flags                  i_din.ffs1_din->di_flags
184 #define   i_ffs1_gen                    i_din.ffs1_din->di_gen
185 #define   i_ffs1_gid                    i_din.ffs1_din->di_gid
186 #define   i_ffs1_ib           i_din.ffs1_din->di_ib
187 #define   i_ffs1_mode                   i_din.ffs1_din->di_mode
188 #define   i_ffs1_mtime                  i_din.ffs1_din->di_mtime
189 #define   i_ffs1_mtimensec    i_din.ffs1_din->di_mtimensec
190 #define   i_ffs1_nlink                  i_din.ffs1_din->di_nlink
191 #define   i_ffs1_rdev                   i_din.ffs1_din->di_rdev
192 #define   i_ffs1_size                   i_din.ffs1_din->di_size
193 #define   i_ffs1_uid                    i_din.ffs1_din->di_uid
194 #define   i_ffs1_ouid                   i_din.ffs1_din->di_oldids[0]
195 #define   i_ffs1_ogid                   i_din.ffs1_din->di_oldids[1]
196 
197 #define   i_ffs2_atime                  i_din.ffs2_din->di_atime
198 #define   i_ffs2_atimensec    i_din.ffs2_din->di_atimensec
199 #define   i_ffs2_birthtime    i_din.ffs2_din->di_birthtime
200 #define   i_ffs2_birthnsec    i_din.ffs2_din->di_birthnsec
201 #define   i_ffs2_blocks                 i_din.ffs2_din->di_blocks
202 #define   i_ffs2_blksize                i_din.ffs2_din->di_blksize
203 #define   i_ffs2_ctime                  i_din.ffs2_din->di_ctime
204 #define   i_ffs2_ctimensec    i_din.ffs2_din->di_ctimensec
205 #define   i_ffs2_db           i_din.ffs2_din->di_db
206 #define   i_ffs2_flags                  i_din.ffs2_din->di_flags
207 #define   i_ffs2_gen                    i_din.ffs2_din->di_gen
208 #define   i_ffs2_gid                    i_din.ffs2_din->di_gid
209 #define   i_ffs2_ib           i_din.ffs2_din->di_ib
210 #define   i_ffs2_mode                   i_din.ffs2_din->di_mode
211 #define   i_ffs2_mtime                  i_din.ffs2_din->di_mtime
212 #define   i_ffs2_mtimensec    i_din.ffs2_din->di_mtimensec
213 #define   i_ffs2_nlink                  i_din.ffs2_din->di_nlink
214 #define   i_ffs2_rdev                   i_din.ffs2_din->di_rdev
215 #define   i_ffs2_size                   i_din.ffs2_din->di_size
216 #define   i_ffs2_uid                    i_din.ffs2_din->di_uid
217 #define   i_ffs2_kernflags    i_din.ffs2_din->di_kernflags
218 #define   i_ffs2_extsize                i_din.ffs2_din->di_extsize
219 #define   i_ffs2_extb                   i_din.ffs2_din->di_extb
220 
221 /* These flags are kept in i_flag. */
222 #define   IN_ACCESS 0x0001              /* Access time update request. */
223 #define   IN_CHANGE 0x0002              /* Inode change time update request. */
224 #define   IN_UPDATE 0x0004              /* Inode written to; update mtime. */
225 #define   IN_MODIFIED         0x0008              /* Inode has been modified. */
226 #define   IN_ACCESSED         0x0010              /* Inode has been accessed. */
227 /*        unused              0x0020 */ /* was IN_RENAME */
228 #define   IN_SHLOCK 0x0040              /* File has shared lock. */
229 #define   IN_EXLOCK 0x0080              /* File has exclusive lock. */
230 /*        unused              0x0100 */ /* was LFS-only IN_CLEANING */
231 /*        unused              0x0200 */ /* was LFS-only IN_ADIROP */
232 #define   IN_SPACECOUNTED     0x0400              /* Blocks to be freed in free count. */
233 /*        unused              0x0800 */ /* what was that? */
234 /*        unused              0x1000 */ /* was LFS-only IN_PAGING */
235 #define   IN_MODIFY 0x2000              /* Modification time update request. */
236 /*        unused              0x4000 */ /* was LFS-only IN_CDIROP */
237 
238 #if defined(_KERNEL)
239 
240 /*
241  * This macro does not differentiate between having extattrs and having
242  * extattrs containing ACLS, but that's ok since it is only used to
243  * determine if we are eligible for namei cache and we can be pessimistic
244  */
245 #define HAS_ACLS(ip) \
246     ((ip)->i_ump->um_fstype == UFS2 && (ip)->i_ffs2_extsize > 0)
247 
248 /*
249  * The DIP macro is used to access fields in the dinode that are
250  * not cached in the inode itself.
251  */
252 #define   DIP(ip, field) \
253           (((ip)->i_ump->um_fstype == UFS1) ? \
254           (ip)->i_ffs1_##field : (ip)->i_ffs2_##field)
255 
256 #define   DIP_ASSIGN(ip, field, value)                                          \
257           do {                                                                            \
258                     if ((ip)->i_ump->um_fstype == UFS1)                         \
259                               (ip)->i_ffs1_##field = (value);                             \
260                     else                                                                  \
261                               (ip)->i_ffs2_##field = (value);                             \
262           } while(0)
263 
264 #define   DIP_ADD(ip, field, value)                                             \
265           do {                                                                            \
266                     if ((ip)->i_ump->um_fstype == UFS1)                         \
267                               (ip)->i_ffs1_##field += (value);                  \
268                     else                                                                  \
269                               (ip)->i_ffs2_##field += (value);                  \
270           } while(0)
271 
272 #define    SHORTLINK(ip) \
273           (((ip)->i_ump->um_fstype == UFS1) ? \
274           (void *)(ip)->i_ffs1_db : (void *)(ip)->i_ffs2_db)
275 
276 
277 /*
278  * Structure used to pass around logical block paths generated by
279  * ufs_getlbns and used by truncate and bmap code.
280  */
281 struct indir {
282           daddr_t in_lbn;               /* Logical block number. */
283           int       in_off;                       /* Offset in buffer. */
284           int       in_exists;                    /* Flag if the block exists. */
285 };
286 
287 /* Convert between inode pointers and vnode pointers. */
288 #define   VTOI(vp)  ((struct inode *)(vp)->v_data)
289 #define   ITOV(ip)  ((ip)->i_vnode)
290 
291 /* This overlays the fid structure (see fstypes.h). */
292 struct ufid {
293           u_int16_t ufid_len; /* Length of structure. */
294           u_int16_t ufid_pad; /* Force 32-bit alignment. */
295           int32_t     ufid_gen;         /* Generation number. */
296           ino_t     ufid_ino; /* File number (ino). */
297 };
298 #endif /* _KERNEL */
299 
300 #endif /* !_UFS_UFS_INODE_H_ */
301