|
|
1.1 root 1: #include <libc.h>
2: #include "worm.h"
3: #include <sys/types.h>
4: #include <sys/udaioc.h>
5:
6: usage()
7: {
8: fprint(2, "Usage: worm mkfs [-fdevice] [-ccomments] [-bblksize] [-nnblks] [-vnewvol_id] vol_id\n");
9: fprint(2, "e.g. worm mkfs -f1 -c\"512x512x24 movies\" tdmovies1a\n");
10: exit(1);
11: }
12:
13: main(argc, argv)
14: char **argv;
15: {
16: Superblock s, os;
17: char *b;
18: long sb;
19: int c;
20: char *volid;
21: char *dev = "/dev/worm0";
22: char *nblks = 0;
23: char *bsize = 0;
24: char *nvolid = 0;
25: char *comments = 0;
26: char *e;
27: int virgin;
28: extern optind;
29: extern char *optarg;
30:
31: while((c = getopt(argc, argv, "f:n:b:c:v:")) != -1)
32: switch(c)
33: {
34: case 'b': bsize = optarg; break;
35: case 'c': comments = optarg; break;
36: case 'f': dev = optarg; break;
37: case 'n': nblks = optarg; break;
38: case 'v': nvolid = optarg; break;
39: case '?': usage();
40: }
41: if(optind != argc-1)
42: usage();
43: volid = argv[optind];
44: if(strlen(volid) > sizeof(s.vol_id)-1)
45: volid[sizeof(s.vol_id)-1] = 0;
46: c = volid[strlen(volid)-1];
47: if((c != 'a') && (c != 'b')){
48: if(nvolid == 0){
49: fprint(2, "worm mkfs: vol_id '%s' must end in 'a' or 'b'\n", volid);
50: exit(1);
51: }
52: fprint(2, "worm mkfs: warning: vol_id '%s' should end in 'a' or 'b'\n", volid);
53: }
54: if(nvolid){
55: if(strlen(nvolid) > sizeof(s.vol_id)-1)
56: nvolid[sizeof(s.vol_id)-1] = 0;
57: c = nvolid[strlen(nvolid)-1];
58: if((c != 'a') && (c != 'b')){
59: fprint(2, "worm mkfs: vol_id '%s' must end in 'a' or 'b'\n", nvolid);
60: exit(1);
61: }
62: }
63: dev = mapdev(dev);
64: if((s.fd = open(dev, 2)) < 0){
65: perror(dev);
66: exit(1);
67: }
68: /*
69: now, do we read the current superblock or make one up?
70: this is hard to answer in general, push the answer off to virginal()
71: */
72: virgin = virginal(&s);
73: if(virgin){
74: setdefaults(&s, nblks);
75: if((s.blocksize < 512) || (s.blocksize%512)){
76: fprint(2, "worm mkfs: bad blocksize '%s'\n", bsize);
77: exit(1);
78: }
79: strcpy(s.vol_id, volid);
80: } else {
81: if(strcmp(volid, s.vol_id)){
82: fprint(2, "worm mkfs: volid mismatch; expected %s, got %s\n",
83: volid, s.vol_id);
84: exit(1);
85: }
86: }
87: /* set any new parameters */
88: if(nvolid)
89: strcpy(s.vol_id, nvolid);
90: if(bsize)
91: s.blocksize = atoi(bsize);
92: if(s.blocksize < 512){
93: fprint(2, "wormmkfs: bad nblocks = '%s'\n", nblks);
94: exit(1);
95: }
96: if(s.blocksize % sizeof(Inode)){
97: fprint(2, "worm mkfs: sizeof(Inode)=%d does not divide blocksize %d\n",
98: sizeof(Inode), s.blocksize);
99: exit(1);
100: }
101: if(comments){
102: if(strlen(comments) > sizeof(s.comment)-1)
103: comments[sizeof(s.comment)-1] = 0;
104: strcpy(s.comment, comments);
105: }
106: /* only check if we are changing it */
107: if(nblks && !virgin){
108: s.nblocks = atoi(nblks);
109: s.nfree = s.nblocks - s.nextffree;
110: if(s.nfree <= 1){
111: fprint(2, "worm mkfs: new nblocks(%d) is too small\n", s.nblocks);
112: exit(1);
113: }
114: }
115: /* now allocate the new superblock */
116: sb = s.nextsb;
117: s.myblock = sb;
118: s.nextsb = sb+1;
119: s.nextffree = sb+2;
120: s.nfree -= 1;
121: s.ninodes = 0;
122: s.ninochars = 0;
123: s.binodes = 0;
124: time(&s.ctime);
125: /* write it */
126: if((b = malloc(s.blocksize)) == 0){
127: fprint(2, "worm mkfs: cannot malloc buffer %d bytes\n", s.blocksize);
128: exit(1);
129: }
130: memset(b, 0, s.blocksize);
131: memcpy(b, (char *)&s, sizeof(s));
132: Seek(&s, sb);
133: if(Write(&s, b, 1L))
134: exit(1);
135: ioctl(s.fd, UIOSPDW);
136: exit(0);
137: }
138:
139: setdefaults(s, nblks)
140: Superblock *s;
141: char *nblks;
142: {
143: struct ud_unit sz;
144: char buf[1024];
145:
146: s->magic = SMAGIC;
147: s->blocksize = 1024;
148: s->version = VLINK;
149: if(nblks){
150: s->nblocks = atoi(nblks);
151: if(s->nblocks <= 2){
152: fprint(2, "worm mkfs: nblocks(%d) too small\n", s->nblocks);
153: exit(1);
154: }
155: } else {
156: read(s->fd, buf, sizeof buf); /* ignore error */
157: if(ioctl(s->fd, UIOCHAR, &sz) >= 0){
158: switch(sz.radsize)
159: { /* note below figures/2 used in scsi/volid.c */
160: case 3275999: /* sony 12in clv single density */
161: s->nblocks = 1600000;
162: break;
163: case 6551999: /* sony 12in clv double density */
164: s->nblocks = 3250000;
165: break;
166: default:
167: fprint(2, "worm mkfs: unknown size %d\n", sz.radsize);
168: exit(1);
169: }
170: } else
171: s->nblocks = 1600000;
172: fprint(2, "worm mkfs: using disk size %d\n", s->nblocks);
173: }
174: s->zero = 0;
175: s->nfree = s->nblocks-1;
176: s->nextffree = 0;
177: s->nextsb = 1;
178: s->vol_id[0] = 0;
179: s->comment[0] = 0;
180: s->myblock = 0;
181: s->ctime = 0;
182: }
183:
184: virginal(s)
185: Superblock *s;
186: {
187: char buf[1024];
188: static char zeros[1024];
189: long sb;
190: char *e;
191: extern char *getenv();
192:
193: if(e = getenv("WORMZERO"))
194: sb = atoi(e);
195: else
196: sb = 1;
197: bigseek(s->fd, sb, 1024, 0);
198: errno = 0;
199: if(read(s->fd, buf, 1024) == 1024)
200: goto valid;
201: if((errno != ENXIO) && (errno != 0) && memcmp(buf, zeros, 1024))
202: goto invalid;
203: errno = 0;
204: if(read(s->fd, buf, 1024) == 1024){ /* try next block */
205: valid:
206: if(e = openinode(s, SPIN_DOWN)){
207: fprint(2, "worm mkfs: %s\n", e);
208: exit(1);
209: }
210: return(0);
211: } else {
212: if((errno == ENXIO) || (errno == 0) || (memcmp(buf, zeros, 1024) == 0))
213: return(1);
214: invalid:
215: perror("worm mkfs: I/O errors probing for superblock");
216: exit(1);
217: }
218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.