| @@ -1,396 +1,400 @@ | | | @@ -1,396 +1,400 @@ |
1 | /* $NetBSD: fsck.h,v 1.54 2020/04/05 15:25:40 joerg Exp $ */ | | 1 | /* $NetBSD: fsck.h,v 1.55 2020/04/18 12:54:38 jdolecek Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1980, 1986, 1993 | | 4 | * Copyright (c) 1980, 1986, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * | | 7 | * |
8 | * This software was developed for the FreeBSD Project by Marshall | | 8 | * This software was developed for the FreeBSD Project by Marshall |
9 | * Kirk McKusick and Network Associates Laboratories, the Security | | 9 | * Kirk McKusick and Network Associates Laboratories, the Security |
10 | * Research Division of Network Associates, Inc. under DARPA/SPAWAR | | 10 | * Research Division of Network Associates, Inc. under DARPA/SPAWAR |
11 | * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS | | 11 | * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS |
12 | * research program | | 12 | * research program |
13 | * | | 13 | * |
14 | * Redistribution and use in source and binary forms, with or without | | 14 | * Redistribution and use in source and binary forms, with or without |
15 | * modification, are permitted provided that the following conditions | | 15 | * modification, are permitted provided that the following conditions |
16 | * are met: | | 16 | * are met: |
17 | * 1. Redistributions of source code must retain the above copyright | | 17 | * 1. Redistributions of source code must retain the above copyright |
18 | * notice, this list of conditions and the following disclaimer. | | 18 | * notice, this list of conditions and the following disclaimer. |
19 | * 2. Redistributions in binary form must reproduce the above copyright | | 19 | * 2. Redistributions in binary form must reproduce the above copyright |
20 | * notice, this list of conditions and the following disclaimer in the | | 20 | * notice, this list of conditions and the following disclaimer in the |
21 | * documentation and/or other materials provided with the distribution. | | 21 | * documentation and/or other materials provided with the distribution. |
22 | * 3. Neither the name of the University nor the names of its contributors | | 22 | * 3. Neither the name of the University nor the names of its contributors |
23 | * may be used to endorse or promote products derived from this software | | 23 | * may be used to endorse or promote products derived from this software |
24 | * without specific prior written permission. | | 24 | * without specific prior written permission. |
25 | * | | 25 | * |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
36 | * SUCH DAMAGE. | | 36 | * SUCH DAMAGE. |
37 | * | | 37 | * |
38 | * @(#)fsck.h 8.4 (Berkeley) 5/9/95 | | 38 | * @(#)fsck.h 8.4 (Berkeley) 5/9/95 |
39 | */ | | 39 | */ |
40 | | | 40 | |
41 | #include <stdio.h> | | 41 | #include <stdio.h> |
42 | #include <sys/queue.h> | | 42 | #include <sys/queue.h> |
43 | #include <machine/bswap.h> | | 43 | #include <machine/bswap.h> |
44 | | | 44 | |
45 | #ifdef PROGRESS | | 45 | #ifdef PROGRESS |
46 | #include "progress.h" | | 46 | #include "progress.h" |
47 | #endif /* PROGRESS */ | | 47 | #endif /* PROGRESS */ |
48 | | | 48 | |
49 | #define MAXDUP 10 /* limit on dup blks (per inode) */ | | 49 | #define MAXDUP 10 /* limit on dup blks (per inode) */ |
50 | #define MAXBAD 10 /* limit on bad blks (per inode) */ | | 50 | #define MAXBAD 10 /* limit on bad blks (per inode) */ |
51 | #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ | | 51 | #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ |
52 | #define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */ | | 52 | #define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */ |
53 | | | 53 | |
54 | union dinode { | | 54 | union dinode { |
55 | struct ufs1_dinode dp1; | | 55 | struct ufs1_dinode dp1; |
56 | struct ufs2_dinode dp2; | | 56 | struct ufs2_dinode dp2; |
57 | }; | | 57 | }; |
58 | #define DIP(dp, field) \ | | 58 | #define DIP(dp, field) \ |
59 | (is_ufs2 ? (dp)->dp2.di_##field : (dp)->dp1.di_##field) | | 59 | (is_ufs2 ? (dp)->dp2.di_##field : (dp)->dp1.di_##field) |
60 | | | 60 | |
61 | #define DIP_SET(dp, field, val) do { \ | | 61 | #define DIP_SET(dp, field, val) do { \ |
62 | if (is_ufs2) \ | | 62 | if (is_ufs2) \ |
63 | (dp)->dp2.di_##field = (val); \ | | 63 | (dp)->dp2.di_##field = (val); \ |
64 | else \ | | 64 | else \ |
65 | (dp)->dp1.di_##field = (val); \ | | 65 | (dp)->dp1.di_##field = (val); \ |
66 | } while (0) | | 66 | } while (0) |
67 | | | 67 | |
68 | #ifndef BUFSIZ | | 68 | #ifndef BUFSIZ |
69 | #define BUFSIZ 1024 | | 69 | #define BUFSIZ 1024 |
70 | #endif | | 70 | #endif |
71 | | | 71 | |
72 | /* | | 72 | /* |
73 | * Each inode on the filesystem is described by the following structure. | | 73 | * Each inode on the filesystem is described by the following structure. |
74 | * The linkcnt is initially set to the value in the inode. Each time it | | 74 | * The linkcnt is initially set to the value in the inode. Each time it |
75 | * is found during the descent in passes 2, 3, and 4 the count is | | 75 | * is found during the descent in passes 2, 3, and 4 the count is |
76 | * decremented. Any inodes whose count is non-zero after pass 4 needs to | | 76 | * decremented. Any inodes whose count is non-zero after pass 4 needs to |
77 | * have its link count adjusted by the value remaining in ino_linkcnt. | | 77 | * have its link count adjusted by the value remaining in ino_linkcnt. |
78 | */ | | 78 | */ |
79 | struct inostat { | | 79 | struct inostat { |
80 | char ino_state; /* state of inode, see below */ | | 80 | char ino_state; /* state of inode, see below */ |
81 | char ino_type; /* type of inode */ | | 81 | char ino_type; /* type of inode */ |
82 | short ino_linkcnt; /* number of links not found */ | | 82 | short ino_linkcnt; /* number of links not found */ |
83 | }; | | 83 | }; |
84 | /* | | 84 | /* |
85 | * Inode states. | | 85 | * Inode states. |
86 | */ | | 86 | */ |
87 | #define USTATE 01 /* inode not allocated */ | | 87 | #define USTATE 01 /* inode not allocated */ |
88 | #define FSTATE 02 /* inode is file */ | | 88 | #define FSTATE 02 /* inode is file */ |
89 | #define DSTATE 03 /* inode is directory */ | | 89 | #define DSTATE 03 /* inode is directory */ |
90 | #define DFOUND 04 /* directory found during descent */ | | 90 | #define DFOUND 04 /* directory found during descent */ |
91 | #define DCLEAR 05 /* directory is to be cleared */ | | 91 | #define DCLEAR 05 /* directory is to be cleared */ |
92 | #define FCLEAR 06 /* file is to be cleared */ | | 92 | #define FCLEAR 06 /* file is to be cleared */ |
93 | #define DMARK 07 /* used in propagate()'s traversal algorithm */ | | 93 | #define DMARK 07 /* used in propagate()'s traversal algorithm */ |
94 | | | 94 | |
95 | /* | | 95 | /* |
96 | * Inode state information is contained on per cylinder group lists | | 96 | * Inode state information is contained on per cylinder group lists |
97 | * which are described by the following structure. | | 97 | * which are described by the following structure. |
98 | */ | | 98 | */ |
99 | extern struct inostatlist { | | 99 | extern struct inostatlist { |
100 | long il_numalloced; /* number of inodes allocated in this cg */ | | 100 | long il_numalloced; /* number of inodes allocated in this cg */ |
101 | struct inostat *il_stat;/* inostat info for this cylinder group */ | | 101 | struct inostat *il_stat;/* inostat info for this cylinder group */ |
102 | } *inostathead; | | 102 | } *inostathead; |
103 | | | 103 | |
104 | | | 104 | |
105 | /* | | 105 | /* |
106 | * buffer cache structure. | | 106 | * buffer cache structure. |
107 | */ | | 107 | */ |
108 | struct bufarea { | | 108 | struct bufarea { |
109 | struct bufarea *b_next; /* free list queue */ | | 109 | struct bufarea *b_next; /* free list queue */ |
110 | struct bufarea *b_prev; /* free list queue */ | | 110 | struct bufarea *b_prev; /* free list queue */ |
111 | daddr_t b_bno; | | 111 | daddr_t b_bno; |
112 | int b_size; | | 112 | int b_size; |
113 | int b_errs; | | 113 | int b_errs; |
114 | int b_flags; | | 114 | int b_flags; |
115 | union { | | 115 | union { |
116 | char *b_buf; /* buffer space */ | | 116 | char *b_buf; /* buffer space */ |
117 | int32_t *b_indir1; /* indirect block */ | | 117 | int32_t *b_indir1; /* indirect block */ |
118 | int64_t *b_indir2; /* indirect block */ | | 118 | int64_t *b_indir2; /* indirect block */ |
119 | struct fs *b_fs; /* super block */ | | 119 | struct fs *b_fs; /* super block */ |
120 | struct cg *b_cg; /* cylinder group */ | | 120 | struct cg *b_cg; /* cylinder group */ |
121 | struct ufs1_dinode *b_dinode1; /* UFS1 inode block */ | | 121 | struct ufs1_dinode *b_dinode1; /* UFS1 inode block */ |
122 | struct ufs2_dinode *b_dinode2; /* UFS2 inode block */ | | 122 | struct ufs2_dinode *b_dinode2; /* UFS2 inode block */ |
123 | #ifndef NO_APPLE_UFS | | 123 | #ifndef NO_APPLE_UFS |
124 | struct appleufslabel *b_appleufs; /* Apple UFS volume label */ | | 124 | struct appleufslabel *b_appleufs; /* Apple UFS volume label */ |
125 | #endif | | 125 | #endif |
126 | } b_un; | | 126 | } b_un; |
127 | char b_dirty; | | 127 | char b_dirty; |
128 | }; | | 128 | }; |
129 | | | 129 | |
130 | #define IBLK(bp, i) \ | | 130 | #define IBLK(bp, i) \ |
131 | (is_ufs2 ? (bp)->b_un.b_indir2[i] : (bp)->b_un.b_indir1[i]) | | 131 | (is_ufs2 ? (bp)->b_un.b_indir2[i] : (bp)->b_un.b_indir1[i]) |
132 | | | 132 | |
133 | #define IBLK_SET(bp, i, val) do { \ | | 133 | #define IBLK_SET(bp, i, val) do { \ |
134 | if (is_ufs2) \ | | 134 | if (is_ufs2) \ |
135 | (bp)->b_un.b_indir2[i] = (val); \ | | 135 | (bp)->b_un.b_indir2[i] = (val); \ |
136 | else \ | | 136 | else \ |
137 | (bp)->b_un.b_indir1[i] = (val); \ | | 137 | (bp)->b_un.b_indir1[i] = (val); \ |
138 | } while (0) | | 138 | } while (0) |
139 | | | 139 | |
140 | #define B_INUSE 1 | | 140 | #define B_INUSE 1 |
141 | | | 141 | |
142 | #define MINBUFS 5 /* minimum number of buffers required */ | | 142 | #define MINBUFS 5 /* minimum number of buffers required */ |
143 | extern struct bufarea bufhead; /* head of list of other blks in filesys */ | | 143 | extern struct bufarea bufhead; /* head of list of other blks in filesys */ |
144 | extern struct bufarea sblk; /* file system superblock */ | | 144 | extern struct bufarea sblk; /* file system superblock */ |
145 | extern struct bufarea asblk; /* file system superblock */ | | 145 | extern struct bufarea asblk; /* file system superblock */ |
146 | extern struct bufarea cgblk; /* cylinder group blocks */ | | 146 | extern struct bufarea cgblk; /* cylinder group blocks */ |
147 | #ifndef NO_APPLE_UFS | | 147 | #ifndef NO_APPLE_UFS |
148 | extern struct bufarea appleufsblk; /* Apple UFS volume label */ | | 148 | extern struct bufarea appleufsblk; /* Apple UFS volume label */ |
149 | #endif | | 149 | #endif |
150 | extern struct bufarea *pdirbp; /* current directory contents */ | | 150 | extern struct bufarea *pdirbp; /* current directory contents */ |
151 | extern struct bufarea *pbp; /* current inode block */ | | 151 | extern struct bufarea *pbp; /* current inode block */ |
152 | | | 152 | |
153 | #define dirty(bp) (bp)->b_dirty = 1 | | 153 | #define dirty(bp) (bp)->b_dirty = 1 |
154 | #define initbarea(bp) \ | | 154 | #define initbarea(bp) \ |
155 | (bp)->b_dirty = 0; \ | | 155 | (bp)->b_dirty = 0; \ |
156 | (bp)->b_bno = (daddr_t)-1; \ | | 156 | (bp)->b_bno = (daddr_t)-1; \ |
157 | (bp)->b_flags = 0; | | 157 | (bp)->b_flags = 0; |
158 | | | 158 | |
159 | extern struct fs *sblock; | | 159 | extern struct fs *sblock; |
160 | extern struct fs *altsblock; | | 160 | extern struct fs *altsblock; |
161 | extern struct cg *cgrp; | | 161 | extern struct cg *cgrp; |
162 | extern struct fs *sblocksave; | | 162 | extern struct fs *sblocksave; |
163 | #define sbdirty() \ | | 163 | #define sbdirty() \ |
164 | do { \ | | 164 | do { \ |
165 | memmove(sblk.b_un.b_fs, sblock, SBLOCKSIZE); \ | | 165 | memmove(sblk.b_un.b_fs, sblock, SBLOCKSIZE); \ |
166 | sb_oldfscompat_write(sblk.b_un.b_fs, sblocksave); \ | | 166 | sb_oldfscompat_write(sblk.b_un.b_fs, sblocksave); \ |
167 | if (needswap) \ | | 167 | if (needswap) \ |
168 | ffs_sb_swap(sblk.b_un.b_fs, sblk.b_un.b_fs); \ | | 168 | ffs_sb_swap(sblk.b_un.b_fs, sblk.b_un.b_fs); \ |
169 | sblk.b_dirty = 1; \ | | 169 | sblk.b_dirty = 1; \ |
170 | } while (0) | | 170 | } while (0) |
171 | #define cgdirty() do {copyback_cg(&cgblk); cgblk.b_dirty = 1;} while (0) | | 171 | #define cgdirty() do {copyback_cg(&cgblk); cgblk.b_dirty = 1;} while (0) |
172 | | | 172 | |
173 | #define appleufsdirty() \ | | 173 | #define appleufsdirty() \ |
174 | do { \ | | 174 | do { \ |
175 | appleufsblk.b_un.b_appleufs->ul_checksum = 0; \ | | 175 | appleufsblk.b_un.b_appleufs->ul_checksum = 0; \ |
176 | appleufsblk.b_un.b_appleufs->ul_checksum = \ | | 176 | appleufsblk.b_un.b_appleufs->ul_checksum = \ |
177 | ffs_appleufs_cksum(appleufsblk.b_un.b_appleufs); \ | | 177 | ffs_appleufs_cksum(appleufsblk.b_un.b_appleufs); \ |
178 | appleufsblk.b_dirty = 1; \ | | 178 | appleufsblk.b_dirty = 1; \ |
179 | } while (0) | | 179 | } while (0) |
180 | | | 180 | |
181 | enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; | | 181 | enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; |
182 | | | 182 | |
183 | struct inodesc { | | 183 | struct inodesc { |
184 | enum fixstate id_fix; /* policy on fixing errors */ | | 184 | enum fixstate id_fix; /* policy on fixing errors */ |
185 | int (*id_func) /* function to be applied to blocks of inode */ | | 185 | int (*id_func) /* function to be applied to blocks of inode */ |
186 | (struct inodesc *); | | 186 | (struct inodesc *); |
187 | ino_t id_number; /* inode number described */ | | 187 | ino_t id_number; /* inode number described */ |
188 | ino_t id_parent; /* for DATA nodes, their parent */ | | 188 | ino_t id_parent; /* for DATA nodes, their parent */ |
189 | daddr_t id_blkno; /* current block number being examined */ | | 189 | daddr_t id_blkno; /* current block number being examined */ |
190 | int id_numfrags; /* number of frags contained in block */ | | 190 | int id_numfrags; /* number of frags contained in block */ |
191 | int64_t id_filesize; /* for DATA nodes, the size of the directory */ | | 191 | int64_t id_filesize; /* for DATA nodes, the size of the directory */ |
192 | int id_loc; /* for DATA nodes, current location in dir */ | | 192 | int id_loc; /* for DATA nodes, current location in dir */ |
193 | int64_t id_entryno; /* for DATA nodes, current entry number */ | | 193 | int64_t id_entryno; /* for DATA nodes, current entry number */ |
194 | struct direct *id_dirp; /* for DATA nodes, ptr to current entry */ | | 194 | struct direct *id_dirp; /* for DATA nodes, ptr to current entry */ |
195 | const char *id_name; /* for DATA nodes, name to find or enter */ | | 195 | const char *id_name; /* for DATA nodes, name to find or enter */ |
196 | char id_type; /* type of descriptor, DATA or ADDR */ | | 196 | char id_type; /* type of descriptor, DATA or ADDR */ |
197 | uid_t id_uid; /* ownerchip of inode described */ | | 197 | uid_t id_uid; /* ownerchip of inode described */ |
198 | gid_t id_gid; | | 198 | gid_t id_gid; |
199 | }; | | 199 | }; |
200 | /* file types */ | | 200 | /* file types */ |
201 | #define DATA 1 | | 201 | #define DATA 1 |
202 | #define SNAP 2 | | 202 | #define SNAP 2 |
203 | #define ADDR 3 | | 203 | #define ADDR 3 |
204 | | | 204 | |
205 | /* | | 205 | /* |
206 | * Linked list of duplicate blocks. | | 206 | * Linked list of duplicate blocks. |
207 | * | | 207 | * |
208 | * The list is composed of two parts. The first part of the | | 208 | * The list is composed of two parts. The first part of the |
209 | * list (from duplist through the node pointed to by muldup) | | 209 | * list (from duplist through the node pointed to by muldup) |
210 | * contains a single copy of each duplicate block that has been | | 210 | * contains a single copy of each duplicate block that has been |
211 | * found. The second part of the list (from muldup to the end) | | 211 | * found. The second part of the list (from muldup to the end) |
212 | * contains duplicate blocks that have been found more than once. | | 212 | * contains duplicate blocks that have been found more than once. |
213 | * To check if a block has been found as a duplicate it is only | | 213 | * To check if a block has been found as a duplicate it is only |
214 | * necessary to search from duplist through muldup. To find the | | 214 | * necessary to search from duplist through muldup. To find the |
215 | * total number of times that a block has been found as a duplicate | | 215 | * total number of times that a block has been found as a duplicate |
216 | * the entire list must be searched for occurrences of the block | | 216 | * the entire list must be searched for occurrences of the block |
217 | * in question. The following diagram shows a sample list where | | 217 | * in question. The following diagram shows a sample list where |
218 | * w (found twice), x (found once), y (found three times), and z | | 218 | * w (found twice), x (found once), y (found three times), and z |
219 | * (found once) are duplicate block numbers: | | 219 | * (found once) are duplicate block numbers: |
220 | * | | 220 | * |
221 | * w -> y -> x -> z -> y -> w -> y | | 221 | * w -> y -> x -> z -> y -> w -> y |
222 | * ^ ^ | | 222 | * ^ ^ |
223 | * | | | | 223 | * | | |
224 | * duplist muldup | | 224 | * duplist muldup |
225 | */ | | 225 | */ |
226 | struct dups { | | 226 | struct dups { |
227 | struct dups *next; | | 227 | struct dups *next; |
228 | daddr_t dup; | | 228 | daddr_t dup; |
229 | }; | | 229 | }; |
230 | extern struct dups *duplist; /* head of dup list */ | | 230 | extern struct dups *duplist; /* head of dup list */ |
231 | extern struct dups *muldup; /* end of unique duplicate dup block numbers */ | | 231 | extern struct dups *muldup; /* end of unique duplicate dup block numbers */ |
232 | | | 232 | |
233 | /* | | 233 | /* |
234 | * Linked list of inodes with zero link counts. | | 234 | * Linked list of inodes with zero link counts. |
235 | */ | | 235 | */ |
236 | struct zlncnt { | | 236 | struct zlncnt { |
237 | struct zlncnt *next; | | 237 | struct zlncnt *next; |
238 | ino_t zlncnt; | | 238 | ino_t zlncnt; |
239 | }; | | 239 | }; |
240 | extern struct zlncnt *zlnhead; /* head of zero link count list */ | | 240 | extern struct zlncnt *zlnhead; /* head of zero link count list */ |
241 | | | 241 | |
242 | /* | | 242 | /* |
243 | * Inode cache data structures. | | 243 | * Inode cache data structures. |
244 | */ | | 244 | */ |
245 | extern struct inoinfo { | | 245 | extern struct inoinfo { |
246 | struct inoinfo *i_nexthash; /* next entry in hash chain */ | | 246 | struct inoinfo *i_nexthash; /* next entry in hash chain */ |
247 | struct inoinfo *i_child, *i_sibling; | | 247 | struct inoinfo *i_child, *i_sibling; |
248 | ino_t i_number; /* inode number of this entry */ | | 248 | ino_t i_number; /* inode number of this entry */ |
249 | ino_t i_parent; /* inode number of parent */ | | 249 | ino_t i_parent; /* inode number of parent */ |
250 | ino_t i_dotdot; /* inode number of `..' */ | | 250 | ino_t i_dotdot; /* inode number of `..' */ |
251 | size_t i_isize; /* size of inode */ | | 251 | size_t i_isize; /* size of inode */ |
252 | u_int i_numblks; /* size of block array in bytes */ | | 252 | u_int i_numblks; /* size of block array in bytes */ |
253 | int64_t i_blks[1]; /* actually longer */ | | 253 | int64_t i_blks[1]; /* actually longer */ |
254 | } **inphead, **inpsort; | | 254 | } **inphead, **inpsort; |
255 | extern long numdirs, dirhash, listmax, inplast; | | 255 | extern long numdirs, dirhash, listmax, inplast; |
256 | | | 256 | |
257 | /* | | 257 | /* |
258 | * quota usage structures | | 258 | * quota usage structures |
259 | */ | | 259 | */ |
260 | struct uquot { | | 260 | struct uquot { |
261 | uint64_t uq_b; /* block usage */ | | 261 | uint64_t uq_b; /* block usage */ |
262 | uint64_t uq_i; /* inode usage */ | | 262 | uint64_t uq_i; /* inode usage */ |
263 | SLIST_ENTRY(uquot) uq_entries; | | 263 | SLIST_ENTRY(uquot) uq_entries; |
264 | uint32_t uq_uid; /* uid/gid of the owner */ | | 264 | uint32_t uq_uid; /* uid/gid of the owner */ |
265 | }; | | 265 | }; |
266 | SLIST_HEAD(uquot_hash, uquot); | | 266 | SLIST_HEAD(uquot_hash, uquot); |
267 | extern struct uquot_hash *uquot_user_hash; | | 267 | extern struct uquot_hash *uquot_user_hash; |
268 | extern struct uquot_hash *uquot_group_hash; | | 268 | extern struct uquot_hash *uquot_group_hash; |
269 | extern uint8_t q2h_hash_shift; | | 269 | extern uint8_t q2h_hash_shift; |
270 | extern uint16_t q2h_hash_mask; | | 270 | extern uint16_t q2h_hash_mask; |
271 | | | 271 | |
272 | extern long dev_bsize; /* computed value of DEV_BSIZE */ | | 272 | extern long dev_bsize; /* computed value of DEV_BSIZE */ |
273 | extern long secsize; /* actual disk sector size */ | | 273 | extern long secsize; /* actual disk sector size */ |
274 | extern char nflag; /* assume a no response */ | | 274 | extern char nflag; /* assume a no response */ |
275 | extern char yflag; /* assume a yes response */ | | 275 | extern char yflag; /* assume a yes response */ |
276 | extern int Uflag; /* resolve user names */ | | 276 | extern int Uflag; /* resolve user names */ |
277 | extern int bflag; /* location of alternate super block */ | | 277 | extern int bflag; /* location of alternate super block */ |
278 | extern int debug; /* output debugging info */ | | 278 | extern int debug; /* output debugging info */ |
279 | extern int zflag; /* zero unused directory space */ | | 279 | extern int zflag; /* zero unused directory space */ |
280 | extern int cvtlevel; /* convert to newer file system format */ | | 280 | extern int cvtlevel; /* convert to newer file system format */ |
281 | extern int doinglevel1; /* converting to new cylinder group format */ | | 281 | extern int doinglevel1; /* converting to new cylinder group format */ |
282 | extern int doinglevel2; /* converting to new inode format */ | | 282 | extern int doinglevel2; /* converting to new inode format */ |
283 | extern int newinofmt; /* filesystem has new inode format */ | | 283 | extern int newinofmt; /* filesystem has new inode format */ |
284 | extern char usedsoftdep; /* just fix soft dependency inconsistencies */ | | 284 | extern char usedsoftdep; /* just fix soft dependency inconsistencies */ |
285 | extern int preen; /* just fix normal inconsistencies */ | | 285 | extern int preen; /* just fix normal inconsistencies */ |
286 | extern int quiet; /* Don't print anything if clean */ | | 286 | extern int quiet; /* Don't print anything if clean */ |
287 | extern int forceimage; /* file system is an image file */ | | 287 | extern int forceimage; /* file system is an image file */ |
288 | extern int is_ufs2; /* we're dealing with an UFS2 filesystem */ | | 288 | extern int is_ufs2; /* we're dealing with an UFS2 filesystem */ |
289 | extern int markclean; /* mark file system clean when done */ | | 289 | extern int markclean; /* mark file system clean when done */ |
290 | extern char havesb; /* superblock has been read */ | | 290 | extern char havesb; /* superblock has been read */ |
291 | extern char skipclean; /* skip clean file systems if preening */ | | 291 | extern char skipclean; /* skip clean file systems if preening */ |
292 | extern int fsmodified; /* 1 => write done to file system */ | | 292 | extern int fsmodified; /* 1 => write done to file system */ |
293 | extern int fsreadfd; /* file descriptor for reading file system */ | | 293 | extern int fsreadfd; /* file descriptor for reading file system */ |
294 | extern int fswritefd; /* file descriptor for writing file system */ | | 294 | extern int fswritefd; /* file descriptor for writing file system */ |
295 | extern int rerun; /* rerun fsck. Only used in non-preen mode */ | | 295 | extern int rerun; /* rerun fsck. Only used in non-preen mode */ |
296 | extern char resolved; /* cleared if unresolved changes => not clean */ | | 296 | extern char resolved; /* cleared if unresolved changes => not clean */ |
297 | | | 297 | |
298 | #ifndef NO_FFS_EI | | 298 | #ifndef NO_FFS_EI |
299 | extern int endian; /* endian coversion */ | | 299 | extern int endian; /* endian coversion */ |
300 | extern int doswap; /* convert byte order */ | | 300 | extern int doswap; /* convert byte order */ |
301 | extern int needswap; /* need to convert byte order in memory */ | | 301 | extern int needswap; /* need to convert byte order in memory */ |
302 | extern int do_blkswap; /* need to do block addr byteswap */ | | 302 | extern int do_blkswap; /* need to do block addr byteswap */ |
303 | extern int do_dirswap; /* need to do dir entry byteswap */ | | 303 | extern int do_dirswap; /* need to do dir entry byteswap */ |
304 | #else | | 304 | #else |
305 | /* Disable Endian-Independent FFS support for install media */ | | 305 | /* Disable Endian-Independent FFS support for install media */ |
306 | #define endian (0) | | 306 | #define endian (0) |
307 | #define doswap (0) | | 307 | #define doswap (0) |
308 | #define needswap (0) | | 308 | #define needswap (0) |
309 | #define do_blkswap (0) | | 309 | #define do_blkswap (0) |
310 | #define do_dirswap (0) | | 310 | #define do_dirswap (0) |
311 | #define ffs_cg_swap(a, b, c) __nothing | | 311 | #define ffs_cg_swap(a, b, c) __nothing |
312 | #define ffs_csum_swap(a, b, c) __nothing | | 312 | #define ffs_csum_swap(a, b, c) __nothing |
313 | #define ffs_sb_swap(a, b) __nothing | | 313 | #define ffs_sb_swap(a, b) __nothing |
314 | #define swap_dinode1(a, b) __nothing | | 314 | #define swap_dinode1(a, b) __nothing |
315 | #define swap_dinode2(a, b) __nothing | | 315 | #define swap_dinode2(a, b) __nothing |
316 | #endif | | 316 | #endif |
317 | | | 317 | |
318 | #ifndef NO_APPLE_UFS | | 318 | #ifndef NO_APPLE_UFS |
319 | extern int isappleufs; /* filesystem is Apple UFS */ | | 319 | extern int isappleufs; /* filesystem is Apple UFS */ |
320 | #else | | 320 | #else |
321 | /* Disable Apple UFS support for install media */ | | 321 | /* Disable Apple UFS support for install media */ |
322 | #define isappleufs (0) | | 322 | #define isappleufs (0) |
323 | #endif | | 323 | #endif |
324 | | | 324 | |
325 | extern daddr_t maxfsblock; /* number of blocks in the file system */ | | 325 | extern daddr_t maxfsblock; /* number of blocks in the file system */ |
326 | extern char *blockmap; /* ptr to primary blk allocation map */ | | 326 | extern char *blockmap; /* ptr to primary blk allocation map */ |
327 | extern ino_t maxino; /* number of inodes in file system */ | | 327 | extern ino_t maxino; /* number of inodes in file system */ |
328 | | | 328 | |
329 | extern int dirblksiz; | | 329 | extern int dirblksiz; |
330 | | | 330 | |
331 | extern ino_t lfdir; /* lost & found directory inode number */ | | 331 | extern ino_t lfdir; /* lost & found directory inode number */ |
332 | extern const char *lfname; /* lost & found directory name */ | | 332 | extern const char *lfname; /* lost & found directory name */ |
333 | extern int lfmode; /* lost & found directory creation mode */ | | 333 | extern int lfmode; /* lost & found directory creation mode */ |
334 | | | 334 | |
335 | extern daddr_t n_blks; /* number of blocks in use */ | | 335 | extern daddr_t n_blks; /* number of blocks in use */ |
336 | extern ino_t n_files; /* number of files in use */ | | 336 | extern ino_t n_files; /* number of files in use */ |
337 | | | 337 | |
338 | extern long countdirs; | | 338 | extern long countdirs; |
339 | | | 339 | |
340 | extern int got_siginfo; /* received a SIGINFO */ | | 340 | extern int got_siginfo; /* received a SIGINFO */ |
341 | | | 341 | |
342 | #define clearinode(dp) \ | | 342 | #define clearinode(dp) \ |
343 | do { \ | | 343 | do { \ |
344 | if (is_ufs2) \ | | 344 | if (is_ufs2) \ |
345 | (dp)->dp2 = ufs2_zino; \ | | 345 | (dp)->dp2 = ufs2_zino; \ |
346 | else \ | | 346 | else \ |
347 | (dp)->dp1 = ufs1_zino; \ | | 347 | (dp)->dp1 = ufs1_zino; \ |
348 | } while (0) | | 348 | } while (0) |
349 | | | 349 | |
350 | extern struct ufs1_dinode ufs1_zino; | | 350 | extern struct ufs1_dinode ufs1_zino; |
351 | extern struct ufs2_dinode ufs2_zino; | | 351 | extern struct ufs2_dinode ufs2_zino; |
352 | | | 352 | |
353 | #define setbmap(blkno) setbit(blockmap, blkno) | | 353 | #define setbmap(blkno) setbit(blockmap, blkno) |
354 | #define testbmap(blkno) isset(blockmap, blkno) | | 354 | #define testbmap(blkno) isset(blockmap, blkno) |
355 | #define clrbmap(blkno) clrbit(blockmap, blkno) | | 355 | #define clrbmap(blkno) clrbit(blockmap, blkno) |
356 | | | 356 | |
357 | #define STOP 0x01 | | 357 | #define STOP 0x01 |
358 | #define SKIP 0x02 | | 358 | #define SKIP 0x02 |
359 | #define KEEPON 0x04 | | 359 | #define KEEPON 0x04 |
360 | #define ALTERED 0x08 | | 360 | #define ALTERED 0x08 |
361 | #define FOUND 0x10 | | 361 | #define FOUND 0x10 |
362 | | | 362 | |
363 | #ifndef NO_FFS_EI | | 363 | #ifndef NO_FFS_EI |
364 | /* some inline functs to help the byte-swapping mess */ | | 364 | /* some inline functs to help the byte-swapping mess */ |
365 | static inline u_int16_t iswap16 (u_int16_t); | | 365 | static inline u_int16_t iswap16 (u_int16_t); |
366 | static inline u_int32_t iswap32 (u_int32_t); | | 366 | static inline u_int32_t iswap32 (u_int32_t); |
367 | static inline u_int64_t iswap64 (u_int64_t); | | 367 | static inline u_int64_t iswap64 (u_int64_t); |
368 | | | 368 | |
369 | static inline u_int16_t | | 369 | static inline u_int16_t |
370 | iswap16(u_int16_t x) | | 370 | iswap16(u_int16_t x) |
371 | { | | 371 | { |
372 | if (needswap) | | 372 | if (needswap) |
373 | return bswap16(x); | | 373 | return bswap16(x); |
374 | else return x; | | 374 | else return x; |
375 | } | | 375 | } |
376 | | | 376 | |
377 | static inline u_int32_t | | 377 | static inline u_int32_t |
378 | iswap32(u_int32_t x) | | 378 | iswap32(u_int32_t x) |
379 | { | | 379 | { |
380 | if (needswap) | | 380 | if (needswap) |
381 | return bswap32(x); | | 381 | return bswap32(x); |
382 | else return x; | | 382 | else return x; |
383 | } | | 383 | } |
384 | | | 384 | |
385 | static inline u_int64_t | | 385 | static inline u_int64_t |
386 | iswap64(u_int64_t x) | | 386 | iswap64(u_int64_t x) |
387 | { | | 387 | { |
388 | if (needswap) | | 388 | if (needswap) |
389 | return bswap64(x); | | 389 | return bswap64(x); |
390 | else return x; | | 390 | else return x; |
391 | } | | 391 | } |
392 | #else | | 392 | #else |
393 | #define iswap16(x) (x) | | 393 | #define iswap16(x) (x) |
394 | #define iswap32(x) (x) | | 394 | #define iswap32(x) (x) |
395 | #define iswap64(x) (x) | | 395 | #define iswap64(x) (x) |
396 | #endif /* NO_FFS_EI */ | | 396 | #endif /* NO_FFS_EI */ |
| | | 397 | |
| | | 398 | #ifdef NO_IOBUF_ALIGNED |
| | | 399 | #define aligned_alloc(align, size) malloc((size)) |
| | | 400 | #endif |