OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.24/] [disk/] [tools/] [fs-EOS32/] [mkfs/] [mkfs.c] - Blame information for rev 276

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 hellwig
/*
2
 * mkfs.c -- make an EOS32 file system
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <stdarg.h>
10
#include <time.h>
11
 
12
 
13
/**************************************************************/
14
 
15
 
16
#define SSIZE           512     /* disk sector size in bytes */
17
#define BSIZE           4096    /* disk block size in bytes */
18
#define SPB             (BSIZE / SSIZE) /* sectors per block */
19
#define AFS             (3 * BSIZE / 2) /* average file size */
20
 
21
#define NICINOD         500     /* number of inodes in superblock */
22
#define NICFREE         500     /* number of free blocks in superblock */
23
#define NADDR           8       /* number of block addresses in inode */
24
#define NDADDR          6       /* number of direct block addresses */
25
#define SINGLE_INDIR    (NDADDR + 0)    /* index of single indirect block */
26
#define DOUBLE_INDIR    (NDADDR + 1)    /* index of double indirect block */
27
#define DIRSIZ          60      /* max length of a path name component */
28
 
29
#define NIPB            (BSIZE / sizeof(Dinode))
30
#define NDIRENT         (BSIZE / sizeof(Dirent))
31
#define NINDIR          (BSIZE / sizeof(EOS32_daddr_t))
32
 
33
#define SUPER_MAGIC     0x44FCB67D
34
 
35
#define IFMT            070000  /* type of file */
36
#define   IFREG         040000  /* regular file */
37
#define   IFDIR         030000  /* directory */
38
#define   IFCHR         020000  /* character special */
39
#define   IFBLK         010000  /* block special */
40
#define   IFFREE        000000  /* reserved (indicates free inode) */
41
#define ISUID           004000  /* set user id on execution */
42
#define ISGID           002000  /* set group id on execution */
43
#define ISVTX           001000  /* save swapped text even after use */
44
#define IUREAD          000400  /* user's read permission */
45
#define IUWRITE         000200  /* user's write permission */
46
#define IUEXEC          000100  /* user's execute permission */
47
#define IGREAD          000040  /* group's read permission */
48
#define IGWRITE         000020  /* group's write permission */
49
#define IGEXEC          000010  /* group's execute permission */
50
#define IOREAD          000004  /* other's read permission */
51
#define IOWRITE         000002  /* other's write permission */
52
#define IOEXEC          000001  /* other's execute permission */
53
 
54
/*
55
 * The following two macros convert an inode number to the disk
56
 * block containing the inode and an inode number within the block.
57
 */
58
#define itod(i)         (2 + (i) / NIPB)
59
#define itoo(i)         ((i) % NIPB)
60
 
61
#define TYPE_COPY       0
62
#define TYPE_INODE      1
63
#define TYPE_FREE       2
64
#define TYPE_SUPER      3
65
#define TYPE_INDIRECT   4
66
#define TYPE_DIRECTORY  5
67
 
68
 
69
/**************************************************************/
70
 
71
 
72
/* EOS32 types */
73
 
74
typedef unsigned long EOS32_ino_t;
75
typedef unsigned long EOS32_daddr_t;
76
typedef unsigned long EOS32_off_t;
77
typedef long EOS32_time_t;
78
 
79
 
80
/* super block */
81
 
82
typedef struct {
83
  unsigned int s_magic;                 /* must be SUPER_MAGIC */
84
  EOS32_daddr_t s_fsize;                /* size of file system in blocks */
85
  EOS32_daddr_t s_isize;                /* size of inode list in blocks */
86
  EOS32_daddr_t s_freeblks;             /* number of free blocks */
87
  EOS32_ino_t s_freeinos;               /* number of free inodes */
88
  unsigned int s_ninode;                /* number of inodes in s_inode */
89
  EOS32_ino_t s_inode[NICINOD];         /* free inode list */
90
  unsigned int s_nfree;                 /* number of addresses in s_free */
91
  EOS32_daddr_t s_free[NICFREE];        /* free block list */
92
  EOS32_time_t s_time;                  /* last super block update */
93
  char s_flock;                         /* lock for free list manipulation */
94
  char s_ilock;                         /* lock for i-list manipulation */
95
  char s_fmod;                          /* super block modified flag */
96
  char s_ronly;                         /* mounted read-only flag */
97
  char s_pad[BSIZE - 4036];             /* pad to block size */
98
} Filsys;
99
 
100
 
101
/* inode on disk */
102
 
103
typedef struct {
104
  unsigned int di_mode;                 /* type and mode of file */
105
  unsigned int di_nlink;                /* number of links to file */
106
  unsigned int di_uid;                  /* owner's user id */
107
  unsigned int di_gid;                  /* owner's group id */
108
  EOS32_time_t di_ctime;                /* time created */
109
  EOS32_time_t di_mtime;                /* time last modified */
110
  EOS32_time_t di_atime;                /* time last accessed */
111
  EOS32_off_t di_size;                  /* number of bytes in file */
112
  EOS32_daddr_t di_addr[NADDR];         /* block addresses */
113
} Dinode;
114
 
