Commit | Line | Data |
---|---|---|
7026cd3f KM |
1 | #ifndef lint |
2 | static char version[] = "@(#)inode.c 3.1 (Berkeley) %G%"; | |
3 | #endif | |
4 | ||
5 | #include <sys/param.h> | |
6 | #include <sys/inode.h> | |
7 | #include <sys/fs.h> | |
8 | #include <sys/dir.h> | |
9 | #include "fsck.h" | |
10 | ||
11 | ckinode(dp, idesc) | |
12 | DINODE *dp; | |
13 | register struct inodesc *idesc; | |
14 | { | |
15 | register daddr_t *ap; | |
16 | int ret, n, ndb, offset; | |
17 | DINODE dino; | |
18 | ||
19 | if (SPECIAL) | |
20 | return (KEEPON); | |
21 | dino = *dp; | |
22 | idesc->id_fix = DONTKNOW; | |
23 | idesc->id_entryno = 0; | |
24 | ndb = howmany(dino.di_size, sblock.fs_bsize); | |
25 | for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { | |
26 | if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) | |
27 | idesc->id_numfrags = | |
28 | numfrags(&sblock, fragroundup(&sblock, offset)); | |
29 | else | |
30 | idesc->id_numfrags = sblock.fs_frag; | |
31 | if (*ap == 0) | |
32 | continue; | |
33 | idesc->id_blkno = *ap; | |
34 | if (idesc->id_type == ADDR) | |
35 | ret = (*idesc->id_func)(idesc); | |
36 | else | |
37 | ret = dirscan(idesc); | |
38 | if (ret & STOP) | |
39 | return (ret); | |
40 | } | |
41 | idesc->id_numfrags = sblock.fs_frag; | |
42 | for (ap = &dino.di_ib[0], n = 1; n <= 2; ap++, n++) { | |
43 | if (*ap) { | |
44 | idesc->id_blkno = *ap; | |
45 | ret = iblock(idesc, n, | |
46 | dino.di_size - sblock.fs_bsize * NDADDR); | |
47 | if (ret & STOP) | |
48 | return (ret); | |
49 | } | |
50 | } | |
51 | return (KEEPON); | |
52 | } | |
53 | ||
54 | iblock(idesc, ilevel, isize) | |
55 | struct inodesc *idesc; | |
56 | register ilevel; | |
57 | long isize; | |
58 | { | |
59 | register daddr_t *ap; | |
60 | register daddr_t *aplim; | |
61 | int i, n, (*func)(), nif; | |
62 | BUFAREA ib; | |
63 | ||
64 | if (idesc->id_type == ADDR) { | |
65 | func = idesc->id_func; | |
66 | if (((n = (*func)(idesc)) & KEEPON) == 0) | |
67 | return (n); | |
68 | } else | |
69 | func = dirscan; | |
70 | if (outrange(idesc->id_blkno, idesc->id_numfrags)) /* protect thyself */ | |
71 | return (SKIP); | |
72 | initbarea(&ib); | |
73 | if (getblk(&ib, idesc->id_blkno, sblock.fs_bsize) == NULL) | |
74 | return (SKIP); | |
75 | ilevel--; | |
76 | if (ilevel == 0) { | |
77 | nif = lblkno(&sblock, isize) + 1; | |
78 | } else /* ilevel == 1 */ { | |
79 | nif = isize / (sblock.fs_bsize * NINDIR(&sblock)) + 1; | |
80 | } | |
81 | if (nif > NINDIR(&sblock)) | |
82 | nif = NINDIR(&sblock); | |
83 | aplim = &ib.b_un.b_indir[nif]; | |
84 | for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++) | |
85 | if (*ap) { | |
86 | idesc->id_blkno = *ap; | |
87 | if (ilevel > 0) | |
88 | n = iblock(idesc, ilevel, | |
89 | isize - i*NINDIR(&sblock)*sblock.fs_bsize); | |
90 | else | |
91 | n = (*func)(idesc); | |
92 | if (n & STOP) | |
93 | return (n); | |
94 | } | |
95 | return (KEEPON); | |
96 | } | |
97 | ||
98 | outrange(blk, cnt) | |
99 | daddr_t blk; | |
100 | int cnt; | |
101 | { | |
102 | register int c; | |
103 | ||
104 | if ((unsigned)(blk+cnt) > fmax) | |
105 | return (1); | |
106 | c = dtog(&sblock, blk); | |
107 | if (blk < cgdmin(&sblock, c)) { | |
108 | if ((blk+cnt) > cgsblock(&sblock, c)) { | |
109 | if (debug) { | |
110 | printf("blk %d < cgdmin %d;", | |
111 | blk, cgdmin(&sblock, c)); | |
112 | printf(" blk+cnt %d > cgsbase %d\n", | |
113 | blk+cnt, cgsblock(&sblock, c)); | |
114 | } | |
115 | return (1); | |
116 | } | |
117 | } else { | |
118 | if ((blk+cnt) > cgbase(&sblock, c+1)) { | |
119 | if (debug) { | |
120 | printf("blk %d >= cgdmin %d;", | |
121 | blk, cgdmin(&sblock, c)); | |
122 | printf(" blk+cnt %d > sblock.fs_fpg %d\n", | |
123 | blk+cnt, sblock.fs_fpg); | |
124 | } | |
125 | return (1); | |
126 | } | |
127 | } | |
128 | return (0); | |
129 | } | |
130 | ||
131 | DINODE * | |
132 | ginode(inumber) | |
133 | ino_t inumber; | |
134 | { | |
135 | daddr_t iblk; | |
136 | static ino_t startinum = 0; /* blk num of first in raw area */ | |
137 | ||
138 | ||
139 | if (inumber < ROOTINO || inumber > imax) { | |
140 | if (debug && inumber > imax) | |
141 | printf("inumber out of range (%d)\n", inumber); | |
142 | return (NULL); | |
143 | } | |
144 | if (startinum == 0 || | |
145 | inumber < startinum || inumber >= startinum + INOPB(&sblock)) { | |
146 | iblk = itod(&sblock, inumber); | |
147 | if (getblk(&inoblk, iblk, sblock.fs_bsize) == NULL) { | |
148 | return (NULL); | |
149 | } | |
150 | startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); | |
151 | } | |
152 | return (&inoblk.b_un.b_dinode[inumber % INOPB(&sblock)]); | |
153 | } | |
154 | ||
155 | clri(idesc, s, flg) | |
156 | register struct inodesc *idesc; | |
157 | char *s; | |
158 | int flg; | |
159 | { | |
160 | register DINODE *dp; | |
161 | ||
162 | if ((dp = ginode(idesc->id_number)) == NULL) | |
163 | return; | |
164 | if (flg == 1) { | |
165 | pwarn("%s %s", s, DIRCT?"DIR":"FILE"); | |
166 | pinode(idesc->id_number); | |
167 | } | |
168 | if (preen || reply("CLEAR") == 1) { | |
169 | if (preen) | |
170 | printf(" (CLEARED)\n"); | |
171 | n_files--; | |
172 | (void)ckinode(dp, idesc); | |
173 | zapino(dp); | |
174 | statemap[idesc->id_number] = USTATE; | |
175 | inodirty(); | |
176 | inosumbad++; | |
177 | } | |
178 | } | |
179 | ||
180 | findino(idesc) | |
181 | struct inodesc *idesc; | |
182 | { | |
183 | register DIRECT *dirp = idesc->id_dirp; | |
184 | ||
185 | if (dirp->d_ino == 0) | |
186 | return (KEEPON); | |
187 | if (!strcmp(dirp->d_name, srchname)) { | |
188 | if (dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) | |
189 | idesc->id_parent = dirp->d_ino; | |
190 | return (STOP); | |
191 | } | |
192 | return (KEEPON); | |
193 | } | |
194 | ||
195 | pinode(ino) | |
196 | ino_t ino; | |
197 | { | |
198 | register DINODE *dp; | |
199 | register char *p; | |
200 | char uidbuf[BUFSIZ]; | |
201 | char *ctime(); | |
202 | ||
203 | printf(" I=%u ", ino); | |
204 | if ((dp = ginode(ino)) == NULL) | |
205 | return; | |
206 | printf(" OWNER="); | |
207 | if (getpw((int)dp->di_uid, uidbuf) == 0) { | |
208 | for (p = uidbuf; *p != ':'; p++); | |
209 | *p = 0; | |
210 | printf("%s ", uidbuf); | |
211 | } | |
212 | else { | |
213 | printf("%d ", dp->di_uid); | |
214 | } | |
215 | printf("MODE=%o\n", dp->di_mode); | |
216 | if (preen) | |
217 | printf("%s: ", devname); | |
218 | printf("SIZE=%ld ", dp->di_size); | |
219 | p = ctime(&dp->di_mtime); | |
220 | printf("MTIME=%12.12s %4.4s ", p+4, p+20); | |
221 | } | |
222 | ||
223 | blkerr(ino, s, blk) | |
224 | ino_t ino; | |
225 | char *s; | |
226 | daddr_t blk; | |
227 | { | |
228 | ||
229 | pfatal("%ld %s I=%u", blk, s, ino); | |
230 | printf("\n"); | |
231 | statemap[ino] = CLEAR; | |
232 | } |