|
|
1.1 root 1: #include <libc.h>
2: #include "worm.h"
3: #include "sym.h"
4: #include <sys/types.h>
5: #include <sys/stat.h>
6: #include <fio.h>
7:
8: Inode **inos;
9: long nino;
10: int fdT, fdF;
11: char *inonames;
12: char *timenow();
13: char *tmp = "/tmp";
14:
15: cmp(a, b)
16: Inode **a, **b;
17: {
18: return(strcmp((*a)->name.n, (*b)->name.n));
19: }
20:
21: main(argc, argv)
22: char **argv;
23: {
24: Superblock s, news;
25: char *e;
26: char *dev = "/dev/worm0";
27: int c, fd;
28: char dbname[256];
29: extern char *optarg;
30: extern int optind;
31: void blkfn();
32:
33: while((c = getopt(argc, argv, "t:f:")) != -1)
34: switch(c)
35: {
36: case 'f': dev = optarg; break;
37: case 't': tmp = optarg; break;
38: case '?': usage();
39: }
40: dev = mapdev(dev);
41: if(optind != argc-1)
42: usage();
43: sprint(dbname, "%s/cbt%d", tmp, getpid());
44: fd = dbinit(dbname);
45: if((s.fd = open(dev, 2)) < 0){
46: perror(dev);
47: exit(1);
48: }
49: if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
50: fprint(2, "%s: %s\n", dev, e);
51: exit(1);
52: }
53: if(strcmp(argv[optind], s.vol_id)){
54: fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id);
55: exit(1);
56: }
57: if((inos = (Inode **)malloc(sizeof(inos[0])*(int)numinodes)) == 0){
58: fprint(2, "out of memory (%d inodes, %d bytes)\n", numinodes, sizeof(inos[0])*(int)numinodes);
59: exit(1);
60: }
61: nino = 0;
62: inodetraverse(blkfn);
63: fprint(2, "%s: sorting inodes\n", timenow());
64: qsort((char *)inos, (int)nino, sizeof(inos[0]), cmp);
65: news = s;
66: news.ninodes = nino;
67: creatdb(fd, dbname, &news); /* fills in nF, nT, inochars */
68: c = NBLKS(&news, news.nF)+NBLKS(&news, news.nT)+NBLKS(&news, news.ninochars);
69: if(c > news.nfree){
70: fprint(2, "%s: sorry, not enough blocks; %d+%d+%d>%d\n", news.vol_id,
71: NBLKS(&news, news.nF), NBLKS(&news, news.nT),
72: NBLKS(&news, news.ninochars), news.nfree);
73: exit(1);
74: }
75: Seek(&s, news.binodes = s.nextffree);
76: fdwrite(&s, fdF, (int)news.nF);
77: fdwrite(&s, fdT, (int)news.nT);
78: memwrite(&s, inonames, (int)news.ninochars);
79: /* set up link ptrs so that zeroing block zero undoes btreeing */
80: s.nfree -= c;
81: s.nextffree += c;
82: s.ninodes = 0;
83: if(e = lkwsb(&s))
84: fprint(2, "%s\n", e);
85: news.nextffree = s.nextffree;
86: news.nfree = s.nfree;
87: news.myblock = 0;
88: news.version = VBTREE;
89: news.nextsb = s.myblock;
90: time(&news.ctime);
91: Seek(&s, news.myblock);
92: free((char *)inos);
93: e = malloc(news.blocksize);
94: if(e == 0){
95: fprint(2, "wbtree: unbelievable malloc fail of %d\n", news.blocksize);
96: exit(1);
97: }
98: memset(e, 0, news.blocksize);
99: *((Superblock *)e) = news;
100: Write(&s, e, 1L);
101: exit(0);
102: }
103:
104: usage()
105: {
106: fprint(2, "Usage: worm btree [-fdevice] [-ttmpdir] vol_id\n");
107: exit(2);
108: }
109:
110: dbinit(name)
111: char *name;
112: {
113: char buf[256];
114: struct stat sbuf;
115: int pid, pip[2];
116:
117: fprint(2, "%s: init db '%s'\n", timenow(), name);
118: sprint(buf, "cbt creat %s", name);
119: if(system(buf))
120: exit(1);
121: pipe(pip);
122: pid = fork();
123: if(pid < 0){
124: perror("fork");
125: exit(1);
126: }
127: if(pid){
128: close(pip[0]);
129: return(pip[1]);
130: } else {
131: close(pip[1]);
132: dup2(pip[0], 0);
133: close(pip[0]);
134: execl("/usr/lib/btree/btbuild", "btbuild", name, 0);
135: perror("execl");
136: exit(1);
137: return(0);
138: }
139: }
140:
141: creatdb(fd, name, s)
142: char *name;
143: Superblock *s; /* fills in nF, nT, inochars */
144: {
145: char buf[256];
146: struct stat sbuf;
147: int status, i;
148: short n;
149: char *np;
150:
151: fprint(2, "%s: creating db '%s'\n", timenow(), name);
152: inonames = malloc((int)numnamechars+1024);
153: if(inonames == 0){
154: sprint(buf, "malloc(%d) namechars failed", numnamechars+1024);
155: perror(buf);
156: exit(1);
157: }
158: Finit(fd, (char *)0);
159: np = inonames;
160: for(i = 0; i < nino; i++){
161: n = strlen(inos[i]->name.n);
162: Fwrite(fd, (char *)&n, 2L);
163: Fwrite(fd, inos[i]->name.n, (long)n);
164: memcpy(np, inos[i]->name.n, n+1);
165: inos[i]->name.o = np - inonames;
166: np += n+1;
167: n = sizeof(Inode);
168: Fwrite(fd, (char *)&n, 2L);
169: Fwrite(fd, (char *)inos[i], (long)n);
170: }
171: s->ninochars = np-inonames;
172: Fflush(fd);
173: close(fd);
174: if(wait(&status) < 0){
175: perror("wbtree: wait");
176: exit(1);
177: }
178: if(status){
179: fprint(2, "wbtree: bad status %d from btbuild\n", status);
180: exit(1);
181: }
182: sprint(buf, "%s.F", name);
183: if(((fdF = open(buf, 0)) < 0) || (fstat(fdF, &sbuf) < 0)){
184: perror(buf);
185: exit(1);
186: }
187: unlink(buf);
188: s->nF = sbuf.st_size;
189: sprint(buf, "%s.T", name);
190: if(((fdT = open(buf, 0)) < 0) || (fstat(fdT, &sbuf) < 0)){
191: perror(buf);
192: exit(1);
193: }
194: unlink(buf);
195: s->nT = sbuf.st_size;
196: fprint(2, "%s: db done\n", timenow());
197: }
198:
199: void
200: blkfn(i)
201: Inode *i;
202: {
203: inos[nino++] = i;
204: }
205:
206: fdwrite(s, fd, cnt)
207: Superblock *s;
208: {
209: char b[BIGBLOCK];
210: int n;
211:
212: lseek(fd, 0L, 0);
213: while(cnt >= sizeof b){
214: n = read(fd, b, sizeof b);
215: if(n != sizeof b){
216: perror("short read");
217: exit(3);
218: }
219: Write(s, b, NBLKS(s, sizeof b));
220: cnt -= sizeof b;
221: }
222: if(cnt){
223: if(read(fd, b, cnt) != cnt){
224: perror("short read");
225: exit(4);
226: }
227: memset(b+cnt, 0, sizeof b - cnt);
228: Write(s, b, NBLKS(s, cnt));
229: }
230: }
231:
232: memwrite(s, base, cnt)
233: Superblock *s;
234: char *base;
235: {
236: int chunk = (BIGBLOCK/1024)*s->blocksize;
237:
238: while(cnt >= chunk){
239: Write(s, base, NBLKS(s, chunk));
240: cnt -= chunk;
241: base += chunk;
242: }
243: if(cnt)
244: Write(s, base, NBLKS(s, cnt));
245: }
246:
247: char *
248: timenow()
249: {
250: long tim;
251: char *tims;
252:
253: time(&tim);
254: tims = ctime(&tim);
255: tims[19] = 0;
256: return(tims);
257: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.