115
 
116
/* inode in memory */
117
 
118
typedef struct {
119
  EOS32_ino_t i_number;                 /* inode number */
120
  unsigned int i_mode;                  /* type and mode of file */
121
  unsigned int i_nlink;                 /* number of links to file */
122
  unsigned int i_uid;                   /* owner's user id */
123
  unsigned int i_gid;                   /* owner's group id */
124
  EOS32_off_t i_size;                   /* number of bytes in file */
125
  EOS32_daddr_t i_addr[NADDR];          /* block addresses */
126
} Inode;
127
 
128
 
129
/* directory entry */
130
 
131
typedef struct {
132
  EOS32_ino_t d_ino;                    /* directory inode */
133
  char d_name[DIRSIZ];                  /* directory name */
134
} Dirent;
135
 
136
 
137
/* free block */
138
 
139
typedef struct {
140
  unsigned int df_nfree;                /* number of valid block addresses */
141
  EOS32_daddr_t df_free[NICFREE];       /* addresses of free blocks */
142
  char df_pad[BSIZE - 2004];            /* pad to block size */
143
} Fblk;
144
 
145
 
146
/**************************************************************/
147
 
148
 
149
time_t now;             /* timestamp used throughout the file system */
150
FILE *fs;               /* the file which holds the disk image */
151
Filsys filsys;          /* the file system's super block */
152
EOS32_ino_t lastIno;    /* last inode allocated */
153
 
154
 
155
/**************************************************************/
156
 
157
 
158
void error(char *fmt, ...) {
159
  va_list ap;
160
 
161
  va_start(ap, fmt);
162
  printf("Error: ");
163
  vprintf(fmt, ap);
164
  printf("\n");
165
  va_end(ap);
166
  exit(1);
167
}
168
 
169
 
170
/**************************************************************/
171
 
172
 
173
unsigned int read4FromEco(unsigned char *p) {
174
  return (unsigned int) p[0] << 24 |
175
         (unsigned int) p[1] << 16 |
176
         (unsigned int) p[2] <<  8 |
177
         (unsigned int) p[3] <<  0;
178
}
179
 
180
 
181
void write4ToEco(unsigned char *p, unsigned int data) {
182
  p[0] = data >> 24;
183
  p[1] = data >> 16;
184
  p[2] = data >>  8;
185
  p[3] = data >>  0;
186
}
187
 
188
 
189
void conv4FromEcoToX86(unsigned char *p) {
190
  unsigned int data;
191
 
192
  data = read4FromEco(p);
193
  * (unsigned int *) p = data;
194
}
195
 
196
 
197
void conv4FromX86ToEco(unsigned char *p) {
198
  unsigned int data;
199
 
200
  data = * (unsigned int *) p;
201
  write4ToEco(p, data);
202
}
203
 
204
 
205
/**************************************************************/
206
 
207
 
208
void superFromEcoToX86(unsigned char *p) {
209
  int i;
210
 
211
  /* magic */
212
  conv4FromEcoToX86(p);
213
  p += 4;
214
  /* fsize */
215
  conv4FromEcoToX86(p);
216
  p += 4;
217
  /* isize */
218
  conv4FromEcoToX86(p);
219
  p += 4;
220
  /* freeblks */
221
  conv4FromEcoToX86(p);
222
  p += 4;
223
  /* freeinos */
224
  conv4FromEcoToX86(p);
225
  p += 4;
226
  /* ninode */
227
  conv4FromEcoToX86(p);
228
  p += 4;
229
  /* inode */
230
  for (i = 0; i < NICINOD; i++) {
231
    conv4FromEcoToX86(p);
232
    p += 4;
233
  }
234
  /* nfree */
235
  conv4FromEcoToX86(p);
236
  p += 4;
237
  /* free */
238
  for (i = 0; i < NICFREE; i++) {
239
    conv4FromEcoToX86(p);
240
    p += 4;
241
  }
242
  /* time */
243
  conv4FromEcoToX86(p);
244
  p += 4;
245
  /* flock */
246
  p += 1;
247
  /* ilock */
248
  p += 1;
249
  /* fmod */
250
  p += 1;
251
  /* ronly */
252
  p += 1;
253
}
254
 
255
 
256
void superFromX86ToEco(unsigned char *p) {
257
  int i;
258
 
259
  /* magic */
260
  conv4FromX86ToEco(p);
261
  p += 4;
262
  /* fsize */
263
  conv4FromX86ToEco(p);
264
  p += 4;
265
  /* isize */
266
  conv4FromX86ToEco(p);
267
  p += 4;
268
  /* freeblks */
269
  conv4FromX86ToEco(p);
270
  p += 4;
271
  /* freeinos */
272
  conv4FromX86ToEco(p);
273
  p += 4;
274
  /* ninode */
275
  conv4FromX86ToEco(p);
276
  p += 4;
277
  /* inode */
278
  for (i = 0; i < NICINOD; i++) {
279
    conv4FromX86ToEco(p);
280
    p += 4;
281
  }
282
  /* nfree */
283
  conv4FromX86ToEco(p);
284
  p += 4;
285
  /* free */
286
  for (i = 0; i < NICFREE; i++) {
287
    conv4FromX86ToEco(p);
288
    p += 4;
289
  }
290
  /* time */
291
  conv4FromX86ToEco(p);
292
  p += 4;
293
  /* flock */
294
  p += 1;
295
  /* ilock */
296
  p += 1;
297
  /* fmod */
298
  p += 1;
299
  /* ronly */
300
  p += 1;
301
}
302
 
