1 /* $OpenBSD: inode.h,v 1.35 2007/06/02 00:45:50 pedro 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
46 /*
47 * Per-filesystem inode extensions.
48 */
49 struct ext2fs_inode_ext {
50 int32_t ext2fs_last_lblk; /* last logical block allocated */
51 int32_t ext2fs_last_blk; /* last block allocated on disk */
52 u_int32_t ext2fs_effective_uid; /* effective inode uid */
53 u_int32_t ext2fs_effective_gid; /* effective inode gid */
54 };
55
56 /*
57 * The inode is used to describe each active (or recently active) file in the
58 * UFS filesystem. It is composed of two types of information. The first part
59 * is the information that is needed only while the file is active (such as
60 * the identity of the file and linkage to speed its lookup). The second part
61 * is * the permanent meta-data associated with the file which is read in
62 * from the permanent dinode from long term storage when the file becomes
63 * active, and is put back when the file is no longer being used.
64 */
65 struct inode {
66 LIST_ENTRY(inode) i_hash; /* Hash chain */
67 struct vnode *i_vnode;/* Vnode associated with this inode. */
68 struct ufsmount *i_ump;
69 u_int32_t i_flag; /* flags, see below */
70 dev_t i_dev; /* Device associated with the inode. */
71 ino_t i_number; /* The identity of the inode. */
72 int i_effnlink; /* i_nlink when I/O completes */
73
74 union { /* Associated filesystem. */
75 struct fs *fs; /* FFS */
76 struct m_ext2fs *e2fs; /* EXT2FS */
77 } inode_u;
78
79 #define i_fs inode_u.fs
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 ufs2_dinode *ffs2_din;
118 struct ext2fs_dinode *e2fs_din;
119 } dinode_u;
120
121 #define i_din1 dinode_u.ffs1_din
122 #define i_din2 dinode_u.ffs2_din
123 #define i_e2din dinode_u.e2fs_din
124
125 struct inode_vtbl *i_vtbl;
126 };
127
128 struct inode_vtbl {
129 int (* iv_truncate)(struct inode *, off_t, int,
130 struct ucred *);
131 int (* iv_update)(struct inode *, struct timespec *, struct timespec *,
132 int waitfor);
133 int (* iv_inode_alloc)(struct inode *, mode_t mode,
134 struct ucred *, struct vnode **);
135 int (* iv_inode_free)(struct inode *, ino_t ino, mode_t mode);
136 int (* iv_buf_alloc)(struct inode *, off_t, int, struct ucred *,
137 int, struct buf **);
138 int (* iv_bufatoff)(struct inode *, off_t offset, char **res,
139 struct buf **bpp);
140 };
141
142 #define UFS_TRUNCATE(ip, off, flags, cred) \
143 ((ip)->i_vtbl->iv_truncate)((ip), (off), (flags), (cred))
144
145 #define UFS_UPDATE(ip, sync) \
146 ((ip)->i_vtbl->iv_update)((ip), NULL, NULL, (sync))
147
148 #define UFS_UPDATE2(ip, atime, mtime, sync) \
149 ((ip)->i_vtbl->iv_update)((ip), (atime), (mtime), (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_dacl i_e2din->e2di_dacl
240 #define i_e2fs_faddr i_e2din->e2di_faddr
241 #define i_e2fs_nfrag i_e2din->e2di_nfrag
242 #define i_e2fs_fsize i_e2din->e2di_fsize
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
257 #define i_devvp i_ump->um_devvp
258
259 #ifdef _KERNEL
260
261 /*
262 * The DIP macros are used to access fields in the dinode.
263 */
264 #define DIP(ip, field) \
265 (((ip)->i_ump->um_fstype == UM_UFS1) ? \
266 (ip)->i_ffs1_##field : (ip)->i_ffs2_##field)
267
268 #define DIP_ASSIGN(ip, field, value) \
269 do { \
270 if ((ip)->i_ump->um_fstype == UM_UFS1) \
271 (ip)->i_ffs1_##field = (value); \
272 else \
273 (ip)->i_ffs2_##field = (value); \
274 } while (0)
275
276 #define DIP_ADD(ip, field, value) \
277 do { \
278 if ((ip)->i_ump->um_fstype == UM_UFS1) \
279 (ip)->i_ffs1_##field += (value); \
280 else \
281 (ip)->i_ffs2_##field += (value); \
282 } while (0)
283
284 #define SHORTLINK(ip) \
285 (((ip)->i_ump->um_fstype == UM_UFS1) ? \
286 (caddr_t)(ip)->i_ffs1_db : (caddr_t)(ip)->i_ffs2_db)
287
288 /*
289 * Structure used to pass around logical block paths generated by
290 * ufs_getlbns and used by truncate and bmap code.
291 */
292 struct indir {
293 daddr_t in_lbn; /* Logical block number. */
294 int in_off; /* Offset in buffer. */
295 int in_exists; /* Flag if the block exists. */
296 };
297
298 /* Convert between inode pointers and vnode pointers. */
299 #define VTOI(vp) ((struct inode *)(vp)->v_data)
300 #define ITOV(ip) ((ip)->i_vnode)
301
302 #define FFS_ITIMES(ip, t1, t2) { \
303 if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
304 (ip)->i_flag |= IN_MODIFIED; \
305 if ((ip)->i_flag & IN_ACCESS) \
306 DIP_ASSIGN((ip), atime, (t1)->tv_sec); \
307 if ((ip)->i_flag & IN_UPDATE) { \
308 DIP_ASSIGN((ip), mtime, (t2)->tv_sec); \
309 (ip)->i_modrev++; \
310 } \
311 if ((ip)->i_flag & IN_CHANGE) \
312 DIP_ASSIGN((ip), ctime, time_second); \
313 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
314 } \
315 }
316
317 #define EXT2FS_ITIMES(ip, t1, t2) { \
318 if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
319 (ip)->i_flag |= IN_MODIFIED; \
320 if ((ip)->i_flag & IN_ACCESS) \
321 (ip)->i_e2fs_atime = (t1)->tv_sec; \
322 if ((ip)->i_flag & IN_UPDATE) { \
323 (ip)->i_e2fs_mtime = (t2)->tv_sec; \
324 (ip)->i_modrev++; \
325 } \
326 if ((ip)->i_flag & IN_CHANGE) \
327 (ip)->i_e2fs_ctime = time_second; \
328 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
329 } \
330 }
331
332 #define ITIMES(ip, t1, t2) { \
333 if (IS_EXT2_VNODE((ip)->i_vnode)) { \
334 EXT2FS_ITIMES(ip, t1, t2); \
335 } else { \
336 FFS_ITIMES(ip, t1, t2); \
337 } \
338 }
339
340 /* Determine if soft dependencies are being done */
341 #ifdef FFS_SOFTUPDATES
342 #define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
343 #else
344 #define DOINGSOFTDEP(vp) (0)
345 #endif
346 #define DOINGASYNC(vp) ((vp)->v_mount->mnt_flag & MNT_ASYNC)
347
348 /* This overlays the fid structure (see mount.h). */
349 struct ufid {
350 u_int16_t ufid_len; /* Length of structure. */
351 u_int16_t ufid_pad; /* Force 32-bit alignment. */
352 ino_t ufid_ino; /* File number (ino). */
353 int32_t ufid_gen; /* Generation number. */
354 };
355 #endif /* _KERNEL */