|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)inode.c 5.2 (Berkeley) 7/17/85";
9: #endif not lint
10:
11: #include <pwd.h>
12: #include <sys/param.h>
13: #include <sys/inode.h>
14: #include <sys/fs.h>
15: #include <sys/dir.h>
16: #include "fsck.h"
17:
18: ckinode(dp, idesc)
19: DINODE *dp;
20: register struct inodesc *idesc;
21: {
22: register daddr_t *ap;
23: int ret, n, ndb, offset;
24: DINODE dino;
25:
26: idesc->id_fix = DONTKNOW;
27: idesc->id_entryno = 0;
28: idesc->id_filesize = dp->di_size;
29: if (SPECIAL(dp))
30: return (KEEPON);
31: dino = *dp;
32: ndb = howmany(dino.di_size, sblock.fs_bsize);
33: for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) {
34: if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
35: idesc->id_numfrags =
36: numfrags(&sblock, fragroundup(&sblock, offset));
37: else
38: idesc->id_numfrags = sblock.fs_frag;
39: if (*ap == 0)
40: continue;
41: idesc->id_blkno = *ap;
42: if (idesc->id_type == ADDR)
43: ret = (*idesc->id_func)(idesc);
44: else
45: ret = dirscan(idesc);
46: if (ret & STOP)
47: return (ret);
48: }
49: idesc->id_numfrags = sblock.fs_frag;
50: for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
51: if (*ap) {
52: idesc->id_blkno = *ap;
53: ret = iblock(idesc, n,
54: dino.di_size - sblock.fs_bsize * NDADDR);
55: if (ret & STOP)
56: return (ret);
57: }
58: }
59: return (KEEPON);
60: }
61:
62: iblock(idesc, ilevel, isize)
63: struct inodesc *idesc;
64: register ilevel;
65: long isize;
66: {
67: register daddr_t *ap;
68: register daddr_t *aplim;
69: int i, n, (*func)(), nif, sizepb;
70: BUFAREA ib;
71: char buf[BUFSIZ];
72: extern int pass1check();
73:
74: if (idesc->id_type == ADDR) {
75: func = idesc->id_func;
76: if (((n = (*func)(idesc)) & KEEPON) == 0)
77: return (n);
78: } else
79: func = dirscan;
80: if (outrange(idesc->id_blkno, idesc->id_numfrags)) /* protect thyself */
81: return (SKIP);
82: initbarea(&ib);
83: getblk(&ib, idesc->id_blkno, sblock.fs_bsize);
84: if (ib.b_errs != NULL)
85: return (SKIP);
86: ilevel--;
87: for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
88: sizepb *= NINDIR(&sblock);
89: nif = isize / sizepb + 1;
90: if (nif > NINDIR(&sblock))
91: nif = NINDIR(&sblock);
92: if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
93: aplim = &ib.b_un.b_indir[NINDIR(&sblock)];
94: for (ap = &ib.b_un.b_indir[nif]; ap < aplim; ap++) {
95: if (*ap == 0)
96: continue;
97: sprintf(buf, "PARTIALLY TRUNCATED INODE I=%d",
98: idesc->id_number);
99: if (dofix(idesc, buf)) {
100: *ap = 0;
101: dirty(&ib);
102: }
103: }
104: flush(&dfile, &ib);
105: }
106: aplim = &ib.b_un.b_indir[nif];
107: for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++)
108: if (*ap) {
109: idesc->id_blkno = *ap;
110: if (ilevel > 0)
111: n = iblock(idesc, ilevel, isize - i * sizepb);
112: else
113: n = (*func)(idesc);
114: if (n & STOP)
115: return (n);
116: }
117: return (KEEPON);
118: }
119:
120: outrange(blk, cnt)
121: daddr_t blk;
122: int cnt;
123: {
124: register int c;
125:
126: if ((unsigned)(blk+cnt) > fmax)
127: return (1);
128: c = dtog(&sblock, blk);
129: if (blk < cgdmin(&sblock, c)) {
130: if ((blk+cnt) > cgsblock(&sblock, c)) {
131: if (debug) {
132: printf("blk %d < cgdmin %d;",
133: blk, cgdmin(&sblock, c));
134: printf(" blk+cnt %d > cgsbase %d\n",
135: blk+cnt, cgsblock(&sblock, c));
136: }
137: return (1);
138: }
139: } else {
140: if ((blk+cnt) > cgbase(&sblock, c+1)) {
141: if (debug) {
142: printf("blk %d >= cgdmin %d;",
143: blk, cgdmin(&sblock, c));
144: printf(" blk+cnt %d > sblock.fs_fpg %d\n",
145: blk+cnt, sblock.fs_fpg);
146: }
147: return (1);
148: }
149: }
150: return (0);
151: }
152:
153: DINODE *
154: ginode(inumber)
155: ino_t inumber;
156: {
157: daddr_t iblk;
158: static ino_t startinum = 0; /* blk num of first in raw area */
159:
160: if (inumber < ROOTINO || inumber > imax)
161: errexit("bad inode number %d to ginode\n", inumber);
162: if (startinum == 0 ||
163: inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
164: iblk = itod(&sblock, inumber);
165: getblk(&inoblk, iblk, sblock.fs_bsize);
166: startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
167: }
168: return (&inoblk.b_un.b_dinode[inumber % INOPB(&sblock)]);
169: }
170:
171: clri(idesc, s, flg)
172: register struct inodesc *idesc;
173: char *s;
174: int flg;
175: {
176: register DINODE *dp;
177:
178: dp = ginode(idesc->id_number);
179: if (flg == 1) {
180: pwarn("%s %s", s, DIRCT(dp) ? "DIR" : "FILE");
181: pinode(idesc->id_number);
182: }
183: if (preen || reply("CLEAR") == 1) {
184: if (preen)
185: printf(" (CLEARED)\n");
186: n_files--;
187: (void)ckinode(dp, idesc);
188: zapino(dp);
189: statemap[idesc->id_number] = USTATE;
190: inodirty();
191: }
192: }
193:
194: findname(idesc)
195: struct inodesc *idesc;
196: {
197: register DIRECT *dirp = idesc->id_dirp;
198:
199: if (dirp->d_ino != idesc->id_parent)
200: return (KEEPON);
201: bcopy(dirp->d_name, idesc->id_name, dirp->d_namlen + 1);
202: return (STOP);
203: }
204:
205: findino(idesc)
206: struct inodesc *idesc;
207: {
208: register DIRECT *dirp = idesc->id_dirp;
209:
210: if (dirp->d_ino == 0)
211: return (KEEPON);
212: if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
213: dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) {
214: idesc->id_parent = dirp->d_ino;
215: return (STOP);
216: }
217: return (KEEPON);
218: }
219:
220: pinode(ino)
221: ino_t ino;
222: {
223: register DINODE *dp;
224: register char *p;
225: struct passwd *pw;
226: char *ctime();
227:
228: printf(" I=%u ", ino);
229: if (ino < ROOTINO || ino > imax)
230: return;
231: dp = ginode(ino);
232: printf(" OWNER=");
233: if ((pw = getpwuid((int)dp->di_uid)) != 0)
234: printf("%s ", pw->pw_name);
235: else
236: printf("%d ", dp->di_uid);
237: printf("MODE=%o\n", dp->di_mode);
238: if (preen)
239: printf("%s: ", devname);
240: printf("SIZE=%ld ", dp->di_size);
241: p = ctime(&dp->di_mtime);
242: printf("MTIME=%12.12s %4.4s ", p+4, p+20);
243: }
244:
245: blkerr(ino, s, blk)
246: ino_t ino;
247: char *s;
248: daddr_t blk;
249: {
250:
251: pfatal("%ld %s I=%u", blk, s, ino);
252: printf("\n");
253: switch (statemap[ino]) {
254:
255: case FSTATE:
256: statemap[ino] = FCLEAR;
257: return;
258:
259: case DSTATE:
260: statemap[ino] = DCLEAR;
261: return;
262:
263: case FCLEAR:
264: case DCLEAR:
265: return;
266:
267: default:
268: errexit("BAD STATE %d TO BLKERR", statemap[ino]);
269: /* NOTREACHED */
270: }
271: }
272:
273: /*
274: * allocate an unused inode
275: */
276: ino_t
277: allocino(request, type)
278: ino_t request;
279: int type;
280: {
281: register ino_t ino;
282: register DINODE *dp;
283:
284: if (request == 0)
285: request = ROOTINO;
286: else if (statemap[request] != USTATE)
287: return (0);
288: for (ino = request; ino < imax; ino++)
289: if (statemap[ino] == USTATE)
290: break;
291: if (ino == imax)
292: return (0);
293: switch (type & IFMT) {
294: case IFDIR:
295: statemap[ino] = DSTATE;
296: break;
297: case IFREG:
298: case IFLNK:
299: statemap[ino] = FSTATE;
300: break;
301: default:
302: return (0);
303: }
304: dp = ginode(ino);
305: dp->di_db[0] = allocblk(1);
306: if (dp->di_db[0] == 0) {
307: statemap[ino] = USTATE;
308: return (0);
309: }
310: dp->di_mode = type;
311: time(&dp->di_atime);
312: dp->di_mtime = dp->di_ctime = dp->di_atime;
313: dp->di_size = sblock.fs_fsize;
314: dp->di_blocks = btodb(sblock.fs_fsize);
315: n_files++;
316: inodirty();
317: return (ino);
318: }
319:
320: /*
321: * deallocate an inode
322: */
323: freeino(ino)
324: ino_t ino;
325: {
326: struct inodesc idesc;
327: extern int pass4check();
328: DINODE *dp;
329:
330: bzero((char *)&idesc, sizeof(struct inodesc));
331: idesc.id_type = ADDR;
332: idesc.id_func = pass4check;
333: idesc.id_number = ino;
334: dp = ginode(ino);
335: (void)ckinode(dp, &idesc);
336: zapino(dp);
337: inodirty();
338: statemap[ino] = USTATE;
339: n_files--;
340: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.