303
 
304
void inodeFromEcoToX86(unsigned char *p) {
305
  int i, j;
306
 
307
  for (i = 0; i < NIPB; i++) {
308
    /* mode */
309
    conv4FromEcoToX86(p);
310
    p += 4;
311
    /* nlink */
312
    conv4FromEcoToX86(p);
313
    p += 4;
314
    /* uid */
315
    conv4FromEcoToX86(p);
316
    p += 4;
317
    /* gid */
318
    conv4FromEcoToX86(p);
319
    p += 4;
320
    /* ctime */
321
    conv4FromEcoToX86(p);
322
    p += 4;
323
    /* mtime */
324
    conv4FromEcoToX86(p);
325
    p += 4;
326
    /* atime */
327
    conv4FromEcoToX86(p);
328
    p += 4;
329
    /* size */
330
    conv4FromEcoToX86(p);
331
    p += 4;
332
    /* addr */
333
    for (j = 0; j < NADDR; j++) {
334
      conv4FromEcoToX86(p);
335
      p += 4;
336
    }
337
  }
338
}
339
 
340
 
341
void inodeFromX86ToEco(unsigned char *p) {
342
  int i, j;
343
 
344
  for (i = 0; i < NIPB; i++) {
345
    /* mode */
346
    conv4FromX86ToEco(p);
347
    p += 4;
348
    /* nlink */
349
    conv4FromX86ToEco(p);
350
    p += 4;
351
    /* uid */
352
    conv4FromX86ToEco(p);
353
    p += 4;
354
    /* gid */
355
    conv4FromX86ToEco(p);
356
    p += 4;
357
    /* ctime */
358
    conv4FromX86ToEco(p);
359
    p += 4;
360
    /* mtime */
361
    conv4FromX86ToEco(p);
362
    p += 4;
363
    /* atime */
364
    conv4FromX86ToEco(p);
365
    p += 4;
366
    /* size */
367
    conv4FromX86ToEco(p);
368
    p += 4;
369
    /* addr */
370
    for (j = 0; j < NADDR; j++) {
371
      conv4FromX86ToEco(p);
372
      p += 4;
373
    }
374
  }
375
}
376
 
377
 
378
void freeFromEcoToX86(unsigned char *p) {
379
  int i;
380
 
381
  /* nfree */
382
  conv4FromEcoToX86(p);
383
  p += 4;
384
  /* free */
385
  for (i = 0; i < NICFREE; i++) {
386
    conv4FromEcoToX86(p);
387
    p += 4;
388
  }
389
}
390
 
391
 
392
void freeFromX86ToEco(unsigned char *p) {
393
  int i;
394
 
395
  /* nfree */
396
  conv4FromX86ToEco(p);
397
  p += 4;
398
  /* free */
399
  for (i = 0; i < NICFREE; i++) {
400
    conv4FromX86ToEco(p);
401
    p += 4;
402
  }
403
}
404
 
405
 
406
void indirectFromEcoToX86(unsigned char *p) {
407
  int i;
408
 
409
  for (i = 0; i < NINDIR; i++) {
410
    conv4FromEcoToX86(p);
411
    p += 4;
412
  }
413
}
414
 
415
 
416
void indirectFromX86ToEco(unsigned char *p) {
417
  int i;
418
 
419
  for (i = 0; i < NINDIR; i++) {
420
    conv4FromX86ToEco(p);
421
    p += 4;
422
  }
423
}
424
 
425
 
426
void directoryFromEcoToX86(unsigned char *p) {
427
  int i;
428
 
429
  for (i = 0; i < NDIRENT; i++) {
430
    conv4FromEcoToX86(p);
431
    p += 4;
432
    p += DIRSIZ;
433
  }
434
}
435
 
436
 
437
void directoryFromX86ToEco(unsigned char *p) {
438
  int i;
439
 
440
  for (i = 0; i < NDIRENT; i++) {
441
    conv4FromX86ToEco(p);
442
    p += 4;
443
    p += DIRSIZ;
444
  }
445
}
446
 
447
 
448
/**************************************************************/
449
 
450
 
451
unsigned long fsStart;          /* file system start sector */
452
 
453
 
