edit to incorperate -r1.6 reorganization of fs.h
[unix-history] / usr / src / sbin / newfs / mkfs.c
CommitLineData
0947395d 1static char *sccsid = "@(#)mkfs.c 1.9 (Berkeley) %G%";
d746d022
KM
2
3/*
4 * make file system for cylinder-group style file systems
5 *
6 * usage: mkfs fs proto
7 * or: mkfs size [ nsect ntrak cpg ]
8 */
9
10#define NDIRECT (BSIZE/sizeof(struct direct))
11#define MAXFN 500
12
d746d022
KM
13#ifndef STANDALONE
14#include <stdio.h>
15#include <a.out.h>
16#endif
17
18#include "../h/param.h"
d746d022
KM
19#include "../h/inode.h"
20#include "../h/fs.h"
21#include "../h/dir.h"
22
23time_t utime;
24
25#ifndef STANDALONE
26FILE *fin;
27#else
28int fin;
29#endif
30
31int fsi;
32int fso;
33char *charp;
34char buf[BSIZE];
35#ifndef STANDALONE
36struct exec head;
37#endif
38char string[50];
39
40union {
41 struct fs fs;
42 char pad[BSIZE];
43} fsun;
44#define sblock fsun.fs
45struct csum *fscs;
46
47union {
48 struct cg cg;
49 char pad[BSIZE];
50} cgun;
51#define acg cgun.cg
52
53#define howmany(x, y) (((x)+((y)-1))/(y))
54#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
55
56char *fsys;
57char *proto;
58int error;
59ino_t ino = ROOTINO - 1;
60long getnum();
61daddr_t alloc();
62
63struct dinode zino[MAXIPG];
64
65main(argc, argv)
66char *argv[];
67{
68 int f, c;
69 long i,n;
70
71 argc--, argv++;
72#ifndef STANDALONE
73 time(&utime);
74 if(argc < 2) {
75 printf("usage: mkfs sblock proto/size [ nsect ntrak cpg ]\n");
76 exit(1);
77 }
78 fsys = argv[0];
79 proto = argv[1];
80#else
81 {
82 static char protos[60];
83
84 printf("file sys size: ");
85 gets(protos);
86 proto = protos;
87 }
88#endif
89#ifdef STANDALONE
90 {
91 char fsbuf[100];
92
93 do {
94 printf("file system: ");
95 gets(fsbuf);
96 fso = open(fsbuf, 1);
97 fsi = open(fsbuf, 0);
98 } while (fso < 0 || fsi < 0);
99 }
100 fin = NULL;
101 argc = 0;
102#else
103 fso = creat(fsys, 0666);
104 if(fso < 0) {
105 printf("%s: cannot create\n", fsys);
106 exit(1);
107 }
108 fsi = open(fsys, 0);
109 if(fsi < 0) {
110 printf("%s: cannot open\n", fsys);
111 exit(1);
112 }
113 fin = fopen(proto, "r");
114#endif
115#ifndef STANDALONE
116 if (fin != NULL) {
117 getstr();
118 f = open(string, 0);
119 if (f < 0) {
120 printf("%s: cannot open init\n", string);
121 goto noinit;
122 }
123 read(f, (char *)&head, sizeof head);
124 c = head.a_text + head.a_data;
125 if (c > BSIZE)
126 printf("%s: too big\n", string);
127 else {
128 read(f, buf, c);
129 wtfs(BBLOCK, BSIZE, buf);
130 }
131 close(f);
132noinit:
133 n = sblock.fs_size = getnum();
134 sblock.fs_ntrak = getnum();
135 sblock.fs_nsect = getnum();
136 sblock.fs_cpg = getnum();
137 } else
138#endif
139 {
140 charp = "d--777 0 0 $ ";
141 n = 0;
142 for (f=0; c=proto[f]; f++) {
143 if (c<'0' || c>'9') {
144 printf("%s: cannot open\n", proto);
145 exit(1);
146 }
147 n = n*10 + (c-'0');
148 }
149 sblock.fs_size = n;
150 if (argc > 2)
151 sblock.fs_nsect = atoi(argv[2]);
152 else
153 sblock.fs_nsect = 32;
154 if (argc > 3)
155 sblock.fs_ntrak = atoi(argv[3]);
156 else
157 sblock.fs_ntrak = 19;
158 }
159 /*
160 * Now have size for file system and nsect and ntrak.
161 * (And, if coming from prototype, cpg).
162 * Determine number of cylinders occupied by file system.
163 */
164 if (sblock.fs_ntrak <= 0)
165 printf("preposterous ntrak %d\n", sblock.fs_ntrak), exit(1);
166 if (sblock.fs_nsect <= 0)
167 printf("preposterous nsect %d\n", sblock.fs_nsect), exit(1);
168 if (sblock.fs_size <= 0)
169 printf("preposterous size %d\n", sblock.fs_size), exit(1);
170 if (sblock.fs_ntrak * sblock.fs_nsect > MAXBPG * NSPB) {
171 printf("cylinder too large (%d sectors)\n",
172 sblock.fs_ntrak * sblock.fs_nsect);
173 printf("maximum cylinder size: %d sectors\n",
174 MAXBPG * NSPB);
175 exit(1);
176 }
177 sblock.fs_ncyl = n * NSPF / (sblock.fs_nsect * sblock.fs_ntrak);
178 if (n * NSPF > sblock.fs_ncyl * sblock.fs_nsect * sblock.fs_ntrak) {
179 printf("%d sector(s) in last cylinder unused\n",
180 n * NSPF - sblock.fs_ncyl * sblock.fs_nsect * sblock.fs_ntrak);
181 sblock.fs_ncyl++;
182 }
183 sblock.fs_magic = FS_MAGIC;
184 /*
185 * Validate specified/determined cpg.
186 */
187#define CGTOOBIG(fs) ((fs).fs_nsect*(fs).fs_ntrak*(fs).fs_cpg/NSPB > MAXBPG)
188 if (argc > 4 || fin) {
189 if (fin == NULL)
190 sblock.fs_cpg = atoi(argv[4]);
191 if (CGTOOBIG(sblock)) {
192 printf("cylinder group too large (%d blocks); ",
193 sblock.fs_cpg * sblock.fs_nsect * sblock.fs_ntrak / NSPB);
194 printf("max: %d blocks\n", MAXBPG);
195 exit(1);
196 }
197 if (sblock.fs_cpg > MAXCPG) {
198 printf("cylinder groups are limited to %d cylinders\n",
199 MAXCPG);
200 exit(1);
201 }
202 } else {
203 sblock.fs_cpg = DESCPG;
204 while (CGTOOBIG(sblock))
205 --sblock.fs_cpg;
206 }
207 /*
208 * Compute/validate number of cylinder groups.
209 */
210 sblock.fs_ncg = sblock.fs_ncyl / sblock.fs_cpg;
211 if (sblock.fs_ncyl % sblock.fs_cpg)
212 sblock.fs_ncg++;
213 if ((sblock.fs_nsect*sblock.fs_ntrak*sblock.fs_cpg) % NSPF) {
214 printf("mkfs: nsect %d, ntrak %d, cpg %d is not tolerable\n",
215 sblock.fs_nsect, sblock.fs_ntrak, sblock.fs_cpg);
216 printf("as this would would have cyl groups whose size\n");
217 printf("is not a multiple of %d; choke!\n", FSIZE);
218 exit(1);
219 }
220 fscs = (struct csum *)
221 calloc(1, roundup(sblock.fs_ncg * sizeof (struct csum), BSIZE));
222 /*
223 * Compute number of inode blocks per cylinder group.
224 * Start with one inode per NBPI bytes; adjust as necessary.
225 */
226 n = ((n * BSIZE) / NBPI) / INOPB;
227 if (n <= 0)
228 n = 1;
229 if (n > 65500/INOPB)
230 n = 65500/INOPB;
231 sblock.fs_ipg = ((n / sblock.fs_ncg) + 1) * INOPB;
232 if (sblock.fs_ipg < INOPB)
233 sblock.fs_ipg = INOPB;
234 if (sblock.fs_ipg > MAXIPG)
235 sblock.fs_ipg = MAXIPG;
236 while (sblock.fs_ipg * sblock.fs_ncyl > 65500)
237 sblock.fs_ipg -= INOPB;
238 sblock.fs_spc = sblock.fs_ntrak * sblock.fs_nsect;
239 sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / (FSIZE / 512);
240 if (cgdmin(0,&sblock) >= sblock.fs_fpg)
241 printf("inode blocks/cyl group (%d) >= data blocks (%d)\n",
242 cgdmin(0,&sblock)/FRAG, sblock.fs_fpg/FRAG), exit(1);
0947395d 243 sblock.fs_cstotal.cs_nifree = sblock.fs_ipg * sblock.fs_ncg;
d746d022
KM
244 sblock.fs_cgsize = cgsize(&sblock);
245 sblock.fs_cssize = cssize(&sblock);
246 sblock.fs_sblkno = SBLOCK;
247 sblock.fs_fmod = 0;
248 sblock.fs_ronly = 0;
249
250 /*
251 * Dump out information about file system.
252 */
253 printf("%s:\t%d sectors in %d cylinders of %d tracks, %d sectors\n",
254 fsys, sblock.fs_size*NSPF, sblock.fs_ncyl, sblock.fs_ntrak, sblock.fs_nsect);
255 printf("\t%.1fMb in %d cyl groups (%d c/g, %.2fMb/g, %d i/g)\n",
256 (float)sblock.fs_size*FSIZE*1e-6, sblock.fs_ncg, sblock.fs_cpg,
257 (float)sblock.fs_fpg*FSIZE*1e-6, sblock.fs_ipg);
258/*
259 printf("%7d size (%d blocks)\n", sblock.fs_size, sblock.fs_size/FRAG);
260 printf("%7d cylinder groups\n", sblock.fs_ncg);
261 printf("%7d cylinder group block size\n", sblock.fs_cgsize);
262 printf("%7d tracks\n", sblock.fs_ntrak);
263 printf("%7d sectors\n", sblock.fs_nsect);
264 printf("%7d sectors per cylinder\n", sblock.fs_spc);
265 printf("%7d cylinders\n", sblock.fs_ncyl);
266 printf("%7d cylinders per group\n", sblock.fs_cpg);
267 printf("%7d blocks per group\n", sblock.fs_fpg/FRAG);
268 printf("%7d inodes per group\n", sblock.fs_ipg);
269 if (sblock.fs_ncyl % sblock.fs_cpg) {
270 printf("%7d cylinders in last group\n",
271 i = sblock.fs_ncyl % sblock.fs_cpg);
272 printf("%7d blocks in last group\n",
273 i * sblock.fs_spc / NSPB);
274 }
275*/
276 /*
277 * Now build the cylinders group blocks and
278 * then print out indices of cylinder groups forwarded
279 * past bad blocks or other obstructions.
280 */
0947395d
KM
281 sblock.fs_cstotal.cs_ndir = 0;
282 sblock.fs_cstotal.cs_nbfree = 0;
283 sblock.fs_cstotal.cs_nifree = 0;
284 sblock.fs_cstotal.cs_nffree = 0;
743f1ef7
KM
285 sblock.fs_cgrotor = 0;
286 for (i = 0; i < NRPOS; i++)
287 sblock.fs_postbl[i] = -1;
288 for (i = 0; i < sblock.fs_spc; i += (NSPF * FRAG))
289 /* void */;
290 for (i -= (NSPF * FRAG); i >= 0; i -= (NSPF * FRAG)) {
291 c = i % sblock.fs_nsect * NRPOS / sblock.fs_nsect;
292 sblock.fs_rotbl[i / (NSPF * FRAG)] = sblock.fs_postbl[c];
293 sblock.fs_postbl[c] = i / (NSPF * FRAG);
294 }
d746d022
KM
295 for (c = 0; c < sblock.fs_ncg; c++)
296 initcg(c);
297 printf("\tsuper-block backups (for fsck -b#) at %d+k*%d (%d .. %d)\n",
298 SBLOCK, sblock.fs_fpg, SBLOCK+sblock.fs_fpg,
299 SBLOCK+(sblock.fs_ncg-1)*sblock.fs_fpg);
300 /*
301 * Now construct the initial file system, and
302 * then write out the super-block.
303 */
304 cfile((struct inode *)0);
305 sblock.fs_time = utime;
306 wtfs(SBLOCK, BSIZE, (char *)&sblock);
307 for (i = 0; i < cssize(&sblock); i += BSIZE)
308 wtfs(csaddr(&sblock) + i/BSIZE, BSIZE, ((char *)fscs)+i);
309 for (c = 0; c < sblock.fs_ncg; c++)
310 wtfs(cgsblock(c, &sblock), BSIZE, (char *)&sblock);
311#ifndef STANDALONE
312 exit(error);
313#endif
314}
315
316/*
317 * Initialize a cylinder group.
318 */
319initcg(c)
320 int c;
321{
322 daddr_t cbase, d, dmin, dmax;
323 long i, j, s;
324 register struct csum *cs;
325
326 /*
327 * Determine block bounds for cylinder group.
328 * Allow space for super block summary information in first
329 * cylinder group.
330 */
331 cbase = cgbase(c,&sblock);
332 dmax = cbase + sblock.fs_fpg;
333 if (dmax > sblock.fs_size)
334 dmax = sblock.fs_size;
f3c028b7 335 dmin = cgdmin(c,&sblock) - cbase;
d746d022
KM
336 d = cbase;
337 cs = fscs+c;
d746d022
KM
338 acg.cg_time = utime;
339 acg.cg_magic = CG_MAGIC;
340 acg.cg_cgx = c;
341 acg.cg_ncyl = sblock.fs_cpg;
342 acg.cg_niblk = sblock.fs_ipg;
343 acg.cg_ndblk = dmax - cbase;
0947395d
KM
344 acg.cg_cs.cs_ndir = 0;
345 acg.cg_cs.cs_nffree = 0;
346 acg.cg_cs.cs_nbfree = 0;
347 acg.cg_cs.cs_nifree = 0;
f3c028b7
KM
348 acg.cg_rotor = dmin;
349 acg.cg_frotor = dmin;
92ea6158 350 acg.cg_irotor = 0;
f3c028b7
KM
351 for (i = 0; i < FRAG; i++) {
352 acg.cg_frsum[i] = 0;
353 }
354 for (i = 0; i < sblock.fs_ipg; ) {
d746d022
KM
355 for (j = INOPB; j > 0; j--) {
356 clrbit(acg.cg_iused, i);
357 i++;
358 }
0947395d 359 acg.cg_cs.cs_nifree += INOPB;
d746d022
KM
360 }
361 while (i < MAXIPG) {
362 clrbit(acg.cg_iused, i);
363 i++;
364 }
365 lseek(fso, cgimin(c,&sblock)*FSIZE, 0);
366 if (write(fso, (char *)zino, sblock.fs_ipg * sizeof (struct dinode)) !=
367 sblock.fs_ipg * sizeof (struct dinode))
368 printf("write error %D\n", tell(fso) / BSIZE);
369 for (i = 0; i < MAXCPG; i++)
370 for (j = 0; j < NRPOS; j++)
371 acg.cg_b[i][j] = 0;
d746d022
KM
372 if (c == 0) {
373 dmin += howmany(cssize(&sblock), BSIZE) * FRAG;
374 }
375 for (d = 0; d < dmin; d += FRAG)
376 clrblock(acg.cg_free, d/FRAG);
377 while ((d+FRAG) <= dmax - cbase) {
56d45dcd 378 setblock(acg.cg_free, d/FRAG);
0947395d 379 acg.cg_cs.cs_nbfree++;
56d45dcd
KM
380 s = d * NSPF;
381 acg.cg_b[s/sblock.fs_spc]
382 [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++;
d746d022
KM
383 d += FRAG;
384 }
385 if (d < dmax - cbase)
56d45dcd
KM
386 for (; d < dmax - cbase; d++) {
387 setbit(acg.cg_free, d);
0947395d 388 acg.cg_cs.cs_nffree++;
56d45dcd 389 }
d746d022
KM
390 for (; d < MAXBPG; d++)
391 clrbit(acg.cg_free, d);
0947395d
KM
392 sblock.fs_dsize += acg.cg_ndblk - dmin;
393 sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir;
394 sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree;
395 sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree;
396 sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree;
397 *cs = acg.cg_cs;
d746d022
KM
398 wtfs(cgtod(c, &sblock), BSIZE, (char *)&acg);
399}
400
401cfile(par)
402struct inode *par;
403{
404 struct inode in;
405 int dbc, ibc;
406 char db[BSIZE];
407 daddr_t ib[NINDIR];
408 int i, f, c;
409
410 /*
411 * get mode, uid and gid
412 */
413
414 getstr();
415 in.i_mode = gmode(string[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
416 in.i_mode |= gmode(string[1], "-u", 0, ISUID, 0, 0);
417 in.i_mode |= gmode(string[2], "-g", 0, ISGID, 0, 0);
418 for(i=3; i<6; i++) {
419 c = string[i];
420 if(c<'0' || c>'7') {
421 printf("%c/%s: bad octal mode digit\n", c, string);
422 error = 1;
423 c = 0;
424 }
425 in.i_mode |= (c-'0')<<(15-3*i);
426 }
427 in.i_uid = getnum();
428 in.i_gid = getnum();
56d45dcd
KM
429 in.i_atime = utime;
430 in.i_mtime = utime;
431 in.i_ctime = utime;
d746d022
KM
432
433 /*
434 * general initialization prior to
435 * switching on format
436 */
437
438 ino++;
439 in.i_number = ino;
440 for(i=0; i<BSIZE; i++)
441 db[i] = 0;
442 for(i=0; i<NINDIR; i++)
443 ib[i] = (daddr_t)0;
444 in.i_nlink = 1;
445 in.i_size = 0;
446 for(i=0; i<NDADDR; i++)
56d45dcd 447 in.i_db[i] = (daddr_t)0;
d746d022 448 for(i=0; i<NIADDR; i++)
56d45dcd 449 in.i_ib[i] = (daddr_t)0;
d746d022
KM
450 if(par == (struct inode *)0) {
451 par = &in;
452 in.i_nlink--;
453 }
454 dbc = 0;
455 ibc = 0;
456 switch(in.i_mode&IFMT) {
457
458 case IFREG:
459 /*
460 * regular file
461 * contents is a file name
462 */
463
464 getstr();
465 f = open(string, 0);
466 if(f < 0) {
467 printf("%s: cannot open\n", string);
468 error = 1;
469 break;
470 }
471 while((i=read(f, db, BSIZE)) > 0) {
472 in.i_size += i;
07670f7d 473 newblk(&dbc, db, &ibc, ib, ibc < NDADDR ? i : BSIZE, 0);
d746d022
KM
474 }
475 close(f);
476 break;
477
478 case IFBLK:
479 case IFCHR:
480 /*
481 * special file
482 * content is maj/min types
483 */
484
485 i = getnum() & 0377;
486 f = getnum() & 0377;
56d45dcd 487 in.i_rdev = makedev(i, f);
d746d022
KM
488 break;
489
490 case IFDIR:
491 /*
492 * directory
493 * put in extra links
494 * call recursively until
495 * name of "$" found
496 */
497
498 par->i_nlink++;
499 in.i_nlink++;
500 entry(in.i_number, ".", &dbc, db, &ibc, ib);
501 entry(par->i_number, "..", &dbc, db, &ibc, ib);
502 in.i_size = 2*sizeof(struct direct);
503 for(;;) {
504 getstr();
505 if(string[0]=='$' && string[1]=='\0')
506 break;
07670f7d 507 if (in.i_size >= BSIZE * NDADDR) {
d746d022 508 printf("can't handle direct of > %d entries\n",
07670f7d 509 NDIRECT * NDADDR);
d746d022
KM
510 exit(1);
511 }
512 entry(ino+1, string, &dbc, db, &ibc, ib);
513 in.i_size += sizeof(struct direct);
514 cfile(&in);
515 }
07670f7d 516 newblk(&dbc, db, &ibc, ib, roundup(dbc, FSIZE), IFDIR);
d746d022
KM
517 break;
518 }
d746d022
KM
519 iput(&in, &ibc, ib);
520}
521
522gmode(c, s, m0, m1, m2, m3)
523char c, *s;
524{
525 int i;
526
527 for(i=0; s[i]; i++)
528 if(c == s[i])
529 return((&m0)[i]);
530 printf("%c/%s: bad mode\n", c, string);
531 error = 1;
532 return(0);
533}
534
535long
536getnum()
537{
538 int i, c;
539 long n;
540
541 getstr();
542 n = 0;
543 i = 0;
544 for(i=0; c=string[i]; i++) {
545 if(c<'0' || c>'9') {
546 printf("%s: bad number\n", string);
547 error = 1;
548 return((long)0);
549 }
550 n = n*10 + (c-'0');
551 }
552 return(n);
553}
554
555getstr()
556{
557 int i, c;
558
559loop:
560 switch(c=getch()) {
561
562 case ' ':
563 case '\t':
564 case '\n':
565 goto loop;
566
567 case '\0':
568 printf("EOF\n");
569 exit(1);
570
571 case ':':
572 while(getch() != '\n');
573 goto loop;
574
575 }
576 i = 0;
577
578 do {
579 string[i++] = c;
580 c = getch();
581 } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0');
582 string[i] = '\0';
583}
584
585rdfs(bno, size, bf)
586daddr_t bno;
587int size;
588char *bf;
589{
590 int n;
591
592 lseek(fsi, bno*FSIZE, 0);
593 n = read(fsi, bf, size);
594 if(n != size) {
595 printf("read error: %ld\n", bno);
596 exit(1);
597 }
598}
599
600wtfs(bno, size, bf)
601daddr_t bno;
602int size;
603char *bf;
604{
605 int n;
606
607 lseek(fso, bno*FSIZE, 0);
608 n = write(fso, bf, size);
609 if(n != size) {
610 printf("write error: %D\n", bno);
611 exit(1);
612 }
613}
614
615daddr_t
07670f7d
KM
616alloc(size, mode)
617 int size;
618 int mode;
d746d022
KM
619{
620 int c, i, s, frag;
621 daddr_t d;
622
623 c = 0;
624 rdfs(cgtod(0,&sblock), sblock.fs_cgsize, (char *)&acg);
0947395d 625 if (acg.cg_cs.cs_nbfree == 0) {
d746d022
KM
626 printf("first cylinder group ran out of space\n");
627 return (0);
628 }
629 for (d = 0; d < acg.cg_ndblk; d += FRAG)
630 if (isblock(acg.cg_free, d/FRAG))
631 goto goth;
632 printf("internal error: can't find block in cyl 0\n");
633 return (0);
634goth:
635 clrblock(acg.cg_free, d/FRAG);
0947395d
KM
636 acg.cg_cs.cs_nbfree--;
637 sblock.fs_cstotal.cs_nbfree--;
d746d022 638 fscs[0].cs_nbfree--;
07670f7d 639 if (mode & IFDIR) {
0947395d
KM
640 acg.cg_cs.cs_ndir++;
641 sblock.fs_cstotal.cs_ndir++;
07670f7d
KM
642 fscs[0].cs_ndir++;
643 }
d746d022
KM
644 s = d * NSPF;
645 acg.cg_b[s/sblock.fs_spc][s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]--;
646 if (size != BSIZE) {
647 frag = howmany(size, FSIZE);
0947395d
KM
648 fscs[0].cs_nffree += FRAG - frag;
649 sblock.fs_cstotal.cs_nffree += FRAG - frag;
650 acg.cg_cs.cs_nffree += FRAG - frag;
f3c028b7 651 acg.cg_frsum[FRAG - frag]++;
d746d022
KM
652 for (i = frag; i < FRAG; i++)
653 setbit(acg.cg_free, d+i);
654 }
655 wtfs(cgtod(0,&sblock), sblock.fs_cgsize, (char *)&acg);
656 return (d);
657}
658
659entry(inum, str, adbc, db, aibc, ib)
660ino_t inum;
661char *str;
662int *adbc, *aibc;
663char *db;
664daddr_t *ib;
665{
666 struct direct *dp;
667 int i;
668
07670f7d
KM
669 if (*adbc == NDIRECT)
670 newblk(adbc, db, aibc, ib, BSIZE, 0);
d746d022
KM
671 dp = (struct direct *)db;
672 dp += *adbc;
673 (*adbc)++;
674 dp->d_ino = inum;
675 for(i=0; i<DIRSIZ; i++)
676 dp->d_name[i] = 0;
677 for(i=0; i<DIRSIZ; i++)
678 if((dp->d_name[i] = str[i]) == 0)
679 break;
d746d022
KM
680}
681
07670f7d
KM
682newblk(adbc, db, aibc, ib, size, mode)
683 int *adbc, *aibc;
684 char *db;
685 daddr_t *ib;
686 int size;
687 int mode;
d746d022
KM
688{
689 int i;
690 daddr_t bno;
691
07670f7d 692 bno = alloc(size, mode);
d746d022
KM
693 wtfs(bno, size, db);
694 for(i=0; i<size; i++)
695 db[i] = 0;
696 *adbc = 0;
697 ib[*aibc] = bno;
698 (*aibc)++;
699 if(*aibc >= NINDIR) {
700 printf("indirect block full\n");
701 error = 1;
702 *aibc = 0;
703 }
704}
705
706getch()
707{
708
709#ifndef STANDALONE
710 if(charp)
711#endif
712 return(*charp++);
713#ifndef STANDALONE
714 return(getc(fin));
715#endif
716}
717
718iput(ip, aibc, ib)
719struct inode *ip;
720int *aibc;
721daddr_t *ib;
722{
723 struct dinode *dp;
724 daddr_t d;
725 int i, c = ip->i_number / sblock.fs_ipg;
726
727 rdfs(cgtod(c,&sblock), sblock.fs_cgsize, (char *)&acg);
0947395d 728 acg.cg_cs.cs_nifree--;
d746d022
KM
729 setbit(acg.cg_iused, ip->i_number);
730 wtfs(cgtod(c,&sblock), sblock.fs_cgsize, (char *)&acg);
0947395d 731 sblock.fs_cstotal.cs_nifree--;
d746d022
KM
732 fscs[0].cs_nifree--;
733 if(ip->i_number >= sblock.fs_ipg) {
734 printf("mkfs: cant handle more than one cg of inodes (yet)\n");
735 exit(1);
736 }
737 if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) {
738 if(error == 0)
739 printf("ilist too small\n");
740 error = 1;
741 return;
742 }
743 d = itod(ip->i_number,&sblock);
744 rdfs(d, BSIZE, buf);
56d45dcd
KM
745 for(i=0; i<*aibc; i++) {
746 if(i >= NDADDR)
747 break;
748 ip->i_db[i] = ib[i];
749 }
750 if(*aibc >= NDADDR) {
07670f7d 751 ip->i_ib[0] = alloc(BSIZE, 0);
56d45dcd
KM
752 for(i=0; i<NINDIR-NDADDR; i++) {
753 ib[i] = ib[i+NDADDR];
754 ib[i+NDADDR] = (daddr_t)0;
d746d022 755 }
56d45dcd 756 wtfs(ip->i_ib[0], (char *)ib);
d746d022 757 }
56d45dcd 758 ((struct dinode *)buf+itoo(ip->i_number))->di_ic = ip->i_ic;
d746d022
KM
759 wtfs(d, BSIZE, buf);
760}