|
|
1.1 root 1: /*
2: * Virtual memory for fsck. Uses hash algorithm
3: * rather than LRU to get it up fast.
4: */
5: #include "assert.h" /* special copy with printf() not fprintf() */
6: #include <sys/stat.h>
7: #include "fsck.h"
8: #if SMALLMODEL
9:
10: #define VBLKB 9 /* bytes in virtual block as power of 2 */
11: #define VBLK (1 << VBLKB) /* bytes in a virtual block */
12: #define MBKSB 6 /* number of virtual blocks as power of 2 */
13: #define MBKS (1 << MBKSB) /* number of virtual blocks */
14:
15: #define DVTMP "/dev/rram1" /* Default Virtual Temp Filename */
16: #define DVTMPCLS "/dev/rram1close" /* Default Virtual Temp File Close */
17: #define MAJORRAM 8 /* Major Device Number for the Ram Disk */
18:
19: struct mapper {
20: unsigned dirty:1;
21: unsigned what_in:15; /* which block is in memory */
22: };
23:
24: static unsigned long flagdsp, blkdsp, dupdsp, duplim;
25: static struct mapper map[MBKS];
26: static unsigned char data[MBKS][VBLK];
27: static int tmp;
28:
29: static char *dvtmp = DVTMP;
30: static char *dvtmpcls = DVTMPCLS;
31:
32: /*
33: * Init file system for virtual arrays.
34: * Data is ordered links, flags, blocks then dups.
35: */
36: initV(links, flags, blocks, dups)
37: unsigned links, flags, blocks, dups;
38: {
39: register long bp;
40: struct stat st;
41: unsigned datasiz;
42:
43: flagdsp = links;
44: blkdsp = flagdsp + flags;
45: dupdsp = blkdsp + blocks;
46: duplim = dupdsp + dups;
47:
48: memset(map, 0, sizeof(map)); /* zero ram arrays */
49: memset(data, 0, sizeof(data));
50:
51: tmp = -1;
52:
53: datasiz = sizeof(data);
54: if ( duplim < datasiz )
55: return;
56:
57: if ( tempFile == NULL ) {
58: switch ( is_fs(dvtmp) ) {
59: case -1:
60: fatal(
61: "Can't access ram disk \"%s\", use the -t option", dvtmp);
62: case 0:
63: break;
64: case 1:
65: fatal(
66: "Possible file system on ram disk \"%s\", use the -t option", dvtmp);
67: }
68: if ( (-1 == stat(dvtmp, &st)) || !(st.st_mode&S_IFCHR) ||
69: (major(st.st_rdev) != MAJORRAM) )
70: fatal("Ram disk \"%s\" not mknod'ed properly",
71: dvtmp);
72: if ( -1 == (tmp = open(dvtmp, 2)) )
73: fatal("Cannot open read/write Ram Disk \"%s\"", dvtmp);
74:
75: /* Ram disk driver may not promise zeroed start.
76: * This code may go later. Extra write not important. */
77: for(bp = 0; bp < duplim; bp += VBLK) /* zero disk stuff */
78: if ( VBLK != write(tmp, data[0], VBLK) )
79: fatal("Error writing to tmp file");
80: } else {
81: if ( -1 == (tmp = open(tempFile, 2)) ) {
82: if ( -1 == (tmp = creat(tempFile, 0600)) )
83: fatal("Cannot create temp file \"%s\"",
84: tempFile);
85: close(tmp);
86: tmp = open(tempFile, 2);
87: unlink(tempFile);
88: }
89: if ( -1 == fstat(tmp, &st) )
90: fatal("Can't stat temp file \"%s\"", tempFile);
91: if ( st.st_dev == fsysrdev )
92: fatal("Temp File must not be on file system to fsck");
93: }
94: }
95:
96: /*
97: * cleanup virtual system
98: */
99: cleanV()
100: {
101: struct stat st;
102:
103: if ( tmp == -1 ) /* No Virtual Temp File Opened */
104: return;
105:
106: close(tmp);
107: if ( tempFile != NULL ) /* Virtual File not Default RAMDisk */
108: return;
109: /* Virtual File is Default RAMDisk */
110: if ( (-1 == stat(dvtmpcls, &st)) || !(st.st_mode&S_IFCHR) ||
111: (major(st.st_rdev) != MAJORRAM) ||
112: ((minor(st.st_rdev)&0x7F) != 0) )
113: fatal("Ram disk close \"%s\" not mknod'ed properly", dvtmpcls);
114: if ( -1 == (tmp = open(dvtmpcls, 2)) )
115: fatal("Cannot open Ram Disk Close \"%s\"", dvtmpcls);
116: if ( close(tmp) < 0 )
117: fatal("Cannot close Ram Disk Close \"%s\"", dvtmpcls);
118: }
119:
120: /*
121: * All actions for virtual array
122: */
123: findblock(bp, action, odata)
124: long bp; /* data address */
125: enum vact action; /* what to do */
126: unsigned odata; /* optional data */
127: {
128: unsigned which, what_in, byte_no, bit;
129: unsigned long diskad;
130: unsigned char *byte;
131: extern long lseek();
132:
133: switch(action) { /* use displacment to correct part of file */
134: case testBlock:
135: case markBlock:
136: case unmarkBlock:
137: bit = 1 << (bp & 7);
138: bp >>= 3;
139: case grabBlock: /* 8 at a time for copy */
140: assert(bp >= 0);
141: bp += blkdsp;
142: assert(bp < dupdsp);
143: break;
144: case testDup:
145: case markDup:
146: case unmarkDup:
147: bit = 1 << (bp & 7);
148: bp >>= 3;
149: case setDup: /* 8 at a time for copy */
150: assert(bp >= 0);
151: bp += dupdsp;
152: assert(bp < duplim);
153: break;
154: case Flags:
155: case setFlags:
156: case orFlags:
157: assert(bp > 0);
158: bp += flagdsp - 1;
159: assert(bp < blkdsp);
160: break;
161: case linkCtr:
162: case incLinkctr:
163: case setLinkctr:
164: assert(bp > 0);
165: bp--;
166: assert(bp < flagdsp);
167: }
168:
169: byte_no = bp & (VBLK - 1);
170: bp >>= VBLKB;
171: which = bp & (MBKS - 1);
172: bp >>= MBKSB;
173: what_in = bp & 0x7fff;
174:
175: if((diskad = map[which].what_in) != what_in) {
176: if(map[which].dirty) {
177: diskad <<= VBLKB + MBKSB;
178: diskad += which << VBLKB;
179: if(-1 == lseek(tmp, diskad, 0))
180: fatal("Error seeking tmp file");
181: if(VBLK != write(tmp, data[which], VBLK))
182: fatal("Error writing tmp file");
183: }
184: diskad = what_in;
185: diskad <<= VBLKB + MBKSB;
186: diskad += which << VBLKB;
187: if(-1 == lseek(tmp, diskad, 0))
188: fatal("Error seeking tmp file");
189: if(VBLK != read(tmp, data[which], VBLK))
190: memset(data[which], 0, VBLK);
191: map[which].what_in = what_in;
192: map[which].dirty = 0; /* clean */
193: }
194: byte = &data[which][byte_no];
195:
196: switch(action) {
197: case testBlock:
198: case testDup:
199: return(*byte & bit);
200: case markBlock:
201: case markDup:
202: map[which].dirty = 1;
203: return(*byte |= bit);
204: case unmarkBlock:
205: case unmarkDup:
206: map[which].dirty = 1;
207: return(*byte ^= bit);
208: case linkCtr:
209: case Flags:
210: case grabBlock:
211: return(*byte);
212: case setLinkctr:
213: case setFlags:
214: case setDup:
215: map[which].dirty = 1;
216: return(*byte = odata);
217: case orFlags:
218: map[which].dirty = 1;
219: return(*byte |= odata);
220: case incLinkctr:
221: map[which].dirty = 1;
222: return(++*byte);
223: default:
224: fatal("Bad action in virtual system");
225: }
226: }
227:
228: /*
229: * copy virtual memory blockmap to dupmap
230: * read and write groups to avoid possable thrashing.
231: */
232: void
233: copyV(size)
234: unsigned size;
235: {
236: char buf[128];
237: register int i;
238: long bp, bs;
239:
240: for(bs = bp = 0; bp < size; ) {
241: for(i = 0; (i < 128) && (bp < size); i++, bp++)
242: buf[i] = findblock(bp, grabBlock);
243:
244: for(i = 0; (i < 128) && (bs < size); i++, bs++)
245: findblock(bs, setDup, buf[i]);
246: }
247: }
248:
249: #ifdef TEST
250: fatal(s)
251: char *s;
252: {
253: printf("%s\n", s);
254: exit(1);
255: }
256:
257: static char buf[80];
258: gbuf()
259: {
260: if(NULL == gets(buf)) {
261: unlink("vtmp");
262: exit(0);
263: }
264: return(buf[0]);
265: }
266:
267: main()
268: {
269: unsigned long b;
270: char data;
271:
272: initV(10000, 10000, 20000);
273: for(;;) {
274: printf("b = block, d = dup, f = flags, l = linkctr\n");
275: switch(gbuf()) {
276: case 'l':
277: printf("s = set, d = display, i = increment: then loc\n");
278: gbuf();
279: sscanf(buf + 2, "%ld", &b);
280: switch(buf[0]) {
281: case 's':
282: setlinkctr(b, 0); /* no data */
283: case 'd':
284: printf("%d\n", linkctr(b));
285: break;
286: case 'i':
287: printf("%d\n", inclinkctr(b));
288: }
289: break;
290: case 'f':
291: printf("d = display, s = set, o = or: then loc\n");
292: gbuf();
293: sscanf(buf + 2, "%ld %c", &b, &data);
294: switch(buf[0]) {
295: case 's':
296: setflags(b, data);
297: case 'd':
298: break;
299: case 'o':
300: orflags(b, data);
301: }
302: printf("%c\n", flags(b));
303: break;
304: case 'b':
305: printf("t = test, m = mark, u = unmark: then loc\n");
306: gbuf();
307: sscanf(buf + 2, "%ld", &b);
308: switch(buf[0]) {
309: case 'm':
310: markblock(b);
311: case 't':
312: break;
313: case 'u':
314: unmarkblock(b);
315: }
316: printf("%c\n", testblock(b) ? '1' : '0');
317: break;
318: case 'd':
319: printf("t = test, m = mark, u = unmark: then loc\n");
320: gbuf();
321: sscanf(buf + 2, "%ld", &b);
322: switch(buf[0]) {
323: case 'm':
324: markdup(b);
325: case 't':
326: break;
327: case 'u':
328: unmarkdup(b);
329: }
330: printf("%c\n", testdup(b) ? '1' : '0');
331: break;
332: }
333: }
334: }
335: #endif
336: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.