454
void rdfs(EOS32_daddr_t bno, unsigned char *bf, int blkType) {
455
  int n;
456
 
457
  fseek(fs, fsStart * SSIZE + bno * BSIZE, SEEK_SET);
458
  n = fread(bf, 1, BSIZE, fs);
459
  if (n != BSIZE) {
460
    printf("read error: %ld\n", bno);
461
    exit(1);
462
  }
463
  switch (blkType) {
464
    case TYPE_COPY:
465
      /* nothing to do here */
466
      break;
467
    case TYPE_INODE:
468
      inodeFromEcoToX86(bf);
469
      break;
470
    case TYPE_FREE:
471
      freeFromEcoToX86(bf);
472
      break;
473
    case TYPE_SUPER:
474
      superFromEcoToX86(bf);
475
      break;
476
    case TYPE_INDIRECT:
477
      indirectFromEcoToX86(bf);
478
      break;
479
    case TYPE_DIRECTORY:
480
      directoryFromEcoToX86(bf);
481
      break;
482
    default:
483
      error("illegal block type %d in rdfs()", blkType);
484
      break;
485
  }
486
}
487
 
488
 
489
void wtfs(EOS32_daddr_t bno, unsigned char *bf, int blkType) {
490
  int n;
491
 
492
  switch (blkType) {
493
    case TYPE_COPY:
494
      /* nothing to do here */
495
      break;
496
    case TYPE_INODE:
497
      inodeFromX86ToEco(bf);
498
      break;
499
    case TYPE_FREE:
500
      freeFromX86ToEco(bf);
501
      break;
502
    case TYPE_SUPER:
503
      superFromX86ToEco(bf);
504
      break;
505
    case TYPE_INDIRECT:
506
      indirectFromX86ToEco(bf);
507
      break;
508
    case TYPE_DIRECTORY:
509
      directoryFromX86ToEco(bf);
510
      break;
511
    default:
512
      error("illegal block type %d in wtfs()", blkType);
513
      break;
514
  }
515
  fseek(fs, fsStart * SSIZE + bno * BSIZE, SEEK_SET);
516
  n = fwrite(bf, 1, BSIZE, fs);
517
  if(n != BSIZE) {
518
    printf("write error: %ld\n", bno);
519
    exit(1);
520
  }
521
  switch (blkType) {
522
    case TYPE_COPY:
523
      /* nothing to do here */
524
      break;
525
    case TYPE_INODE:
526
      inodeFromEcoToX86(bf);
527
      break;
528
    case TYPE_FREE:
529
      freeFromEcoToX86(bf);
530
      break;
531
    case TYPE_SUPER:
532
      superFromEcoToX86(bf);
533
      break;
534
    case TYPE_INDIRECT:
535
      indirectFromEcoToX86(bf);
536
      break;
537
    case TYPE_DIRECTORY:
538
      directoryFromEcoToX86(bf);
539
      break;
540
    default:
541
      error("illegal block type %d in wtfs()", blkType);
542
      break;
543
  }
544
}
545
 
546
 
547
/**************************************************************/
548
 
549
 
550
char *charp;
551
FILE *fin;
552
char string[100];
553
 
554
 
555
char getChar(void) {
556
  int c;
557
 
558
  if (charp != NULL) {
559
    /* take character from string */
560
    c = *charp;
561
    if (c != 0) {
562
      charp++;
563
    }
564
  } else {
565
    /* take character from prototype file */
566
    c = getc(fin);
567
    if (c == EOF) {
568
      c = 0;
569
    }
570
  }
571
  return c;
572
}
573
 
574
 
575
void getStr(void) {
576
  char c;
577
  int i;
578
 
579
  while (1) {
580
    c = getChar();
581
    if (c == ' ' || c == '\t' || c == '\n') {
582
      continue;
583
    }
584
    if (c == '\0') {
585
      error("unexpected EOF in prototype file");
586
    }
587
    if (c == '#') {
588
      do {
589
        c = getChar();
590
        if (c == '\0') {
591
          error("unexpected EOF in prototype file");
592
        }
593
      } while (c != '\n');
594
      continue;
595
    }
596
    break;
597
  }
598
  i = 0;
599
  do {
600
    string[i++] = c;
601
    c = getChar();
602
  } while (c != ' ' &&
603
           c != '\t' &&
604
           c != '\n' &&
605
           c != '\0');
606
  string[i] = '\0';
607
}
608
 
609
 
610
void badMode(char c) {
611
  error("%c/%s: bad mode", c, string);
612
}
613
 
614
 
615
int getMode(char c, char *s, int m0, int m1, int m2, int m3) {
616
  if (s[0] == 0) badMode(c);
617
  if (c == s[0]) return m0;
618
  if (s[1] == 0) badMode(c);
619
  if (c == s[1]) return m1;
620
  if (s[2] == 0) badMode(c);
621
  if (c == s[2]) return m2;
622
  if (s[3] == 0) badMode(c);
623
  if (c == s[3]) return m3;
624
  badMode(c);
625
  /* never reached */
626
  return 0;
627
}
628
 
629
 
630
long getNum(void) {
631
  int i, c;
632
  long n;
633
 
634
  getStr();
635
  n = 0;
636
  i = 0;
637
  for (i = 0; (c = string[i]) != '\0'; i++) {
638
    if (c < '0' || c > '9') {
639
      error("%s: bad number", string);
640
    }
641
    n = n * 10 + (c - '0');
642
  }
643
  return n;
644
}
645
 
