File: | src/sbin/fsck_ffs/inode.c |
Warning: | line 215, column 6 Value stored to 'isize' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: inode.c,v 1.50 2020/07/13 06:52:53 otto Exp $ */ |
2 | /* $NetBSD: inode.c,v 1.23 1996/10/11 20:15:47 thorpej Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 1980, 1986, 1993 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions |
10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. Neither the name of the University nor the names of its contributors |
17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
30 | * SUCH DAMAGE. |
31 | */ |
32 | |
33 | #include <sys/param.h> /* setbit btodb */ |
34 | #include <sys/time.h> |
35 | #include <ufs/ufs/dinode.h> |
36 | #include <ufs/ufs/dir.h> |
37 | #include <ufs/ffs/fs.h> |
38 | #ifndef SMALL |
39 | #include <pwd.h> |
40 | #endif |
41 | #include <stdio.h> |
42 | #include <stdlib.h> |
43 | #include <string.h> |
44 | #include <unistd.h> |
45 | #include <limits.h> |
46 | |
47 | #include "fsck.h" |
48 | #include "fsutil.h" |
49 | #include "extern.h" |
50 | |
51 | #define MINIMUM(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b)) |
52 | #define MAXIMUM(a, b)(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b)) |
53 | |
54 | static ino_t startinum; |
55 | |
56 | static int iblock(struct inodesc *, long, off_t); |
57 | |
58 | int |
59 | ckinode(union dinode *dp, struct inodesc *idesc) |
60 | { |
61 | long ret, ndb, offset; |
62 | union dinode dino; |
63 | off_t sizepb, remsize; |
64 | mode_t mode; |
65 | int i; |
66 | char pathbuf[PATH_MAX1024 + 1]; |
67 | |
68 | if (idesc->id_fix != IGNORE) |
69 | idesc->id_fix = DONTKNOW; |
70 | idesc->id_entryno = 0; |
71 | idesc->id_filesize = DIP(dp, di_size)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_size : (dp)->dp2.di_size); |
72 | mode = DIP(dp, di_mode)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_mode : (dp)->dp2.di_mode) & IFMT0170000; |
73 | if (mode == IFBLK0060000 || mode == IFCHR0020000 || (mode == IFLNK0120000 && |
74 | (DIP(dp, di_size)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_size : (dp)->dp2.di_size) < sblock(*sblk.b_un.b_fs).fs_maxsymlinklen || |
75 | (sblock(*sblk.b_un.b_fs).fs_maxsymlinklen == 0 && DIP(dp, di_blocks)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_blocks : (dp)->dp2.di_blocks) == 0)))) |
76 | return (KEEPON0x04); |
77 | if (sblock(*sblk.b_un.b_fs).fs_magic == FS_UFS1_MAGIC0x011954) |
78 | dino.dp1 = dp->dp1; |
79 | else |
80 | dino.dp2 = dp->dp2; |
81 | ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize)((((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)-> dp1.di_size : (&dino)->dp2.di_size)) + (((*sblk.b_un.b_fs ).fs_bsize) - 1)) / ((*sblk.b_un.b_fs).fs_bsize)); |
82 | for (i = 0; i < NDADDR12; i++) { |
83 | if (--ndb == 0 && (offset = blkoff(&sblock,(((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)-> dp1.di_size : (&dino)->dp2.di_size)) & (&(*sblk .b_un.b_fs))->fs_qbmask) |
84 | DIP(&dino, di_size))(((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)-> dp1.di_size : (&dino)->dp2.di_size)) & (&(*sblk .b_un.b_fs))->fs_qbmask)) != 0) |
85 | idesc->id_numfrags = |
86 | numfrags(&sblock, fragroundup(&sblock, offset))(((((offset) + (&(*sblk.b_un.b_fs))->fs_qfmask) & ( &(*sblk.b_un.b_fs))->fs_fmask)) >> (&(*sblk. b_un.b_fs))->fs_fshift); |
87 | else |
88 | idesc->id_numfrags = sblock(*sblk.b_un.b_fs).fs_frag; |
89 | if (DIP(&dino, di_db[i])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)->dp1 .di_db[i] : (&dino)->dp2.di_db[i]) == 0) { |
90 | if (idesc->id_type == DATA1 && ndb >= 0) { |
91 | /* An empty block in a directory XXX */ |
92 | getpathname(pathbuf, sizeof pathbuf, |
93 | idesc->id_number, idesc->id_number); |
94 | pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", |
95 | pathbuf); |
96 | if (reply("ADJUST LENGTH") == 1) { |
97 | dp = ginode(idesc->id_number); |
98 | DIP_SET(dp, di_size,do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = (i * (*sblk.b_un.b_fs).fs_bsize); else (dp)->dp2 .di_size = (i * (*sblk.b_un.b_fs).fs_bsize); } while (0) |
99 | i * sblock.fs_bsize)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = (i * (*sblk.b_un.b_fs).fs_bsize); else (dp)->dp2 .di_size = (i * (*sblk.b_un.b_fs).fs_bsize); } while (0); |
100 | printf( |
101 | "YOU MUST RERUN FSCK AFTERWARDS\n"); |
102 | rerun = 1; |
103 | inodirty(); |
104 | } |
105 | } |
106 | continue; |
107 | } |
108 | idesc->id_blkno = DIP(&dino, di_db[i])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)->dp1 .di_db[i] : (&dino)->dp2.di_db[i]); |
109 | if (idesc->id_type == ADDR2) |
110 | ret = (*idesc->id_func)(idesc); |
111 | else |
112 | ret = dirscan(idesc); |
113 | if (ret & STOP0x01) |
114 | return (ret); |
115 | } |
116 | idesc->id_numfrags = sblock(*sblk.b_un.b_fs).fs_frag; |
117 | remsize = DIP(&dino, di_size)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)->dp1 .di_size : (&dino)->dp2.di_size) - sblock(*sblk.b_un.b_fs).fs_bsize * NDADDR12; |
118 | sizepb = sblock(*sblk.b_un.b_fs).fs_bsize; |
119 | for (i = 0; i < NIADDR3; i++) { |
120 | if (DIP(&dino, di_ib[i])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)->dp1 .di_ib[i] : (&dino)->dp2.di_ib[i])) { |
121 | idesc->id_blkno = DIP(&dino, di_ib[i])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (&dino)->dp1 .di_ib[i] : (&dino)->dp2.di_ib[i]); |
122 | ret = iblock(idesc, i + 1, remsize); |
123 | if (ret & STOP0x01) |
124 | return (ret); |
125 | } else { |
126 | if (idesc->id_type == DATA1 && remsize > 0) { |
127 | /* An empty block in a directory XXX */ |
128 | getpathname(pathbuf, sizeof pathbuf, |
129 | idesc->id_number, idesc->id_number); |
130 | pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", |
131 | pathbuf); |
132 | if (reply("ADJUST LENGTH") == 1) { |
133 | dp = ginode(idesc->id_number); |
134 | DIP_SET(dp, di_size,do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)-> dp1.di_size : (dp)->dp2.di_size) - remsize); else (dp)-> dp2.di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp )->dp1.di_size : (dp)->dp2.di_size) - remsize); } while (0) |
135 | DIP(dp, di_size) - remsize)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)-> dp1.di_size : (dp)->dp2.di_size) - remsize); else (dp)-> dp2.di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp )->dp1.di_size : (dp)->dp2.di_size) - remsize); } while (0); |
136 | remsize = 0; |
137 | printf( |
138 | "YOU MUST RERUN FSCK AFTERWARDS\n"); |
139 | rerun = 1; |
140 | inodirty(); |
141 | break; |
142 | } |
143 | } |
144 | } |
145 | sizepb *= NINDIR(&sblock)((&(*sblk.b_un.b_fs))->fs_nindir); |
146 | remsize -= sizepb; |
147 | } |
148 | return (KEEPON0x04); |
149 | } |
150 | |
151 | static int |
152 | iblock(struct inodesc *idesc, long ilevel, off_t isize) |
153 | { |
154 | struct bufarea *bp; |
155 | int i, n, (*func)(struct inodesc *), nif; |
156 | off_t sizepb; |
157 | char buf[BUFSIZ1024]; |
158 | char pathbuf[PATH_MAX1024 + 1]; |
159 | union dinode *dp; |
160 | |
161 | if (idesc->id_type == ADDR2) { |
162 | func = idesc->id_func; |
163 | if (((n = (*func)(idesc)) & KEEPON0x04) == 0) |
164 | return (n); |
165 | } else |
166 | func = dirscan; |
167 | if (isize < 0 || chkrange(idesc->id_blkno, idesc->id_numfrags)) |
168 | return (SKIP0x02); |
169 | bp = getdatablk(idesc->id_blkno, sblock(*sblk.b_un.b_fs).fs_bsize); |
170 | ilevel--; |
171 | for (sizepb = sblock(*sblk.b_un.b_fs).fs_bsize, i = 0; i < ilevel; i++) |
172 | sizepb *= NINDIR(&sblock)((&(*sblk.b_un.b_fs))->fs_nindir); |
173 | if (howmany(isize, sizepb)(((isize) + ((sizepb) - 1)) / (sizepb)) > NINDIR(&sblock)((&(*sblk.b_un.b_fs))->fs_nindir)) |
174 | nif = NINDIR(&sblock)((&(*sblk.b_un.b_fs))->fs_nindir); |
175 | else |
176 | nif = howmany(isize, sizepb)(((isize) + ((sizepb) - 1)) / (sizepb)); |
177 | if (idesc->id_func == pass1check && nif < NINDIR(&sblock)((&(*sblk.b_un.b_fs))->fs_nindir)) { |
178 | for (i = nif; i < NINDIR(&sblock)((&(*sblk.b_un.b_fs))->fs_nindir); i++) { |
179 | if (IBLK(bp, i)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (bp)->b_un.b_indir1 [i] : (bp)->b_un.b_indir2[i]) == 0) |
180 | continue; |
181 | (void)snprintf(buf, sizeof buf, |
182 | "PARTIALLY TRUNCATED INODE I=%llu", |
183 | (unsigned long long)idesc->id_number); |
184 | if (preen) |
185 | pfatal("%s", buf); |
186 | else if (dofix(idesc, buf)) { |
187 | IBLK_SET(bp, i, 0)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (bp)->b_un .b_indir1[i] = (0); else (bp)->b_un.b_indir2[i] = (0); } while (0); |
188 | dirty(bp)(bp)->b_dirty = 1; |
189 | } |
190 | } |
191 | flush(fswritefd, bp); |
192 | } |
193 | for (i = 0; i < nif; i++) { |
194 | if (IBLK(bp, i)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (bp)->b_un.b_indir1 [i] : (bp)->b_un.b_indir2[i])) { |
195 | idesc->id_blkno = IBLK(bp, i)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (bp)->b_un.b_indir1 [i] : (bp)->b_un.b_indir2[i]); |
196 | if (ilevel == 0) |
197 | n = (*func)(idesc); |
198 | else |
199 | n = iblock(idesc, ilevel, isize); |
200 | if (n & STOP0x01) { |
201 | bp->b_flags &= ~B_INUSE1; |
202 | return (n); |
203 | } |
204 | } else { |
205 | if (idesc->id_type == DATA1 && isize > 0) { |
206 | /* An empty block in a directory XXX */ |
207 | getpathname(pathbuf, sizeof pathbuf, |
208 | idesc->id_number, idesc->id_number); |
209 | pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", |
210 | pathbuf); |
211 | if (reply("ADJUST LENGTH") == 1) { |
212 | dp = ginode(idesc->id_number); |
213 | DIP_SET(dp, di_size,do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)-> dp1.di_size : (dp)->dp2.di_size) - isize); else (dp)->dp2 .di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)-> dp1.di_size : (dp)->dp2.di_size) - isize); } while (0) |
214 | DIP(dp, di_size) - isize)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)-> dp1.di_size : (dp)->dp2.di_size) - isize); else (dp)->dp2 .di_size = ((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)-> dp1.di_size : (dp)->dp2.di_size) - isize); } while (0); |
215 | isize = 0; |
Value stored to 'isize' is never read | |
216 | printf( |
217 | "YOU MUST RERUN FSCK AFTERWARDS\n"); |
218 | rerun = 1; |
219 | inodirty(); |
220 | bp->b_flags &= ~B_INUSE1; |
221 | return(STOP0x01); |
222 | } |
223 | } |
224 | } |
225 | isize -= sizepb; |
226 | } |
227 | bp->b_flags &= ~B_INUSE1; |
228 | return (KEEPON0x04); |
229 | } |
230 | |
231 | /* |
232 | * Check that a block in a legal block number. |
233 | * Return 0 if in range, 1 if out of range. |
234 | */ |
235 | int |
236 | chkrange(daddr_t blk, int cnt) |
237 | { |
238 | int c; |
239 | |
240 | if (cnt <= 0 || blk <= 0 || blk > maxfsblock || |
241 | cnt - 1 > maxfsblock - blk) |
242 | return (1); |
243 | if (cnt > sblock(*sblk.b_un.b_fs).fs_frag || |
244 | fragnum(&sblock, blk)((blk) & ((&(*sblk.b_un.b_fs))->fs_frag - 1)) + cnt > sblock(*sblk.b_un.b_fs).fs_frag) { |
245 | if (debug) |
246 | printf("bad size: blk %lld, offset %lld, size %d\n", |
247 | (long long)blk, (long long)fragnum(&sblock, blk)((blk) & ((&(*sblk.b_un.b_fs))->fs_frag - 1)), |
248 | cnt); |
249 | return (1); |
250 | } |
251 | c = dtog(&sblock, blk)((blk) / (&(*sblk.b_un.b_fs))->fs_fpg); |
252 | if (blk < cgdmin(&sblock, c)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (c)) + (& (*sblk.b_un.b_fs))->fs_cgoffset * ((c) & ~((&(*sblk .b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))-> fs_dblkno)) { |
253 | if ((blk + cnt) > cgsblock(&sblock, c)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (c)) + (& (*sblk.b_un.b_fs))->fs_cgoffset * ((c) & ~((&(*sblk .b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))-> fs_sblkno)) { |
254 | if (debug) { |
255 | printf("blk %lld < cgdmin %lld;", |
256 | (long long)blk, |
257 | (long long)cgdmin(&sblock, c)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (c)) + (& (*sblk.b_un.b_fs))->fs_cgoffset * ((c) & ~((&(*sblk .b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))-> fs_dblkno)); |
258 | printf(" blk + cnt %lld > cgsbase %lld\n", |
259 | (long long)(blk + cnt), |
260 | (long long)cgsblock(&sblock, c)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (c)) + (& (*sblk.b_un.b_fs))->fs_cgoffset * ((c) & ~((&(*sblk .b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))-> fs_sblkno)); |
261 | } |
262 | return (1); |
263 | } |
264 | } else { |
265 | if ((blk + cnt) > cgbase(&sblock, c+1)((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (c+1))) { |
266 | if (debug) { |
267 | printf("blk %lld >= cgdmin %lld;", |
268 | (long long)blk, |
269 | (long long)cgdmin(&sblock, c)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (c)) + (& (*sblk.b_un.b_fs))->fs_cgoffset * ((c) & ~((&(*sblk .b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))-> fs_dblkno)); |
270 | printf(" blk + cnt %lld > sblock.fs_fpg %d\n", |
271 | (long long)(blk+cnt), sblock(*sblk.b_un.b_fs).fs_fpg); |
272 | } |
273 | return (1); |
274 | } |
275 | } |
276 | return (0); |
277 | } |
278 | |
279 | /* |
280 | * General purpose interface for reading inodes. |
281 | */ |
282 | union dinode * |
283 | ginode(ino_t inumber) |
284 | { |
285 | daddr_t iblk; |
286 | |
287 | if (inumber < ROOTINO((ufsino_t)2) || inumber > maxino) |
288 | errexit("bad inode number %llu to ginode\n", |
289 | (unsigned long long)inumber); |
290 | if (startinum == 0 || |
291 | inumber < startinum || inumber >= startinum + INOPB(&sblock)((&(*sblk.b_un.b_fs))->fs_inopb)) { |
292 | iblk = ino_to_fsba(&sblock, inumber)((daddr_t)(((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * ( ((inumber) / (&(*sblk.b_un.b_fs))->fs_ipg))) + (&( *sblk.b_un.b_fs))->fs_cgoffset * ((((inumber) / (&(*sblk .b_un.b_fs))->fs_ipg)) & ~((&(*sblk.b_un.b_fs))-> fs_cgmask))) + (&(*sblk.b_un.b_fs))->fs_iblkno) + (((( ((inumber) % (&(*sblk.b_un.b_fs))->fs_ipg) / ((&(* sblk.b_un.b_fs))->fs_inopb))) << ((&(*sblk.b_un. b_fs)))->fs_fragshift)))); |
293 | if (pbp != 0) |
294 | pbp->b_flags &= ~B_INUSE1; |
295 | pbp = getdatablk(iblk, sblock(*sblk.b_un.b_fs).fs_bsize); |
296 | startinum = (inumber / INOPB(&sblock)((&(*sblk.b_un.b_fs))->fs_inopb)) * INOPB(&sblock)((&(*sblk.b_un.b_fs))->fs_inopb); |
297 | } |
298 | if (sblock(*sblk.b_un.b_fs).fs_magic == FS_UFS1_MAGIC0x011954) |
299 | return ((union dinode *) |
300 | &pbp->b_un.b_dinode1[inumber % INOPB(&sblock)((&(*sblk.b_un.b_fs))->fs_inopb)]); |
301 | return ((union dinode *)&pbp->b_un.b_dinode2[inumber % INOPB(&sblock)((&(*sblk.b_un.b_fs))->fs_inopb)]); |
302 | } |
303 | |
304 | /* |
305 | * Special purpose version of ginode used to optimize first pass |
306 | * over all the inodes in numerical order. |
307 | */ |
308 | ino_t nextino, lastinum; |
309 | long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; |
310 | static caddr_t inodebuf; |
311 | |
312 | union dinode * |
313 | getnextinode(ino_t inumber) |
314 | { |
315 | long size; |
316 | daddr_t dblk; |
317 | union dinode *dp; |
318 | static caddr_t nextinop; |
319 | |
320 | if (inumber != nextino++ || inumber > maxino) |
321 | errexit("bad inode number %llu to nextinode %llu\n", |
322 | (unsigned long long)inumber, |
323 | (unsigned long long)nextino); |
324 | if (inumber >= lastinum) { |
325 | readcnt++; |
326 | dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum))((((daddr_t)(((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (((lastinum) / (&(*sblk.b_un.b_fs))->fs_ipg))) + (& (*sblk.b_un.b_fs))->fs_cgoffset * ((((lastinum) / (&(* sblk.b_un.b_fs))->fs_ipg)) & ~((&(*sblk.b_un.b_fs) )->fs_cgmask))) + (&(*sblk.b_un.b_fs))->fs_iblkno) + ((((((lastinum) % (&(*sblk.b_un.b_fs))->fs_ipg) / ((& (*sblk.b_un.b_fs))->fs_inopb))) << ((&(*sblk.b_un .b_fs)))->fs_fragshift))))) << (&(*sblk.b_un.b_fs ))->fs_fsbtodb); |
327 | if (readcnt % readpercg == 0) { |
328 | size = partialsize; |
329 | lastinum += partialcnt; |
330 | } else { |
331 | size = inobufsize; |
332 | lastinum += fullcnt; |
333 | } |
334 | (void)bread(fsreadfd, inodebuf, dblk, size); |
335 | nextinop = inodebuf; |
336 | } |
337 | dp = (union dinode *)nextinop; |
338 | if (sblock(*sblk.b_un.b_fs).fs_magic == FS_UFS1_MAGIC0x011954) |
339 | nextinop += sizeof(struct ufs1_dinode); |
340 | else |
341 | nextinop += sizeof(struct ufs2_dinode); |
342 | return (dp); |
343 | } |
344 | |
345 | void |
346 | setinodebuf(ino_t inum) |
347 | { |
348 | |
349 | startinum = 0; |
350 | nextino = inum; |
351 | lastinum = inum; |
352 | readcnt = 0; |
353 | if (inodebuf != NULL((void *)0)) |
354 | return; |
355 | inobufsize = blkroundup(&sblock, INOBUFSIZE)(((56*1024) + (&(*sblk.b_un.b_fs))->fs_qbmask) & ( &(*sblk.b_un.b_fs))->fs_bmask); |
356 | if (sblock(*sblk.b_un.b_fs).fs_magic == FS_UFS1_MAGIC0x011954) |
357 | fullcnt = inobufsize / sizeof(struct ufs1_dinode); |
358 | else |
359 | fullcnt = inobufsize / sizeof(struct ufs2_dinode); |
360 | readpercg = sblock(*sblk.b_un.b_fs).fs_ipg / fullcnt; |
361 | partialcnt = sblock(*sblk.b_un.b_fs).fs_ipg % fullcnt; |
362 | if (sblock(*sblk.b_un.b_fs).fs_magic == FS_UFS1_MAGIC0x011954) |
363 | partialsize = partialcnt * sizeof(struct ufs1_dinode); |
364 | else |
365 | partialsize = partialcnt * sizeof(struct ufs2_dinode); |
366 | if (partialcnt != 0) { |
367 | readpercg++; |
368 | } else { |
369 | partialcnt = fullcnt; |
370 | partialsize = inobufsize; |
371 | } |
372 | if (inodebuf == NULL((void *)0) && |
373 | (inodebuf = Malloc((unsigned)inobufsize)) == NULL((void *)0)) |
374 | errexit("Cannot allocate space for inode buffer\n"); |
375 | } |
376 | |
377 | void |
378 | freeinodebuf(void) |
379 | { |
380 | |
381 | free(inodebuf); |
382 | inodebuf = NULL((void *)0); |
383 | } |
384 | |
385 | /* |
386 | * Routines to maintain information about directory inodes. |
387 | * This is built during the first pass and used during the |
388 | * second and third passes. |
389 | * |
390 | * Enter inodes into the cache. |
391 | */ |
392 | void |
393 | cacheino(union dinode *dp, ino_t inumber) |
394 | { |
395 | struct inoinfo *inp; |
396 | struct inoinfo **inpp, **newinpsort; |
397 | unsigned int blks; |
398 | long newlistmax; |
399 | int i; |
400 | |
401 | blks = howmany(DIP(dp, di_size), sblock.fs_bsize)((((((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_size : (dp)->dp2.di_size)) + (((*sblk.b_un.b_fs).fs_bsize) - 1 )) / ((*sblk.b_un.b_fs).fs_bsize)); |
402 | if (blks > NDADDR12) |
403 | blks = NDADDR12 + NIADDR3; |
404 | inp = Malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); |
405 | if (inp == NULL((void *)0)) |
406 | errexit("cannot allocate memory for inode cache\n"); |
407 | inpp = &inphead[inumber % numdirs]; |
408 | inp->i_nexthash = *inpp; |
409 | *inpp = inp; |
410 | inp->i_child = inp->i_sibling = 0; |
411 | if (inumber == ROOTINO((ufsino_t)2)) |
412 | inp->i_parent = ROOTINO((ufsino_t)2); |
413 | else |
414 | inp->i_parent = 0; |
415 | inp->i_dotdot = 0; |
416 | inp->i_number = inumber; |
417 | inp->i_isize = DIP(dp, di_size)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_size : (dp)->dp2.di_size); |
418 | inp->i_numblks = blks; |
419 | for (i = 0; i < (blks < NDADDR12 ? blks : NDADDR12); i++) |
420 | inp->i_blks[i] = DIP(dp, di_db[i])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_db [i] : (dp)->dp2.di_db[i]); |
421 | if (blks > NDADDR12) |
422 | for (i = 0; i < NIADDR3; i++) |
423 | inp->i_blks[NDADDR12 + i] = DIP(dp, di_ib[i])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_ib [i] : (dp)->dp2.di_ib[i]); |
424 | if (inplast == listmax) { |
425 | newlistmax = listmax + 100; |
426 | newinpsort = Reallocarray(inpsort, |
427 | (unsigned)newlistmax, sizeof(struct inoinfo *)); |
428 | if (newinpsort == NULL((void *)0)) |
429 | errexit("cannot increase directory list\n"); |
430 | inpsort = newinpsort; |
431 | listmax = newlistmax; |
432 | } |
433 | inpsort[inplast++] = inp; |
434 | } |
435 | |
436 | /* |
437 | * Look up an inode cache structure. |
438 | */ |
439 | struct inoinfo * |
440 | getinoinfo(ino_t inumber) |
441 | { |
442 | struct inoinfo *inp; |
443 | |
444 | for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) { |
445 | if (inp->i_number != inumber) |
446 | continue; |
447 | return (inp); |
448 | } |
449 | errexit("cannot find inode %llu\n", (unsigned long long)inumber); |
450 | return (NULL((void *)0)); |
451 | } |
452 | |
453 | /* |
454 | * Clean up all the inode cache structure. |
455 | */ |
456 | void |
457 | inocleanup(void) |
458 | { |
459 | struct inoinfo **inpp; |
460 | |
461 | if (inphead == NULL((void *)0)) |
462 | return; |
463 | for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) |
464 | free(*inpp); |
465 | free(inphead); |
466 | free(inpsort); |
467 | inphead = inpsort = NULL((void *)0); |
468 | } |
469 | |
470 | void |
471 | inodirty(void) |
472 | { |
473 | dirty(pbp)(pbp)->b_dirty = 1; |
474 | } |
475 | |
476 | void |
477 | clri(struct inodesc *idesc, char *type, int flag) |
478 | { |
479 | union dinode *dp; |
480 | |
481 | dp = ginode(idesc->id_number); |
482 | if (flag == 1) { |
483 | pwarn("%s %s", type, |
484 | (DIP(dp, di_mode)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_mode : (dp)->dp2.di_mode) & IFMT0170000) == IFDIR0040000 ? "DIR" : "FILE"); |
485 | pinode(idesc->id_number); |
486 | } |
487 | if (preen || reply("CLEAR") == 1) { |
488 | if (preen) |
489 | printf(" (CLEARED)\n"); |
490 | n_files--; |
491 | (void)ckinode(dp, idesc); |
492 | clearinode(dp)if ((*sblk.b_un.b_fs).fs_magic == 0x011954) { (dp)->dp1 = ufs1_zino ; } else { (dp)->dp2 = ufs2_zino; }; |
493 | SET_ISTATE(idesc->id_number, USTATE)do { (inoinfo(idesc->id_number)->ino_state) = (01); } while (0); |
494 | inodirty(); |
495 | } |
496 | } |
497 | |
498 | int |
499 | findname(struct inodesc *idesc) |
500 | { |
501 | struct direct *dirp = idesc->id_dirp; |
502 | |
503 | if (dirp->d_ino != idesc->id_parent) |
504 | return (KEEPON0x04); |
505 | memcpy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1); |
506 | return (STOP0x01|FOUND0x10); |
507 | } |
508 | |
509 | int |
510 | findino(struct inodesc *idesc) |
511 | { |
512 | struct direct *dirp = idesc->id_dirp; |
513 | |
514 | if (dirp->d_ino == 0) |
515 | return (KEEPON0x04); |
516 | if (strcmp(dirp->d_name, idesc->id_name) == 0 && |
517 | dirp->d_ino >= ROOTINO((ufsino_t)2) && dirp->d_ino <= maxino) { |
518 | idesc->id_parent = dirp->d_ino; |
519 | return (STOP0x01|FOUND0x10); |
520 | } |
521 | return (KEEPON0x04); |
522 | } |
523 | |
524 | void |
525 | pinode(ino_t ino) |
526 | { |
527 | union dinode *dp; |
528 | const char *p; |
529 | time_t t; |
530 | |
531 | printf(" I=%llu ", (unsigned long long)ino); |
532 | if (ino < ROOTINO((ufsino_t)2) || ino > maxino) |
533 | return; |
534 | dp = ginode(ino); |
535 | printf(" OWNER="); |
536 | #ifndef SMALL |
537 | if ((p = user_from_uid(DIP(dp, di_uid)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_uid : (dp)->dp2.di_uid), 1)) != NULL((void *)0)) |
538 | printf("%s ", p); |
539 | else |
540 | #endif |
541 | printf("%u ", (unsigned)DIP(dp, di_uid)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_uid : (dp)->dp2.di_uid)); |
542 | printf("MODE=%o\n", DIP(dp, di_mode)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_mode : (dp)->dp2.di_mode)); |
543 | if (preen) |
544 | printf("%s: ", cdevname()); |
545 | printf("SIZE=%llu ", (unsigned long long)DIP(dp, di_size)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_size : (dp)->dp2.di_size)); |
546 | t = DIP(dp, di_mtime)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_mtime : (dp)->dp2.di_mtime); |
547 | p = ctime(&t); |
548 | printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); |
549 | } |
550 | |
551 | void |
552 | blkerror(ino_t ino, char *type, daddr_t blk) |
553 | { |
554 | |
555 | pfatal("%lld %s I=%llu", blk, type, (unsigned long long)ino); |
556 | printf("\n"); |
557 | switch (GET_ISTATE(ino)(inoinfo(ino)->ino_state)) { |
558 | |
559 | case FSTATE02: |
560 | SET_ISTATE(ino, FCLEAR)do { (inoinfo(ino)->ino_state) = (06); } while (0); |
561 | return; |
562 | |
563 | case DSTATE03: |
564 | SET_ISTATE(ino, DCLEAR)do { (inoinfo(ino)->ino_state) = (05); } while (0); |
565 | return; |
566 | |
567 | case FCLEAR06: |
568 | case DCLEAR05: |
569 | return; |
570 | |
571 | default: |
572 | errexit("BAD STATE %d TO BLKERR\n", GET_ISTATE(ino)(inoinfo(ino)->ino_state)); |
573 | /* NOTREACHED */ |
574 | } |
575 | } |
576 | |
577 | /* |
578 | * allocate an unused inode |
579 | */ |
580 | ino_t |
581 | allocino(ino_t request, int type) |
582 | { |
583 | ino_t ino; |
584 | union dinode *dp; |
585 | struct bufarea *cgbp; |
586 | struct cg *cgp; |
587 | int cg; |
588 | time_t t; |
589 | struct inostat *info; |
590 | |
591 | if (request == 0) |
592 | request = ROOTINO((ufsino_t)2); |
593 | else if (GET_ISTATE(request)(inoinfo(request)->ino_state) != USTATE01) |
594 | return (0); |
595 | for (ino = request; ino < maxino; ino++) |
596 | if (GET_ISTATE(ino)(inoinfo(ino)->ino_state) == USTATE01) |
597 | break; |
598 | if (ino == maxino) |
599 | return (0); |
600 | cg = ino_to_cg(&sblock, ino)((ino) / (&(*sblk.b_un.b_fs))->fs_ipg); |
601 | /* If necessary, extend the inoinfo array. grow exponentially */ |
602 | if ((ino % sblock(*sblk.b_un.b_fs).fs_ipg) >= (uint64_t)inostathead[cg].il_numalloced) { |
603 | unsigned long newalloced, i; |
604 | newalloced = MINIMUM(sblock.fs_ipg,((((*sblk.b_un.b_fs).fs_ipg) < ((((2 * inostathead[cg].il_numalloced ) > (10)) ? (2 * inostathead[cg].il_numalloced) : (10)))) ? ((*sblk.b_un.b_fs).fs_ipg) : ((((2 * inostathead[cg].il_numalloced ) > (10)) ? (2 * inostathead[cg].il_numalloced) : (10)))) |
605 | MAXIMUM(2 * inostathead[cg].il_numalloced, 10))((((*sblk.b_un.b_fs).fs_ipg) < ((((2 * inostathead[cg].il_numalloced ) > (10)) ? (2 * inostathead[cg].il_numalloced) : (10)))) ? ((*sblk.b_un.b_fs).fs_ipg) : ((((2 * inostathead[cg].il_numalloced ) > (10)) ? (2 * inostathead[cg].il_numalloced) : (10)))); |
606 | info = Calloc(newalloced, sizeof(struct inostat)); |
607 | if (info == NULL((void *)0)) { |
608 | pwarn("cannot alloc %zu bytes to extend inoinfo\n", |
609 | sizeof(struct inostat) * newalloced); |
610 | return 0; |
611 | } |
612 | memmove(info, inostathead[cg].il_stat, |
613 | inostathead[cg].il_numalloced * sizeof(*info)); |
614 | for (i = inostathead[cg].il_numalloced; i < newalloced; i++) { |
615 | info[i].ino_state = USTATE01; |
616 | } |
617 | if (inostathead[cg].il_numalloced) |
618 | free(inostathead[cg].il_stat); |
619 | inostathead[cg].il_stat = info; |
620 | inostathead[cg].il_numalloced = newalloced; |
621 | info = inoinfo(ino); |
622 | } |
623 | cgbp = cglookup(cg); |
624 | cgp = cgbp->b_un.b_cg; |
625 | if (!cg_chkmagic(cgp)((cgp)->cg_magic == 0x090255 || ((struct ocg *)(cgp))-> cg_magic == 0x090255)) |
626 | pfatal("CG %d: BAD MAGIC NUMBER\n", cg); |
627 | setbit(cg_inosused(cgp), ino % sblock.fs_ipg)(((((cgp)->cg_magic != 0x090255) ? (((struct ocg *)(cgp))-> cg_iused) : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff ))))[(ino % (*sblk.b_un.b_fs).fs_ipg)>>3] |= 1<<( (ino % (*sblk.b_un.b_fs).fs_ipg)&(8 -1))); |
628 | cgp->cg_cs.cs_nifree--; |
629 | |
630 | switch (type & IFMT0170000) { |
631 | case IFDIR0040000: |
632 | SET_ISTATE(ino, DSTATE)do { (inoinfo(ino)->ino_state) = (03); } while (0); |
633 | cgp->cg_cs.cs_ndir++; |
634 | break; |
635 | case IFREG0100000: |
636 | case IFLNK0120000: |
637 | SET_ISTATE(ino, FSTATE)do { (inoinfo(ino)->ino_state) = (02); } while (0); |
638 | break; |
639 | default: |
640 | return (0); |
641 | } |
642 | dirty(cgbp)(cgbp)->b_dirty = 1; |
643 | dp = ginode(ino); |
644 | DIP_SET(dp, di_db[0], allocblk(1))do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_db[0] = (allocblk(1)); else (dp)->dp2.di_db[0] = (allocblk (1)); } while (0); |
645 | if (DIP(dp, di_db[0])(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_db [0] : (dp)->dp2.di_db[0]) == 0) { |
646 | SET_ISTATE(ino, USTATE)do { (inoinfo(ino)->ino_state) = (01); } while (0); |
647 | return (0); |
648 | } |
649 | DIP_SET(dp, di_mode, type)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_mode = (type); else (dp)->dp2.di_mode = (type); } while (0); |
650 | DIP_SET(dp, di_uid, geteuid())do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_uid = (geteuid()); else (dp)->dp2.di_uid = (geteuid()) ; } while (0); |
651 | DIP_SET(dp, di_gid, getegid())do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_gid = (getegid()); else (dp)->dp2.di_gid = (getegid()) ; } while (0); |
652 | DIP_SET(dp, di_flags, 0)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_flags = (0); else (dp)->dp2.di_flags = (0); } while (0 ); |
653 | (void)time(&t); |
654 | DIP_SET(dp, di_atime, t)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_atime = (t); else (dp)->dp2.di_atime = (t); } while (0 ); |
655 | DIP_SET(dp, di_atimensec, 0)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_atimensec = (0); else (dp)->dp2.di_atimensec = (0); } while (0); |
656 | DIP_SET(dp, di_mtime, t)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_mtime = (t); else (dp)->dp2.di_mtime = (t); } while (0 ); |
657 | DIP_SET(dp, di_mtimensec, 0)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_mtimensec = (0); else (dp)->dp2.di_mtimensec = (0); } while (0); |
658 | DIP_SET(dp, di_ctime, t)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_ctime = (t); else (dp)->dp2.di_ctime = (t); } while (0 ); |
659 | DIP_SET(dp, di_ctimensec, 0)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_ctimensec = (0); else (dp)->dp2.di_ctimensec = (0); } while (0); |
660 | DIP_SET(dp, di_size, sblock.fs_fsize)do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_size = ((*sblk.b_un.b_fs).fs_fsize); else (dp)->dp2.di_size = ((*sblk.b_un.b_fs).fs_fsize); } while (0); |
661 | DIP_SET(dp, di_blocks, btodb(sblock.fs_fsize))do { if ((*sblk.b_un.b_fs).fs_magic == 0x011954) (dp)->dp1 .di_blocks = ((((*sblk.b_un.b_fs).fs_fsize) >> 9)); else (dp)->dp2.di_blocks = ((((*sblk.b_un.b_fs).fs_fsize) >> 9)); } while (0); |
662 | n_files++; |
663 | inodirty(); |
664 | SET_ITYPE(ino, IFTODT(type))do { (inoinfo(ino)->ino_type) = ((((type) & 0170000) >> 12)); } while (0); |
665 | return (ino); |
666 | } |
667 | |
668 | /* |
669 | * deallocate an inode |
670 | */ |
671 | void |
672 | freeino(ino_t ino) |
673 | { |
674 | struct inodesc idesc; |
675 | union dinode *dp; |
676 | |
677 | memset(&idesc, 0, sizeof(struct inodesc)); |
678 | idesc.id_type = ADDR2; |
679 | idesc.id_func = pass4check; |
680 | idesc.id_number = ino; |
681 | dp = ginode(ino); |
682 | (void)ckinode(dp, &idesc); |
683 | clearinode(dp)if ((*sblk.b_un.b_fs).fs_magic == 0x011954) { (dp)->dp1 = ufs1_zino ; } else { (dp)->dp2 = ufs2_zino; }; |
684 | inodirty(); |
685 | SET_ISTATE(ino, USTATE)do { (inoinfo(ino)->ino_state) = (01); } while (0); |
686 | n_files--; |
687 | } |