|
|
1.1 root 1: #include "fs.h"
2: int rerunmsg;
3:
4: attach(n)
5: { int lf;
6: char x[24];
7: if(imap[n].type == Unalloc) {
8: pmesg("ino %d is unallocated, not put in lost+found\n", n);
9: return;
10: }
11: pmesg("re-attaching ino %d\n", n);
12: lf = nams(ROOTINO, "lost+found");
13: if(lf <= 0)
14: lf = mkdir(ROOTINO, "lost+found");
15: if(lf <= 0) {
16: pmesg("can't find or create /lost+found. HELP!\n");
17: exitcode = 1;
18: return;
19: }
20: sprintf(x, "%d", n);
21: if(addtodir(lf, n, x) >= 0) {
22: imap[n].nrefs++;
23: fixlinks(n);
24: }
25: }
26:
27: mkdir(n, s)
28: char *s;
29: { int i, b;
30: struct dinode *dip;
31: struct direct *dp;
32: i = alloci(Dir);
33: dip = (struct dinode *) (buf + 2*bsize + (i-1)*sizeof(*dip));
34: dip->di_mode = (IFDIR | 0777);
35: dip->di_uid = dip->di_gid = 0;
36: b = allocb(i, First);
37: dip->di_nlink = imap[i].nrefs = 2; /* a little lie */
38: dip->di_ctime = dip->di_mtime = dip->di_atime = time(0);
39: /* now write . and .. */
40: memset(buf, 0, bsize);
41: dp = (struct direct *) buf;
42: dp->d_ino = i;
43: strcpy(dp->d_name, ".");
44: dp++;
45: dp->d_ino = n;
46: strcpy(dp->d_name, "..");
47: if(bwrite(b, buf, 1)) {
48: pmesg("write of new dir blk %d failed\n", b);
49: return(-1);
50: }
51: /* now stick it in its parent */
52: if(addtodir(n, i, "lost+found") >= 0) {
53: wrti(i);
54: return(i);
55: }
56: pmesg("addtodir failed\n");
57: return(-1);
58: }
59:
60: fndfr(dir, pbno, n)
61: int *pbno;
62: { struct direct *dp;
63: int i;
64: if(bread(n, buf, 1)) {
65: pmesg("couldn't read dir block %d\n", n);
66: return(-1);
67: }
68: *pbno = n;
69: dp = (struct direct *) buf;
70: for(i = 0; i < bsize/sizeof(*dp); i++, dp++)
71: if(dp->d_ino == 0)
72: return(i);
73: return(-1);
74: }
75:
76: addtodir(dir, ino, s)
77: char *s;
78: { int i, bno;
79: struct direct *dp;
80: i = nami(dir, ino);
81: if(i >= 0) {
82: pmesg("ino %d already in dir (%d,%s) (it's ok)\n", ino, dir, prname(dir));
83: /* since you cared enough to ask for it: */
84: imap[ino].parent = dir;
85: return(-1);
86: }
87: i = dirsrch(dir, &bno, fndfr);
88: if(i < 0) {
89: bno = allocb(dir, Other);
90: wrti(dir);
91: memset(buf, 0, bsize);
92: i = 0;
93: }
94: dp = (struct direct *)buf + i;
95: dp->d_ino = ino;
96: strncpy(dp->d_name, s, DIRSIZ);
97: imap[ino].parent = dir;
98: /* if ino was a directory, its wretched pointers are wrong */
99: if(flags['w'] && bwrite(bno, buf, 1) < 0) {
100: pmesg("couldn't rewrite dir block %d\n", bno);
101: return(-1);
102: }
103: if(!rerunmsg++)
104: pmesg("!!counts may be wrong, RERUN chuck!\n");
105: return(0);
106: }
107:
108: alloci(t)
109: { int i;
110: for(i = 2; i < ninode; i++)
111: if(imap[i].type == Unalloc) {
112: imap[i].type = t;
113: /* and adjust some counts? */
114: return(i);
115: }
116: return(-1);
117: }
118:
119: /* doesn't understand about holes BUG*/
120: allocb(ino, t)
121: { int i, j;
122: long addr[NADDR];
123: struct dinode *dip;
124: dip = (struct dinode *) (buf + 2*bsize + (ino-1)*sizeof(*dip));
125: l3tol(addr, dip->di_addr, NADDR);
126: for(j = 0; j < NADDR-3; j++) /* secret knowledge!! */
127: if(!addr[j])
128: break;
129: if(j >= NADDR-3) {
130: pmesg("won't allocate indirect block (bug)%d %d\n"); /* BUG */
131: return(-1);
132: }
133: dip->di_size += 4096;
134: for(i = fblk; i < lblk; i++)
135: if(bmap[i].type == Free) {
136: bmap[i].ino = ino;
137: bmap[i].type = t;
138: addr[j] = i;
139: ltol3(dip->di_addr, addr, NADDR);
140: /* and adjust some counts? */
141: return(i);
142: }
143: pmesg("no more free blocks\n");
144: return(-1);
145: }
146:
147: expg(dir, x, n)
148: { struct direct *dp;
149: static struct direct nildp;
150: int i;
151: if(bread(n, buf, 1)) {
152: pmesg("expg read block %d failed\n", n);
153: return(-1);
154: }
155: dp = (struct direct *) buf;
156: for(i = 0; i < bsize/sizeof(*dp); i++ , dp++)
157: if(dp->d_ino == x) {
158: *dp = nildp;
159: if(flags['w'] && bwrite(n, buf, 1))
160: pmesg("couldn't rewrite dir block\n");
161: }
162: return(-1); /* in case it occurs many times in the directory */
163: }
164: /* remove the ref to the inode from a directory it's in */
165: /* if you want more than one, run it lots of times */
166: expunge(n)
167: { int i, j;
168: j = imap[n].parent;
169: if(!j || imap[j].type != Dir) {
170: pmesg("parent is %d, not dir\n", j);
171: return(-1);
172: }
173: i = dirsrch(j, n, expg);
174: }
175:
176: fixdots(ino)
177: { struct dinode *dp = (struct dinode *)(buf + 2*bsize + (ino-1)*sizeof(*dp));
178: int addr[NADDR], i;
179: if(imap[ino].type == Unalloc) /* someone else really fixed it */
180: return;
181: pmesg("fixdots %s\n", prino(ino));
182: if(imap[ino].type != Dir) {
183: pmesg("fixdir called on non-dir %s\n", prino(ino));
184: return;
185: }
186: /* now redo all the checking and fix everything in sight */
187: l3tol(addr, dp->di_addr, NADDR);
188: if(fixfirst(ino, dp, addr[0]) < 0) {
189: pmesg("too hard, try rerunning chuck\n");
190: exitcode++;
191: rerunmsg++;
192: return;
193: }
194: for(i = 0; i < erptr; i++)
195: switch(erlist[i].type) {
196: case Enotdot: case Edotino: case Enotdotdot: case Ebadparent:
197: if(erlist[i].a == ino)
198: erlist[i].done = 1;
199: }
200: }
201:
202: fixfirst(ino, dp, addr)
203: struct dinode *dp;
204: { struct direct *d;
205: static struct direct nildir;
206: int i;
207: if(addr < fblk || addr >= lblk) {
208: pmesg("first block address %d bogus\n", addr); /* FIX */
209: return(-1);
210: }
211: if(bread(addr, buf, 1) < 0) {
212: pmesg("couldn't read %d\n", addr);
213: return(-1);
214: }
215: d = (struct direct *) buf;
216: if(firstspace() < 0) /* make space at beginning for . and .. */
217: return(-1);
218: /* this strategy may leave some link counts wrong, FIX */
219: /* also, who made dp->d_size large enough? FIX */
220: *d = nildir;
221: d->d_ino = ino;
222: strcpy(d->d_name, ".");
223: d++;
224: i = imap[ino].parent; /* what if we are a directory? FIX */
225: if(i < ROOTINO || i >= ninode) {
226: pmesg("parent is %d, and so illegal\n", i);
227: return(-1);
228: }
229: *d = nildir;
230: d->d_ino = i;
231: strcpy(d->d_name, "..");
232: if(flags['w'] && bwrite(addr, buf, 1) < 0) {
233: pmesg("couldn't rewrite %d\n");
234: return(-1);
235: }
236: return(0);
237: }
238:
239: firstspace()
240: { struct direct *dp = (struct direct *)buf;
241: int i, cnt, baddot, baddotdot, fa, fb;
242: for(fa = fb = cnt = i = 0; i < bsize/sizeof(*dp); i++) {
243: if(dp->d_ino)
244: continue;
245: cnt++;
246: if(!fa) {
247: fa = i;
248: continue;
249: }
250: if(!fb)
251: fb = i;
252: }
253: dp = (struct direct *) buf;
254: baddot = strcmp(dp->d_name, ".");
255: baddotdot = strcmp(dp[1].d_name, "..");
256: if(cnt - baddot - baddotdot < 0) {
257: pmesg("first block of directory overfull\n");
258: return(-1); /* too hard FIX */
259: }
260: if(baddot)
261: dp[fa] = dp[0];
262: if(baddotdot)
263: dp[fb] = dp[1];
264: return(0);
265: }
266:
267: xfxnm(dir, ret, n)
268: int *ret;
269: { struct direct *dp;
270: int i, j, cnt = 0;
271: if(bread(n, buf, 1)) {
272: pmesg("dir %d couldn't read dir block %d\n", dir, n);
273: return(*ret = -1);
274: }
275: dp = (struct direct *)buf;
276: for(i = 0; i < bsize/sizeof(*dp); i++, dp++) {
277: if(!dp->d_ino)
278: continue;
279: if(dp->d_ino == dir && dp->d_name[0] != '.') { /* FIX */
280: dp->d_ino = 0; /* dirs can't refer to themselves */
281: /* link count now wrong, in safe direction */
282: }
283: if(dp->d_ino < 1 || dp->d_ino >= ninode)
284: dp->d_ino = 0; /* bad inumber */
285: if(imap[dp->d_ino].type == Unalloc) { /* ambitious FIX*/
286: if(cnt++ == 10)
287: pmesg("...\n");
288: else if(cnt < 10)
289: pmesg("dir entry %d,%.16s unalloc inode\n", dp->d_ino,
290: dp->d_name);
291: dp->d_ino = 0;
292: }
293: for(j = 0; j < DIRSIZ; j++) {
294: if(!dp->d_name[j])
295: break;
296: if(dp->d_name[j] & 0x80) { /* ascii! */
297: dp->d_name[j] &= 0x7f;
298: j--; /* did we zero it? */
299: continue;
300: }
301: }
302: if(j == 0) {
303: pmesg("ino %d in dir %d had no name\n", dp->d_ino, dir);
304: pmesg("being called #%d\n", dp->d_ino);
305: sprintf(dp->d_name, "#%d", dp->d_ino);
306: continue;
307: }
308: for(; j < DIRSIZ;j++)
309: dp->d_name[j] = 0;
310: }
311: if(flags['w'] && bwrite(n, buf, 1)) {
312: pmesg("couldn't rewrite blk %d ino %d\n", n, dir);
313: return(*ret = -1);
314: }
315: return(-1);
316: }
317: fixnames(ino)
318: { int retcode = 0, j;
319: (void) dirsrch(ino, &retcode, xfxnm);
320: if(retcode < 0) {
321: pmesg("fixnames failed\n");
322: return;
323: }
324: for(j = 0; j < erptr; j++)
325: if(erlist[j].type == Ebadname && erlist[j].a == ino)
326: erlist[j].done = 1;
327: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.