646
 
647
/**************************************************************/
648
 
649
/* data block handling */
650
 
651
 
652
EOS32_daddr_t allocBlock(void) {
653
  EOS32_daddr_t bno;
654
  Fblk fbuf;
655
  int i;
656
 
657
  if (filsys.s_nfree <= 0) {
658
    error("this should never happen (filsys.s_nfree <= 0)");
659
  }
660
  bno = filsys.s_free[--filsys.s_nfree];
661
  if (bno == 0) {
662
    error("out of free disk blocks");
663
  }
664
  if (filsys.s_nfree == 0) {
665
    rdfs(bno, (unsigned char *) &fbuf, TYPE_FREE);
666
    filsys.s_nfree = fbuf.df_nfree;
667
    for (i = 0; i < NICFREE; i++) {
668
      filsys.s_free[i] = fbuf.df_free[i];
669
    }
670
  }
671
  filsys.s_freeblks--;
672
  return bno;
673
}
674
 
675
 
676
void freeBlock(EOS32_daddr_t bno) {
677
  Fblk fbuf;
678
  int i;
679
 
680
  if (filsys.s_nfree > NICFREE) {
681
    error("this should never happen (filsys.s_nfree > NICFREE)");
682
  }
683
  if (filsys.s_nfree == NICFREE) {
684
    memset(&fbuf, 0, sizeof(Fblk));
685
    fbuf.df_nfree = NICFREE;
686
    for (i = 0; i < NICFREE; i++) {
687
      fbuf.df_free[i] = filsys.s_free[i];
688
    }
689
    wtfs(bno, (unsigned char *) &fbuf, TYPE_FREE);
690
    filsys.s_nfree = 0;
691
  }
692
  filsys.s_free[filsys.s_nfree++] = bno;
693
  if (bno != 0) {
694
    /* note: block number 0 does not count as free block */
695
    filsys.s_freeblks++;
696
  }
697
}
698
 
699
 
700
void initFreeList(void) {
701
  EOS32_daddr_t bno;
702
 
703
  freeBlock(0);
704
  for (bno = filsys.s_fsize - 1; bno >= 2 + filsys.s_isize; bno--) {
705
    freeBlock(bno);
706
  }
707
}
708
 
709
 
710
/**************************************************************/
711
 
712
/* inode handling */
713
 
714
 
715
void iput(Inode *ip) {
716
  EOS32_daddr_t inodeBlock;
717
  Dinode *dp;
718
  unsigned char buf[BSIZE];
719
  int i;
720
 
721
  inodeBlock = itod(ip->i_number);
722
  if (inodeBlock >= 2 + filsys.s_isize) {
723
    error("too few inodes");
724
  }
725
  rdfs(inodeBlock, buf, TYPE_INODE);
726
  dp = (Dinode *) buf;
727
  dp += itoo(ip->i_number);
728
  dp->di_mode = ip->i_mode;
729
  dp->di_nlink = ip->i_nlink;
730
  dp->di_uid = ip->i_uid;
731
  dp->di_gid = ip->i_gid;
732
  dp->di_ctime = now;
733
  dp->di_mtime = now;
734
  dp->di_atime = now;
735
  dp->di_size = ip->i_size;
736
  for (i = 0; i < NADDR; i++) {
737
    dp->di_addr[i] = ip->i_addr[i];
738
  }
739
  wtfs(inodeBlock, buf, TYPE_INODE);
740
  filsys.s_freeinos--;
741
}
742
 
743
 
744
void initInodes(void) {
745
  int i;
746
  EOS32_daddr_t n;
747
  unsigned char buf[BSIZE];
748
  Inode in;
749
 
750
  /* init all inodes to free */
751
  for (i = 0; i < BSIZE; i++) {
752
    buf[i] = '\0';
753
  }
754
  for (n = 0; n < filsys.s_isize; n++) {
755
    wtfs(2 + n, buf, TYPE_INODE);
756
    filsys.s_freeinos += NIPB;
757
  }
758
  /* init inode 0 */
759
  lastIno = 0;
760
  in.i_number = lastIno;
761
  in.i_mode = IFREG;
762
  in.i_nlink = 0;
763
  in.i_uid = 0;
764
  in.i_gid = 0;
765
  in.i_size = 0;
766
  for (i = 0; i < NADDR; i++) {
767
    in.i_addr[i] = 0;
768
  }
769
  iput(&in);
770
}
771
 
772
 
773
void fillFreeInodeList(EOS32_ino_t numInodes) {
774
  int index;
775
  EOS32_ino_t ino;
776
  int i;
777
 
778
  /* fill the free inode list starting at the upper end */
779
  index = NICINOD;
780
  for (ino = lastIno + 1; ino < numInodes && index > 0; ino++) {
781
    filsys.s_inode[--index] = ino;
782
  }
783
  filsys.s_ninode = NICINOD - index;
784
  /* if the list is not completely filled, shift entries down */
785
  if (index > 0) {
786
    for (i = 0; i < filsys.s_ninode; i++) {
787
      filsys.s_inode[i] = filsys.s_inode[index++];
788
    }
789
  }
790
}
791
 
