date and time created 84/03/31 21:03:42 by mckusick
[unix-history] / usr / src / sbin / fsck / inode.c
CommitLineData
7026cd3f
KM
1#ifndef lint
2static 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
11ckinode(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
54iblock(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
98outrange(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
131DINODE *
132ginode(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
155clri(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
180findino(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
195pinode(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
223blkerr(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}