xref: /openbsd/sys/ufs/ufs/inode.h (revision 81fb472f)
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