792
 
793
/**************************************************************/
794
 
795
 
796
void appendData(Inode *ip, int blkType, unsigned char *src, int size) {
797
  EOS32_off_t offset;
798
  int index1, index2;
799
  EOS32_daddr_t bno;
800
  unsigned char buf[BSIZE];
801
  EOS32_daddr_t ibno;
802
  EOS32_daddr_t iblk[NINDIR];
803
  EOS32_daddr_t dibno;
804
  EOS32_daddr_t diblk[NINDIR];
805
 
806
  offset = ip->i_size;
807
  if (offset < NDADDR * BSIZE) {
808
    /* direct block */
809
    index1 = offset / BSIZE;
810
    offset %= BSIZE;
811
    if (ip->i_addr[index1] == 0) {
812
      bno = allocBlock();
813
      ip->i_addr[index1] = bno;
814
      memset(buf, 0, BSIZE);
815
    } else {
816
      bno = ip->i_addr[index1];
817
      rdfs(bno, buf, blkType);
818
    }
819
  } else
820
  if (offset < (NINDIR + NDADDR) * BSIZE) {
821
    /* single indirect block */
822
    offset -= NDADDR * BSIZE;
823
    index1 = offset / BSIZE;
824
    offset %= BSIZE;
825
    if (ip->i_addr[SINGLE_INDIR] == 0) {
826
      ibno = allocBlock();
827
      ip->i_addr[SINGLE_INDIR] = ibno;
828
      memset(iblk, 0, BSIZE);
829
    } else {
830
      ibno = ip->i_addr[SINGLE_INDIR];
831
      rdfs(ibno, (unsigned char *) iblk, TYPE_INDIRECT);
832
    }
833
    if (iblk[index1] == 0) {
834
      bno = allocBlock();
835
      iblk[index1] = bno;
836
      wtfs(ibno, (unsigned char *) iblk, TYPE_INDIRECT);
837
      memset(buf, 0, BSIZE);
838
    } else {
839
      bno = iblk[index1];
840
      rdfs(bno, buf, blkType);
841
    }
842
  } else {
843
    /* double indirect block */
844
    offset -= (NINDIR + NDADDR) * BSIZE;
845
    index1 = offset / BSIZE;
846
    offset %= BSIZE;
847
    index2 = index1 / NINDIR;
848
    index1 %= NINDIR;
849
    if (ip->i_addr[DOUBLE_INDIR] == 0) {
850
      dibno = allocBlock();
851
      ip->i_addr[DOUBLE_INDIR] = dibno;
852
      memset(diblk, 0, BSIZE);
853
    } else {
854
      dibno = ip->i_addr[DOUBLE_INDIR];
855
      rdfs(dibno, (unsigned char *) diblk, TYPE_INDIRECT);
856
    }
857
    if (diblk[index2] == 0) {
858
      ibno = allocBlock();
859
      diblk[index2] = ibno;
860
      wtfs(dibno, (unsigned char *) diblk, TYPE_INDIRECT);
861
      memset(iblk, 0, BSIZE);
862
    } else {
863
      ibno = diblk[index2];
864
      rdfs(ibno, (unsigned char *) iblk, TYPE_INDIRECT);
865
    }
866
    if (iblk[index1] == 0) {
867
      bno = allocBlock();
868
      iblk[index1] = bno;
869
      wtfs(ibno, (unsigned char *) iblk, TYPE_INDIRECT);
870
      memset(buf, 0, BSIZE);
871
    } else {
872
      bno = iblk[index1];
873
      rdfs(bno, buf, blkType);
874
    }
875
  }
876
  memcpy(buf + offset, src, size);
877
  wtfs(bno, buf, blkType);
878
  ip->i_size += size;
879
}
880
 
881
 
882
void makeDirEntry(Inode *dir, EOS32_ino_t ino, char *name) {
883
  Dirent entry;
884
 
885
  memset(&entry, 0, sizeof(Dirent));
886
  entry.d_ino = ino;
887
  strcpy(entry.d_name, name);
888
  appendData(dir, TYPE_DIRECTORY, (unsigned char *) &entry, sizeof(Dirent));
889
}
890
 
891
 
892
void createFile(Inode *parent) {
893
  Inode in;
894
  int i;
895
  char c;
896
  FILE *f;
897
  unsigned char buf[BSIZE];
898
 
899
  /* get mode, uid and gid */
900
  getStr();
901
  in.i_mode = getMode(string[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
902
  in.i_mode |= getMode(string[1], "-u", 0, ISUID, 0, 0);
903
  in.i_mode |= getMode(string[2], "-g", 0, ISGID, 0, 0);
904
  for (i = 3; i < 6; i++) {
905
    c = string[i];
906
    if (c < '0' || c > '7') {
907
      error("%c/%s: bad octal mode digit", c, string);
908
    }
909
    in.i_mode |= (c - '0') << (15 - 3 * i);
910
  }
911
  in.i_uid = getNum();
912
  in.i_gid = getNum();
913
  /* general initialization prior to switching on format */
914
  lastIno++;
915
  in.i_number = lastIno;
916
  in.i_nlink = 1;
917
  in.i_size = 0;
918
  for (i = 0; i < NADDR; i++) {
919
    in.i_addr[i] = 0;
920
  }
921
  if (parent == NULL) {
922
    parent = &in;
923
    in.i_nlink--;
924
  }
925
  /* now switch on format */
926
  switch (in.i_mode & IFMT) {
927
    case IFREG:
928
      /* regular file:
929
         contents is a file name */
930
      getStr();
931
      f = fopen(string, "rb");
932
      if (f == NULL) {
933
        error("%s: cannot open", string);
934
      }
935
      while ((i = fread(buf, 1, BSIZE, f)) > 0) {
936
        appendData(&in, TYPE_COPY, buf, i);
937
      }
938
      fclose(f);
939
      break;
940
    case IFBLK:
941
    case IFCHR:
942
      /* special file:
943
         contents is major/minor device */
944
      in.i_addr[0] = (getNum() & 0xFFFF) << 16;
945
      in.i_addr[0] |= (getNum() & 0xFFFF);
946
      break;
947
    case IFDIR:
948
      /* directory:
949
         put in extra links, call recursively until name is "$" */
950
      parent->i_nlink++;
951
      in.i_nlink++;
952
      makeDirEntry(&in, in.i_number, ".");
953
      makeDirEntry(&in, parent->i_number, "..");
954
      while (1) {
955
        getStr();
956
        if (string[0] == '$' && string[1] == '\0') {
957
          break;
958
        }
959
        makeDirEntry(&in, lastIno + 1, string);
960
        createFile(&in);
961
      }
962
      break;
963
    default:
964
      error("bad format/mode %o\n", in.i_mode);
965
      break;
966
  }
967
  /* finally write the inode */
968
  iput(&in);
969
}
970
 
971
 
972
/**************************************************************/
973
 
974
 
975
void showSizes(void) {
976
  printf("BSIZE   = %d\n", BSIZE);
977
  printf("NICINOD = %d\n", NICINOD);
978
  printf("NICFREE = %d\n", NICFREE);
979
  printf("NADDR   = %d\n", NADDR);
980
  printf("NDADDR  = %d\n", NDADDR);
981
  printf("DIRSIZ  = %d\n", DIRSIZ);
982
  printf("NIPB    = %d\n", NIPB);
983
  printf("NDIRENT = %d\n", NDIRENT);
984
  printf("NINDIR  = %d\n", NINDIR);
985
  printf("sizeof(Filsys) = %d\n", sizeof(Filsys));
986
  printf("sizeof(Dinode) = %d\n", sizeof(Dinode));
987
  printf("sizeof(Dirent) = %d\n", sizeof(Dirent));
988
  printf("sizeof(Fblk)   = %d\n", sizeof(Fblk));
989
}
990
 
991
 
992
int main(int argc, char *argv[]) {
993
  char *fsnam;
994
  char *proto;
995
  char protoBuf[20];
996
  unsigned long fsSize;
997
  int part;
998
  char *endptr;
999
  unsigned char partTable[SSIZE];
1000
  unsigned char *ptptr;
1001
  unsigned long partType;
1002
  EOS32_daddr_t maxBlocks;
1003
  EOS32_daddr_t numBlocks;
1004
  EOS32_ino_t numInodes;
1005
  int i;
1006
  char c;
1007
  FILE *bootblk;
1008
  long bootblkSize;
1009
  unsigned char buf[BSIZE];
1010
 
1011
  if (argc == 2 && strcmp(argv[1], "--sizes") == 0) {
1012
    showSizes();
1013
    exit(0);
1014
  }
1015
  if (argc != 3 && argc != 4) {
1016
    printf("Usage: %s <disk> <partition or '*'> [<prototype or size>]\n",
1017
           argv[0]);
1018
    printf("   or: %s --sizes\n", argv[0]);
1019
    exit(1);
1020
  }
1021
  time(&now);
1022
  fsnam = argv[1];
1023
  fs = fopen(fsnam, "r+b");
1024
  if (fs == NULL) {
1025
    error("cannot open disk image '%s'", fsnam);
1026
  }
1027
  if (strcmp(argv[2], "*") == 0) {
1028
    /* whole disk contains one single file system */
1029
    fsStart = 0;
1030
    fseek(fs, 0, SEEK_END);
1031
    fsSize = ftell(fs) / SSIZE;
1032
  } else {
1033
    /* argv[2] is partition number of file system */
1034
    part = strtoul(argv[2], &endptr, 10);
1035
    if (*endptr != '\0' || part < 0 || part > 15) {
1036
      error("illegal partition number '%s'", argv[2]);
1037
    }
1038
    fseek(fs, 1 * SSIZE, SEEK_SET);
1039
    if (fread(partTable, 1, SSIZE, fs) != SSIZE) {
1040
      error("cannot read partition table of disk '%s'", fsnam);
1041
    }
1042
    ptptr = partTable + part * 32;
1043
    partType = read4FromEco(ptptr + 0);
1044
    if ((partType & 0x7FFFFFFF) != 0x00000058) {
1045
      error("partition %d of disk '%s' does not contain an EOS32 file system",
1046
            part, fsnam);
1047
    }
1048
    fsStart = read4FromEco(ptptr + 4);
1049
    fsSize = read4FromEco(ptptr + 8);
1050
  }
1051
  printf("File system space is %lu (0x%lX) sectors of %d bytes each.\n",
1052
         fsSize, fsSize, SSIZE);
1053
  if (fsSize % SPB != 0) {
1054
    printf("File system space is not a multiple of block size.\n");
1055
  }
1056
  maxBlocks = fsSize / SPB;
1057
  printf("This equals %lu (0x%lX) blocks of %d bytes each.\n",
1058
         maxBlocks, maxBlocks, BSIZE);
1059
  if (argc == 4) {
1060
    proto = argv[3];
1061
  } else {
1062
    proto = protoBuf;
1063
    sprintf(protoBuf, "%lu", maxBlocks);
1064
  }
1065
  /* initialize super block and possibly write boot block */
1066
  filsys.s_magic = SUPER_MAGIC;
1067
  fin = fopen(proto, "rt");
1068
  if (fin == NULL) {
1069
    /* cannot open prototype file, perhaps size was specified */
1070
    charp = "d--777 0 0 $ ";
1071
    numBlocks = 0;
1072
    for (i = 0; (c = proto[i]) != '\0'; i++) {
1073
      if (c < '0' || c > '9') {
1074
        /* neither valid prototype file nor valid size */
1075
        error("cannot open prototype '%s'", proto);
1076
      }
1077
      numBlocks = numBlocks * 10 + (c - '0');
1078
    }
1079
    numInodes = (numBlocks * BSIZE) / AFS;
1080
  } else {
1081
    /* prototype file opened */
1082
    charp = NULL;
1083
    getStr();
1084
    if (strcmp(string, "-noboot-") == 0) {
1085
      /* boot block not wanted */
1086
    } else {
1087
      /* string holds the name of the boot block file */
1088
      bootblk = fopen(string, "rb");
1089
      if (bootblk == NULL) {
1090
        error("cannot open boot block file '%s'", string);
1091
      }
1092
      fseek(bootblk, 0, SEEK_END);
1093
      bootblkSize = ftell(bootblk);
1094
      fseek(bootblk, 0, SEEK_SET);
1095
      if (bootblkSize > BSIZE) {
1096
        error("boot block file '%s' is bigger than a block", string);
1097
      }
1098
      for (i = 0; i < BSIZE; i++) {
1099
        buf[i] = '\0';
1100
      }
1101
      if (fread(buf, 1, bootblkSize, bootblk) != bootblkSize) {
1102
        error("cannot read boot block file '%s'", string);
1103
      }
1104
      wtfs(0, buf, TYPE_COPY);
1105
      fclose(bootblk);
1106
    }
1107
    numBlocks = getNum();
1108
    numInodes = getNum();
1109
  }
1110
  if (numBlocks > maxBlocks) {
1111
    error("file system exceeds available space");
1112
  }
1113
  if (numBlocks < maxBlocks) {
1114
    printf("File system does not fully utilize available space.\n");
1115
  }
1116
  filsys.s_fsize = numBlocks;
1117
  filsys.s_isize = (numInodes + NIPB - 1) / NIPB;
1118
  numInodes = filsys.s_isize * NIPB;
1119
  if (2 + filsys.s_isize >= filsys.s_fsize) {
1120
    error("bad block ratio (total/inode = %lu/%lu)",
1121
          filsys.s_fsize, filsys.s_isize);
1122
  }
1123
  printf("File system size = %ld blocks\n", filsys.s_fsize);
1124
  printf("Number of inodes = %ld inodes\n", numInodes);
1125
  filsys.s_freeblks = 0;
1126
  filsys.s_freeinos = 0;
1127
  filsys.s_ninode = 0;
1128
  for (i = 0; i < NICINOD; i++) {
1129
    filsys.s_inode[i] = 0;
1130
  }
1131
  filsys.s_nfree = 0;
1132
  for (i = 0; i < NICFREE; i++) {
1133
    filsys.s_free[i] = 0;
1134
  }
1135
  filsys.s_time = now;
1136
  filsys.s_flock = 0;
1137
  filsys.s_ilock = 0;
1138
  filsys.s_fmod = 0;
1139
  filsys.s_ronly = 0;
1140
  /* init inodes */
1141
  initInodes();
1142
  /* init free list */
1143
  initFreeList();
1144
  /* create files */
1145
  createFile(NULL);
1146
  /* fill free inode list in super block */
1147
  /* note: this isn't strictly necessary, but cuts down file
1148
     creation time within the newly created partition or disk */
1149
  fillFreeInodeList(numInodes);
1150
  /* finally write super block and return */
1151
  wtfs(1, (unsigned char *) &filsys, TYPE_SUPER);
1152
  return 0;
1153
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.