]> Zhao Yanbai Git Server - minix.git/commitdiff
Make mkfs.mfs cross compilable
authorThomas Veerman <tveerman@gmail.com>
Tue, 12 Jun 2012 18:45:29 +0000 (20:45 +0200)
committerThomas Veerman <thomas@minix3.org>
Mon, 18 Jun 2012 10:54:54 +0000 (10:54 +0000)
commands/Makefile
tools/Makefile
tools/mkfs.mfs/Makefile [new file with mode: 0644]
usr.sbin/Makefile
usr.sbin/mkfs.mfs/Makefile [moved from commands/mkfs.mfs/Makefile with 65% similarity]
usr.sbin/mkfs.mfs/const.h [new file with mode: 0644]
usr.sbin/mkfs.mfs/mfsdir.h [new file with mode: 0644]
usr.sbin/mkfs.mfs/mkfs.c [moved from commands/mkfs.mfs/mkfs.c with 84% similarity]
usr.sbin/mkfs.mfs/super.h [new file with mode: 0644]
usr.sbin/mkfs.mfs/type.h [new file with mode: 0644]

index baa0d80c2d1f11cb195b489ac998922174e5ef0f..b4bd668ef93fa8bc918c9462b03dc6437b980b33 100644 (file)
@@ -17,7 +17,7 @@ SUBDIR=       add_route arp ash at \
        intr ipcrm ipcs irdpd isoread join kill last \
        less loadkeys loadramdisk logger look lp \
        lpd ls lspci mail MAKEDEV \
-       mdb  mesg mined mkfifo mkfs.mfs mknod \
+       mdb  mesg mined mkfifo mknod \
        mkproto mount mt netconf nice acknm nohup \
        nonamed od paste patch pax \
        ping postinstall poweroff pr prep printf printroot \
index ace0ad160d2abae01e05c1fab2fbbb73609b552a..a3fa0aa9fe8fdde8b8c4408a3899d72e5ccb1871 100644 (file)
@@ -9,7 +9,7 @@ SUBDIR= host-mkdep .WAIT compat .WAIT \
        binstall .WAIT mktemp .WAIT sed .WAIT \
                genassym \
                makewhatis mkdep \
-               m4 \
+               mkfs.mfs m4 \
        .WAIT yacc \
        .WAIT awk \
        .WAIT tic \
diff --git a/tools/mkfs.mfs/Makefile b/tools/mkfs.mfs/Makefile
new file mode 100644 (file)
index 0000000..97b09db
--- /dev/null
@@ -0,0 +1,5 @@
+HOSTPROGNAME=  ${_TOOL_PREFIX}mkfs.mfs
+HOST_SRCDIR=   usr.sbin/mkfs.mfs
+
+LDADD= #defined
+.include "${.CURDIR}/../Makefile.host"
index 0a7b8133b48789a945d095662c96f0af2d6466bd..ace63176878d88ba5c8c3ea1c349ceb50237e3ae 100644 (file)
@@ -3,6 +3,6 @@
 .include <bsd.own.mk>
 
 # NetBSD imports
-SUBDIR= installboot pwd_mkdb user vipw zic chroot
+SUBDIR= installboot pwd_mkdb user vipw zic chroot mkfs.mfs
 
 .include <bsd.subdir.mk>
similarity index 65%
rename from commands/mkfs.mfs/Makefile
rename to usr.sbin/mkfs.mfs/Makefile
index bef0514ce4b753b067000baf89af20ed85d8888c..169888e6b81a5c86a8a3d0b036d1604bc9415738 100644 (file)
@@ -1,7 +1,8 @@
 PROG=  mkfs.mfs
 SRCS=  mkfs.c
 BINDIR=        /sbin
-CPPFLAGS+= -I${NETBSDSRCDIR}/servers
 MAN=
 
+LDADD?= -lminlib -lcompat_minix
+
 .include <bsd.prog.mk>
diff --git a/usr.sbin/mkfs.mfs/const.h b/usr.sbin/mkfs.mfs/const.h
new file mode 100644 (file)
index 0000000..863fe20
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef __MFS_CONST_H__
+#define __MFS_CONST_H__
+
+/* Tables sizes */
+#define V1_NR_DZONES       7   /* # direct zone numbers in a V1 inode */
+#define V1_NR_TZONES       9   /* total # zone numbers in a V1 inode */
+#define V2_NR_DZONES       7   /* # direct zone numbers in a V2 inode */
+#define V2_NR_TZONES      10   /* total # zone numbers in a V2 inode */
+
+#define NR_INODES        512   /* # slots in "in core" inode table,
+                                * should be more or less the same as
+                                * NR_VNODES in vfs
+                                */
+#define GETDENTS_BUFSIZ  257
+
+#define INODE_HASH_LOG2   7     /* 2 based logarithm of the inode hash size */
+#define INODE_HASH_SIZE   ((unsigned long)1<<INODE_HASH_LOG2)
+#define INODE_HASH_MASK   (((unsigned long)1<<INODE_HASH_LOG2)-1)
+
+/* Max. filename length */
+#define MFS_NAME_MAX    MFS_DIRSIZ
+
+
+/* The type of sizeof may be (unsigned) long.  Use the following macro for
+ * taking the sizes of small objects so that there are no surprises like
+ * (small) long constants being passed to routines expecting an int.
+ */
+#define usizeof(t) ((unsigned) sizeof(t))
+
+/* File system types. */
+#define SUPER_MAGIC   0x137F   /* magic number contained in super-block */
+#define SUPER_REV     0x7F13   /* magic # when 68000 disk read on PC or vv */
+#define SUPER_V2      0x2468   /* magic # for V2 file systems */
+#define SUPER_V2_REV  0x6824   /* V2 magic written on PC, read on 68K or vv */
+#define SUPER_V3      0x4d5a   /* magic # for V3 file systems */
+
+#define V1                1    /* version number of V1 file systems */ 
+#define V2                2    /* version number of V2 file systems */ 
+#define V3                3    /* version number of V3 file systems */ 
+
+/* Miscellaneous constants */
+#define SU_UID          ((uid_t) 0)    /* super_user's uid_t */
+#define NORMAL            0    /* forces get_block to do disk read */
+#define NO_READ            1   /* prevents get_block from doing disk read */
+#define PREFETCH           2   /* tells get_block not to read or mark dev */
+
+#define NO_BIT   ((uint32_t) 0)        /* returned by alloc_bit() to signal failure */
+
+#define LOOK_UP            0 /* tells search_dir to lookup string */
+#define ENTER              1 /* tells search_dir to make dir entry */
+#define DELETE             2 /* tells search_dir to delete entry */
+#define IS_EMPTY           3 /* tells search_dir to ret. OK or ENOTEMPTY */  
+
+/* write_map() args */
+#define WMAP_FREE      (1 << 0)
+
+#define IGN_PERM       0
+#define CHK_PERM       1
+
+#define BP_CLEAN        0      /* on-disk block and memory copies identical */
+#define BP_DIRTY        1      /* on-disk block and memory copies differ */
+#define IN_CLEAN        0      /* in-block inode and memory copies identical */
+#define IN_DIRTY        1      /* in-block inode and memory copies differ */
+#define ATIME            002   /* set if atime field needs updating */
+#define CTIME            004   /* set if ctime field needs updating */
+#define MTIME            010   /* set if mtime field needs updating */
+
+#define BYTE_SWAP          0   /* tells conv2/conv4 to swap bytes */
+
+#define END_OF_FILE   (-104)   /* eof detected */
+
+#define ROOT_INODE    ((ino_t) 1)      /* inode number for root directory */
+#define BOOT_BLOCK  ((blkcnt_t) 0)     /* block number of boot block */
+#define SUPER_BLOCK_BYTES  (1024)      /* bytes offset */
+#define START_BLOCK ((blkcnt_t) 2)     /* first block of FS (not counting SB) */
+
+#define DIR_ENTRY_SIZE       usizeof (struct direct)  /* # bytes/dir entry   */
+#define NR_DIR_ENTRIES(b)   ((b)/DIR_ENTRY_SIZE)  /* # dir entries/blk   */
+#define SUPER_SIZE      usizeof (struct super_block)  /* super_block size    */
+
+#define FS_BITMAP_CHUNKS(b) ((b)/usizeof (uint32_t))/* # map chunks/blk   */
+#define FS_BITCHUNK_BITS               (usizeof(uint32_t) * CHAR_BIT)
+#define FS_BITS_PER_BLOCK(b)   (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
+
+/* Derived sizes pertaining to the V1 file system. */
+#define V1_ZONE_NUM_SIZE           usizeof (uint16_t)  /* # bytes in V1 zone  */
+#define V1_INODE_SIZE             usizeof (d1_inode)  /* bytes in V1 dsk ino */
+
+/* # zones/indir block */
+#define V1_INDIRECTS (_STATIC_BLOCK_SIZE/V1_ZONE_NUM_SIZE)  
+
+/* # V1 dsk inodes/blk */
+#define V1_INODES_PER_BLOCK (_STATIC_BLOCK_SIZE/V1_INODE_SIZE)
+
+/* Derived sizes pertaining to the V2 file system. */
+#define V2_ZONE_NUM_SIZE            usizeof (uint32_t)  /* # bytes in V2 zone  */
+#define V2_INODE_SIZE             usizeof (d2_inode)  /* bytes in V2 dsk ino */
+#define V2_INDIRECTS(b)   ((b)/V2_ZONE_NUM_SIZE)  /* # zones/indir block */
+#define V2_INODES_PER_BLOCK(b) ((b)/V2_INODE_SIZE)/* # V2 dsk inodes/blk */
+
+#define NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
+
+#define _STATIC_BLOCK_SIZE      1024
+#define _MIN_BLOCK_SIZE          1024
+#define _MAX_BLOCK_SIZE          4096
+#endif
+
diff --git a/usr.sbin/mkfs.mfs/mfsdir.h b/usr.sbin/mkfs.mfs/mfsdir.h
new file mode 100644 (file)
index 0000000..ea4c71c
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _MFSDIR_H
+#define _MFSDIR_H
+
+/* Maximum Minix MFS on-disk directory filename.
+ * MFS uses 'struct direct' to write and parse 
+ * directory entries, so this can't be changed
+ * without breaking filesystems.
+ */
+
+#define MFS_DIRSIZ     60
+
+struct direct {
+  uint32_t mfs_d_ino;
+  char mfs_d_name[MFS_DIRSIZ];
+#ifdef __NBSD_LIBC 
+} __packed;
+#else
+};
+#endif
+
+#endif /* _MFSDIR_H */
similarity index 84%
rename from commands/mkfs.mfs/mkfs.c
rename to usr.sbin/mkfs.mfs/mkfs.c
index ab495e2d35e2ff3628e54aa503bf9ec3150841c6..a710690ebaa89a0bdbc5c5ccdd0c83e280deaa09 100644 (file)
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/type.h>
-#include <minix/minlib.h>
-#include "mfs/const.h"
-#include "mfs/mfsdir.h"
-#if (MACHINE == IBM_PC)
+#include <stdint.h>
+#include "const.h"
+#include "type.h"
+#include "mfsdir.h"
+#if (defined(__minix) && MACHINE == IBM_PC)
 #include <minix/partition.h>
 #include <minix/u64.h>
 #include <sys/ioctl.h>
 #endif
 #include <a.out.h>
-#include <tools.h>
 #include <dirent.h>
 
 #undef EXTERN
 #define EXTERN                 /* get rid of EXTERN by making it null */
-#include "mfs/super.h"
-#include "mfs/type.h"
-#include "mfs/inode.h"
-#include <minix/fslib.h>
+#include "super.h"
 
 #ifndef max
 #define max(a,b) ((a) > (b) ? (a) : (b))
@@ -59,6 +53,7 @@
 #define BINGRP               2
 #define BIT_MAP_SHIFT       13
 #define INODE_MAX       ((unsigned) 65535)
+#define SECTOR_SIZE       512
 
 
 #ifdef DOS
@@ -66,6 +61,19 @@ maybedefine O_RDONLY 4               /* O_RDONLY | BINARY_BIT */
  maybedefine BWRITE 5          /* O_WRONLY | BINARY_BIT */
 #endif
 
+#if !defined(__minix)
+#define mul64u(a,b)    ((a) * (b))
+#define lseek64(a,b,c,d) lseek(a,b,c)
+#ifdef __linux__
+#include <mntent.h>
+#endif
+#endif
+
+#if !defined(__minix)
+typedef uint32_t block_t;
+typedef uint32_t zone_t;
+#endif
+
 extern char *optarg;
 extern int optind;
 
@@ -77,42 +85,42 @@ int override = 0, simple = 0, dflag;
 int donttest;                  /* skip test if it fits on medium */
 char *progname;
 
-long current_time, bin_time;
+uint32_t current_time, bin_time;
 char *zero, *lastp;
 char *umap_array;      /* bit map tells if block read yet */
 int umap_array_elements = 0;
 block_t zone_map;              /* where is zone map? (depends on # inodes) */
 int inodes_per_block;
 int fs_version;
-unsigned int block_size;
+size_t block_size;
 
 FILE *proto;
 
-#ifdef __NBSD_LIBC
+#if defined(__NBSD_LIBC) || !defined(__minix)
 #define getline _mkfs_getline
 #endif
 
 int main(int argc, char **argv);
 block_t sizeup(char *device);
-void super(zone_t zones, Ino_t inodes);
-void rootdir(Ino_t inode);
-void eat_dir(Ino_t parent);
-void eat_file(Ino_t inode, int f);
-void enter_dir(Ino_t parent, char *name, Ino_t child);
-void incr_size(Ino_t n, long count);
+void super(zone_t zones, ino_t inodes);
+void rootdir(ino_t inode);
+void eat_dir(ino_t parent);
+void eat_file(ino_t inode, int f);
+void enter_dir(ino_t parent, char *name, ino_t child);
+void incr_size(ino_t n, size_t count);
 static ino_t alloc_inode(int mode, int usrid, int grpid);
 static zone_t alloc_zone(void);
-void add_zone(Ino_t n, zone_t z, long bytes, long cur_time);
-void add_z_1(Ino_t n, zone_t z, long bytes, long cur_time);
-void add_z_2(Ino_t n, zone_t z, long bytes, long cur_time);
-void incr_link(Ino_t n);
+void add_zone(ino_t n, zone_t z, size_t bytes, uint32_t cur_time);
+void add_z_1(ino_t n, zone_t z, size_t bytes, uint32_t cur_time);
+void add_z_2(ino_t n, zone_t z, size_t bytes, uint32_t cur_time);
+void incr_link(ino_t n);
 void insert_bit(block_t block, int bit);
 int mode_con(char *p);
 void getline(char line[LINE_LEN], char *parse[MAX_TOKENS]);
 void check_mtab(char *devname);
-long file_time(int f);
+uint32_t file_time(int f);
 void pexit(char *s);
-void copy(char *from, char *to, int count);
+void copy(char *from, char *to, size_t count);
 void print_fs(void);
 int read_and_set(block_t n);
 void special(char *string);
@@ -136,7 +144,7 @@ char *argv[];
 {
   int nread, mode, usrid, grpid, ch;
   block_t blocks, maxblocks;
-  block_t i;
+  size_t i;
   ino_t root_inum;
   ino_t inodes;
   zone_t zones;
@@ -270,7 +278,11 @@ char *argv[];
                if (blocks == 0) pexit("Can't open prototype file");
        }
        if (i == 0) {
-               u32_t kb = div64u(mul64u(blocks, block_size), 1024);
+#if defined(_MINIX) || defined(__minix)
+               uint32_t kb = div64u(mul64u(blocks, block_size), 1024);
+#else
+               uint32_t kb = ((unsigned long long) blocks * block_size) / 1024;
+#endif
                i = kb / 2;
                if (kb >= 100000) i = kb / 4;
 
@@ -299,7 +311,7 @@ char *argv[];
   size_t bytes;
   bytes = 1 + blocks/8;
   if(!(umap_array = malloc(bytes))) {
-       fprintf(stderr, "mkfs: can't allocate block bitmap (%d bytes).\n",
+       fprintf(stderr, "mkfs: can't allocate block bitmap (%u bytes).\n",
                bytes);
        exit(1);
   }
@@ -325,7 +337,7 @@ char *argv[];
        testb[block_size/2-1] = 0x1F2F;
        if ((w=write(fd, (char *) testb, block_size)) != block_size) {
                if(w < 0) perror("write");
-               printf("%d/%d\n", w, block_size);
+               printf("%d/%u\n", w, block_size);
                pexit("File system is too big for minor device (write)");
        }
        sync();                 /* flush write, so if error next read fails */
@@ -381,10 +393,22 @@ printf("testb = 0x%x 0x%x 0x%x\n", testb[0], testb[1], testb[block_size-1]);
 block_t sizeup(device)
 char *device;
 {
-  u64_t bytes, resize;
   block_t d;
+#if defined(__minix)
+  u64_t bytes, resize;
   u32_t rem;
+#else
+  off_t size;
+#endif
 
+
+  if ((fd = open(device, O_RDONLY)) == -1) {
+       if (errno != ENOENT)
+               perror("sizeup open");
+       return 0;
+  }
+
+#if defined(__minix)
   if(minix_sizeup(device, &bytes) < 0) {
        perror("sizeup");
        return 0;
@@ -396,12 +420,33 @@ char *device;
   resize = add64u(mul64u(d, block_size), rem);
   if(cmp64(resize, bytes) != 0) {
        d = ULONG_MAX;
-       fprintf(stderr, "mkfs: truncating FS at %lu blocks\n", d);
+       fprintf(stderr, "mkfs: truncating FS at %u blocks\n", d);
+  }
+#else
+  size = lseek(fd, 0, SEEK_END);
+  if (size == (off_t) -1) {
+         fprintf(stderr, "Cannot get device size fd=%d\n", fd);
+         exit(-1);
   }
+  d = size / block_size;
+#endif
 
   return d;
 }
 
+/*
+ * copied from fslib
+ */
+static int bitmapsize(nr_bits, block_size)
+uint32_t nr_bits;
+size_t block_size;
+{
+  block_t nr_blocks;
+
+  nr_blocks = (int) (nr_bits / FS_BITS_PER_BLOCK(block_size));
+  if (((uint32_t) nr_blocks * FS_BITS_PER_BLOCK(block_size)) < nr_bits) ++nr_blocks;
+  return(nr_blocks);
+}
 
 /*================================================================
  *                 super  -  construct a superblock
@@ -414,7 +459,7 @@ ino_t inodes;
   unsigned int i;
   int inodeblks;
   int initblks;
-  u32_t nb;
+  uint32_t nb;
   zone_t v1sq, v2sq;
   zone_t zo;
   struct super_block *sup;
@@ -438,12 +483,12 @@ ino_t inodes;
   }
   
 #define BIGGERBLOCKS "Please try a larger block size for an FS of this size.\n"
-  sup->s_imap_blocks = nb = bitmapsize((bit_t) (1 + inodes), block_size);
+  sup->s_imap_blocks = nb = bitmapsize((uint32_t) (1 + inodes), block_size);
   if(sup->s_imap_blocks != nb) {
        fprintf(stderr, "mkfs: too many inode bitmap blocks.\n" BIGGERBLOCKS);
        exit(1);
   }
-  sup->s_zmap_blocks = nb = bitmapsize((bit_t) zones, block_size);
+  sup->s_zmap_blocks = nb = bitmapsize((uint32_t) zones, block_size);
   if(nb != sup->s_zmap_blocks) {
        fprintf(stderr, "mkfs: too many block bitmap blocks.\n" BIGGERBLOCKS);
        exit(1);
@@ -468,7 +513,7 @@ ino_t inodes;
   if (fs_version == 1) {
        sup->s_magic = SUPER_MAGIC;     /* identify super blocks */
        v1sq = (zone_t) V1_INDIRECTS * V1_INDIRECTS;
-       zo = V1_NR_DZONES + (long) V1_INDIRECTS + v1sq;
+       zo = V1_NR_DZONES + (int) V1_INDIRECTS + v1sq;
        sup->s_max_size = zo * block_size;
   } else {
        v2sq = (zone_t) V2_INDIRECTS(block_size) * V2_INDIRECTS(block_size);
@@ -480,9 +525,9 @@ ino_t inodes;
                sup->s_magic = SUPER_V3;
                sup->s_block_size = block_size;
                sup->s_disk_version = 0;
-#define MAX_MAX_SIZE   ((unsigned long) LONG_MAX)
+#define MAX_MAX_SIZE   (INT_MAX)
                if(MAX_MAX_SIZE/block_size < zo) {
-                       sup->s_max_size = MAX_MAX_SIZE;
+                       sup->s_max_size = (int32_t) MAX_MAX_SIZE;
                }
                else {
                        sup->s_max_size = zo * block_size;
@@ -544,7 +589,7 @@ ino_t parent;
   int mode, usrid, grpid, maj, min, f;
   ino_t n;
   zone_t z;
-  long size;
+  size_t size;
 
   while (1) {
        getline(line, token);
@@ -579,7 +624,7 @@ ino_t parent;
                size = 0;
                if (token[6]) size = atoi(token[6]);
                size = block_size * size;
-               add_zone(n, (zone_t) ((maj << 8) | min), size, current_time);
+               add_zone(n, (zone_t) (makedev(maj,min)), size, current_time);
        } else {
                /* Regular file. Go read it. */
                if ((f = open(token[4], O_RDONLY)) < 0) {
@@ -604,7 +649,7 @@ int f;
   int ct, i, j, k;
   zone_t z;
   char *buf;
-  long timeval;
+  uint32_t timeval;
 
   buf = alloc_block();
 
@@ -617,9 +662,10 @@ int f;
                }
        }
        timeval = (dflag ? current_time : file_time(f));
-       if (ct) add_zone(inode, z, (long) j, timeval);
+       if (ct) add_zone(inode, z, (size_t) j, timeval);
   } while (ct == block_size);
   close(f);
+  free(buf);
 }
 
 
@@ -633,7 +679,7 @@ char *name;
 {
   /* Enter child in parent directory */
   /* Works for dir > 1 block and zone > block */
-  int i, j, k, l, off;
+  unsigned int i, j, k, l, off;
   block_t b;
   zone_t z;
   char *p1, *p2;
@@ -680,6 +726,7 @@ char *name;
                                p1 = name;
                                p2 = dir_entry[i].mfs_d_name;
                                j = sizeof(dir_entry[i].mfs_d_name);
+                               j = 60;
                                while (j--) {
                                        *p2++ = *p1;
                                        if (*p1 != 0) p1++;
@@ -698,16 +745,13 @@ char *name;
        }
   }
 
-  printf("Directory-inode %d beyond direct blocks.  Could not enter %s\n",
+  printf("Directory-inode %lu beyond direct blocks.  Could not enter %s\n",
          parent, name);
   pexit("Halt");
 }
 
 
-void add_zone(n, z, bytes, cur_time)
-ino_t n;
-zone_t z;
-long bytes, cur_time;
+void add_zone(ino_t n, zone_t z, size_t bytes, uint32_t cur_time)
 {
   if (fs_version == 1) {
        add_z_1(n, z, bytes, cur_time);
@@ -716,17 +760,14 @@ long bytes, cur_time;
   }
 }
 
-void add_z_1(n, z, bytes, cur_time)
-ino_t n;
-zone_t z;
-long bytes, cur_time;
+void add_z_1(ino_t n, zone_t z, size_t bytes, uint32_t cur_time)
 {
   /* Add zone z to inode n. The file has grown by 'bytes' bytes. */
 
   int off, i;
   block_t b;
   zone_t indir;
-  zone1_t blk[V1_INDIRECTS];
+  uint16_t blk[V1_INDIRECTS];
   d1_inode *p;
   d1_inode inode[V1_INODES_PER_BLOCK];
 
@@ -738,7 +779,7 @@ long bytes, cur_time;
   p->d1_mtime = cur_time;
   for (i = 0; i < V1_NR_DZONES; i++)
        if (p->d1_zone[i] == 0) {
-               p->d1_zone[i] = (zone1_t) z;
+               p->d1_zone[i] = (uint16_t) z;
                put_block(b, (char *) inode);
                return;
        }
@@ -746,24 +787,21 @@ long bytes, cur_time;
 
   /* File has grown beyond a small file. */
   if (p->d1_zone[V1_NR_DZONES] == 0)
-       p->d1_zone[V1_NR_DZONES] = (zone1_t) alloc_zone();
+       p->d1_zone[V1_NR_DZONES] = (uint16_t) alloc_zone();
   indir = p->d1_zone[V1_NR_DZONES];
   put_block(b, (char *) inode);
   b = indir << zone_shift;
   get_block(b, (char *) blk);
   for (i = 0; i < V1_INDIRECTS; i++)
        if (blk[i] == 0) {
-               blk[i] = (zone1_t) z;
+               blk[i] = (uint16_t) z;
                put_block(b, (char *) blk);
                return;
        }
   pexit("File has grown beyond single indirect");
 }
 
-void add_z_2(n, z, bytes, cur_time)
-ino_t n;
-zone_t z;
-long bytes, cur_time;
+void add_z_2(ino_t n, zone_t z, size_t bytes, uint32_t cur_time)
 {
   /* Add zone z to inode n. The file has grown by 'bytes' bytes. */
 
@@ -850,7 +888,7 @@ ino_t n;
 
 void incr_size(n, count)
 ino_t n;
-long count;
+size_t count;
 {
   /* Increment the file-size in inode n */
   block_t b;
@@ -953,14 +991,26 @@ int bit;
 {
   /* Insert 'count' bits in the bitmap */
   int w, s;
+#if defined(__minix)
   bitchunk_t *buf;
+#else
+  uint32_t *buf;
+#endif
 
+#if defined(__minix)
   buf = (bitchunk_t *) alloc_block();
+#else
+  buf = (uint32_t *) alloc_block();
+#endif
 
-  if (block < 0) pexit("insert_bit called with negative argument");
   get_block(block, (char *) buf);
+#if defined(__minix)
   w = bit / (8 * sizeof(bitchunk_t));
   s = bit % (8 * sizeof(bitchunk_t));
+#else
+  w = bit / (8 * sizeof(uint32_t));
+  s = bit % (8 * sizeof(uint32_t));
+#endif
   buf[w] |= (1 << s);
   put_block(block, (char *) buf);
 
@@ -985,12 +1035,12 @@ char *p;
   o2 = *p++ - '0';
   o3 = *p++ - '0';
   mode = (o1 << 6) | (o2 << 3) | o3;
-  if (c1 == 'd') mode += I_DIRECTORY;
-  if (c1 == 'b') mode += I_BLOCK_SPECIAL;
-  if (c1 == 'c') mode += I_CHAR_SPECIAL;
-  if (c1 == '-') mode += I_REGULAR;
-  if (c2 == 'u') mode += I_SET_UID_BIT;
-  if (c3 == 'g') mode += I_SET_GID_BIT;
+  if (c1 == 'd') mode |= S_IFDIR;
+  if (c1 == 'b') mode |= S_IFBLK;
+  if (c1 == 'c') mode |= S_IFCHR;
+  if (c1 == '-') mode |= S_IFREG;
+  if (c2 == 'u') mode |= S_ISUID;
+  if (c3 == 'g') mode |= S_ISGID;
   return(mode);
 }
 
@@ -1041,22 +1091,22 @@ char line[LINE_LEN];
 /*================================================================
  *                     other stuff
  *===============================================================*/
-void check_mtab(devname)
-char *devname;                 /* /dev/hd1 or whatever */
+void check_mtab(device)
+char *device;                  /* /dev/hd1 or whatever */
 {
 /* Check to see if the special file named in s is mounted. */
-
+#if defined(__minix)
   int n, r;
   struct stat sb;
   char special[PATH_MAX + 1], mounted_on[PATH_MAX + 1], version[10], rw_flag[10];
 
-  r= stat(devname, &sb);
+  r= stat(device, &sb);
   if (r == -1)
   {
        if (errno == ENOENT)
                return; /* Does not exist, and therefore not mounted. */
        fprintf(stderr, "%s: stat %s failed: %s\n",
-               progname, devname, strerror(errno));
+               progname, device, strerror(errno));
        exit(1);
   }
   if (!S_ISBLK(sb.st_mode))
@@ -1069,17 +1119,124 @@ char *devname;                 /* /dev/hd1 or whatever */
   while (1) {
        n = get_mtab_entry(special, mounted_on, version, rw_flag);
        if (n < 0) return;
-       if (strcmp(devname, special) == 0) {
+       if (strcmp(device, special) == 0) {
                /* Can't mkfs on top of a mounted file system. */
                fprintf(stderr, "%s: %s is mounted on %s\n",
-                       progname, devname, mounted_on);
+                       progname, device, mounted_on);
                exit(1);
        }
   }
+#elif defined(__linux__)
+/* XXX: this code is copyright Theodore T'so and distributed under the GPLv2. Rewrite.
+ */
+       struct mntent   *mnt;
+       struct stat     st_buf;
+       dev_t           file_dev=0, file_rdev=0;
+       ino_t           file_ino=0;
+       FILE            *f;
+       int             fd;
+       char            *mtab_file = "/proc/mounts";
+
+       if ((f = setmntent (mtab_file, "r")) == NULL)
+               goto error;
+
+       if (stat(device, &st_buf) == 0) {
+               if (S_ISBLK(st_buf.st_mode)) {
+                       file_rdev = st_buf.st_rdev;
+               } else {
+                       file_dev = st_buf.st_dev;
+                       file_ino = st_buf.st_ino;
+               }
+       }
+       
+       while ((mnt = getmntent (f)) != NULL) {
+               if (strcmp(device, mnt->mnt_fsname) == 0)
+                       break;
+               if (stat(mnt->mnt_fsname, &st_buf) == 0) {
+                       if (S_ISBLK(st_buf.st_mode)) {
+                               if (file_rdev && (file_rdev == st_buf.st_rdev))
+                                       break;
+                       } else {
+                               if (file_dev && ((file_dev == st_buf.st_dev) &&
+                                                (file_ino == st_buf.st_ino)))
+                                       break;
+                       }
+               }
+       }
+
+       if (mnt == NULL) {
+               /*
+                * Do an extra check to see if this is the root device.  We
+                * can't trust /etc/mtab, and /proc/mounts will only list
+                * /dev/root for the root filesystem.  Argh.  Instead we
+                * check if the given device has the same major/minor number
+                * as the device that the root directory is on.
+                */
+               if (file_rdev && stat("/", &st_buf) == 0) {
+                       if (st_buf.st_dev == file_rdev) {
+                               goto is_root;
+                       }
+               }
+               goto test_busy;
+       }
+       /* Validate the entry in case /etc/mtab is out of date */
+       /* 
+        * We need to be paranoid, because some broken distributions
+        * (read: Slackware) don't initialize /etc/mtab before checking
+        * all of the non-root filesystems on the disk.
+        */
+       if (stat(mnt->mnt_dir, &st_buf) < 0) {
+               if (errno == ENOENT) {
+                       goto test_busy;
+               }
+               goto error;
+       }
+       if (file_rdev && (st_buf.st_dev != file_rdev)) {
+               goto error;
+       }
+
+       fprintf(stderr, "Device %s is mounted, exiting\n", device);
+       exit(-1);
+
+       /*
+        * Check to see if we're referring to the root filesystem.
+        * If so, do a manual check to see if we can open /etc/mtab
+        * read/write, since if the root is mounted read/only, the
+        * contents of /etc/mtab may not be accurate.
+        */
+       if (!strcmp(mnt->mnt_dir, "/")) {
+is_root:
+               fprintf(stderr, "Device %s is mounted as root file system!\n",
+                               device);
+               exit(-1);
+       }
+       
+test_busy:
+
+       endmntent (f);
+       if ((stat(device, &st_buf) != 0) ||
+                       !S_ISBLK(st_buf.st_mode))
+               return;
+       fd = open(device, O_RDONLY | O_EXCL);
+       if (fd < 0) {
+               if (errno == EBUSY) {
+                       fprintf(stderr, "Device %s is used by the system\n", device);
+                       exit(-1);
+               }
+       } else
+               close(fd);
+
+       return;
+
+error:
+       endmntent (f);
+       fprintf(stderr, "Error while checking if device %s is mounted\n", device);
+       exit(-1);
+#endif
 }
 
 
-long file_time(f)
+uint32_t file_time(f)
 int f;
 {
 #ifdef UNIX
@@ -1105,7 +1262,7 @@ char *s;
 
 void copy(from, to, count)
 char *from, *to;
-int count;
+size_t count;
 {
   while (count--) *to++ = *from++;
 }
@@ -1129,7 +1286,7 @@ void print_fs()
   d1_inode inode1[V1_INODES_PER_BLOCK];
   d2_inode *inode2;
   unsigned short *usbuf;
-  block_t b, inode_limit;
+  block_t b;
   struct direct *dir;
 
   if(!(inode2 = malloc(V2_INODES_PER_BLOCK(block_size) * sizeof(*inode2))))
@@ -1167,35 +1324,35 @@ void print_fs()
                if (k > nrinodes) break;
                if (fs_version == 1) {
                        if (inode1[i].d1_mode != 0) {
-                               printf("Inode %2d:  mode=", k);
+                               printf("Inode %2lu:  mode=", k);
                                printf("%06o", inode1[i].d1_mode);
                                printf("  uid=%2d  gid=%2d  size=",
                                inode1[i].d1_uid, inode1[i].d1_gid);
-                               printf("%6ld", inode1[i].d1_size);
+                               printf("%6d", inode1[i].d1_size);
                                printf("  zone[0]=%d\n", inode1[i].d1_zone[0]);
                        }
-                       if ((inode1[i].d1_mode & I_TYPE) == I_DIRECTORY) {
+                       if ((inode1[i].d1_mode & S_IFMT) == S_IFDIR) {
                                /* This is a directory */
                                get_block(inode1[i].d1_zone[0], (char *) dir);
                                for (j = 0; j < NR_DIR_ENTRIES(block_size); j++)
                                        if (dir[j].mfs_d_ino)
-                                               printf("\tInode %2d: %s\n", dir[j].mfs_d_ino, dir[j].mfs_d_name);
+                                               printf("\tInode %2u: %s\n", dir[j].mfs_d_ino, dir[j].mfs_d_name);
                        }
                } else {
                        if (inode2[i].d2_mode != 0) {
-                               printf("Inode %2d:  mode=", k);
+                               printf("Inode %2lu:  mode=", k);
                                printf("%06o", inode2[i].d2_mode);
                                printf("  uid=%2d  gid=%2d  size=",
                                inode2[i].d2_uid, inode2[i].d2_gid);
-                               printf("%6ld", inode2[i].d2_size);
-                               printf("  zone[0]=%ld\n", inode2[i].d2_zone[0]);
+                               printf("%6d", inode2[i].d2_size);
+                               printf("  zone[0]=%u\n", inode2[i].d2_zone[0]);
                        }
-                       if ((inode2[i].d2_mode & I_TYPE) == I_DIRECTORY) {
+                       if ((inode2[i].d2_mode & S_IFMT) == S_IFDIR) {
                                /* This is a directory */
                                get_block(inode2[i].d2_zone[0], (char *) dir);
                                for (j = 0; j < NR_DIR_ENTRIES(block_size); j++)
                                        if (dir[j].mfs_d_ino)
-                                               printf("\tInode %2d: %s\n", dir[j].mfs_d_ino, dir[j].mfs_d_name);
+                                               printf("\tInode %2u: %s\n", dir[j].mfs_d_ino, dir[j].mfs_d_name);
                        }
                }
        }
diff --git a/usr.sbin/mkfs.mfs/super.h b/usr.sbin/mkfs.mfs/super.h
new file mode 100644 (file)
index 0000000..d90757a
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef __MFS_SUPER_H__
+#define __MFS_SUPER_H__
+
+/* Super block table.  The root file system and every mounted file system
+ * has an entry here.  The entry holds information about the sizes of the bit
+ * maps and inodes.  The s_ninodes field gives the number of inodes available
+ * for files and directories, including the root directory.  Inode 0 is 
+ * on the disk, but not used.  Thus s_ninodes = 4 means that 5 bits will be
+ * used in the bit map, bit 0, which is always 1 and not used, and bits 1-4
+ * for files and directories.  The disk layout is:
+ *
+ *    Item        # blocks
+ *    boot block      1
+ *    super block     1    (offset 1kB)
+ *    inode map     s_imap_blocks
+ *    zone map      s_zmap_blocks
+ *    inodes        (s_ninodes + 'inodes per block' - 1)/'inodes per block'
+ *    unused        whatever is needed to fill out the current zone
+ *    data zones    (s_zones - s_firstdatazone) << s_log_zone_size
+ *
+ * A super_block slot is free if s_dev == NO_DEV. 
+ */
+
+EXTERN struct super_block {
+  uint32_t s_ninodes;          /* # usable inodes on the minor device */
+  uint16_t  s_nzones;          /* total device size, including bit maps etc */
+  int16_t s_imap_blocks;       /* # of blocks used by inode bit map */
+  int16_t s_zmap_blocks;       /* # of blocks used by zone bit map */
+  uint16_t s_firstdatazone_old;        /* number of first data zone (small) */
+  uint16_t s_log_zone_size;    /* log2 of blocks/zone */
+  uint16_t s_flags;            /* FS state flags */
+  int32_t s_max_size;          /* maximum file size on this device */
+  uint32_t s_zones;            /* number of zones (replaces s_nzones in V2) */
+  int16_t s_magic;             /* magic number to recognize super-blocks */
+
+  /* The following items are valid on disk only for V3 and above */
+
+  /* The block size in bytes. Minimum MIN_BLOCK SIZE. SECTOR_SIZE
+   * multiple. If V1 or V2 filesystem, this should be
+   * initialised to STATIC_BLOCK_SIZE.
+   */
+  int16_t s_pad2;              /* try to avoid compiler-dependent padding */
+  uint16_t s_block_size;       /* block size in bytes. */
+  int8_t s_disk_version;       /* filesystem format sub-version */
+
+  /* The following items are only used when the super_block is in memory.
+   * If this ever changes, i.e. more fields after s_disk_version has to go to
+   * disk, update LAST_ONDISK_FIELD in super.c as that controls which part of the
+   * struct is copied to and from disk.
+   */
+  
+  /*struct inode *s_isup;*/    /* inode for root dir of mounted file sys */
+  /*struct inode *s_imount;*/   /* inode mounted on */
+  unsigned s_inodes_per_block; /* precalculated from magic number */
+  uint32_t s_firstdatazone;    /* number of first data zone (big) */
+  dev_t s_dev;                 /* whose super block is this? */
+  int32_t s_rd_only;           /* set to 1 iff file sys mounted read only */
+  int32_t s_native;            /* set to 1 iff not byte swapped file system */
+  int32_t s_version;           /* file system version, zero means bad magic */
+  int32_t s_ndzones;           /* # direct zones in an inode */
+  int32_t s_nindirs;           /* # indirect zones per indirect block */
+  uint32_t s_isearch;          /* inodes below this bit number are in use */
+  uint32_t s_zsearch;          /* all zones below this bit number are in use*/
+  int8_t s_is_root;
+} superblock;
+
+#define IMAP           0       /* operating on the inode bit map */
+#define ZMAP           1       /* operating on the zone bit map */
+
+/* s_flags contents; undefined flags are guaranteed to be zero on disk
+ * (not counting future versions of mfs setting them!)
+ */
+#define MFSFLAG_CLEAN  (1L << 0) /* 0: dirty; 1: FS was unmounted cleanly */
+
+/* Future compatability (or at least, graceful failure):
+ * if any of these bits are on, and the MFS or fsck
+ * implementation doesn't understand them, do not mount/fsck
+ * the FS.
+ */
+#define MFSFLAG_MANDATORY_MASK 0xff00
+
+#endif
+
diff --git a/usr.sbin/mkfs.mfs/type.h b/usr.sbin/mkfs.mfs/type.h
new file mode 100644 (file)
index 0000000..2c65282
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __MFS_TYPE_H__
+#define __MFS_TYPE_H__
+
+/* Declaration of the V1 inode as it is on the disk (not in core). */
+typedef struct {               /* V1.x disk inode */
+  uint16_t d1_mode;            /* file type, protection, etc. */
+  int16_t d1_uid;              /* user id of the file's owner */
+  int32_t d1_size;             /* current file size in bytes */
+  int32_t d1_mtime;            /* when was file data last changed */
+  uint8_t d1_gid;              /* group number */
+  uint8_t d1_nlinks;           /* how many links to this file */
+  uint16_t d1_zone[V1_NR_TZONES];/* block nums for direct, ind, and dbl ind */
+} d1_inode;
+
+/* Declaration of the V2 inode as it is on the disk (not in core). */
+typedef struct {               /* V2.x disk inode */
+  uint16_t d2_mode;            /* file type, protection, etc. */
+  uint16_t d2_nlinks;          /* how many links to this file. HACK! */
+  int16_t d2_uid;              /* user id of the file's owner. */
+  uint16_t d2_gid;             /* group number HACK! */
+  int32_t d2_size;             /* current file size in bytes */
+  int32_t d2_atime;            /* when was file data last accessed */
+  int32_t d2_mtime;            /* when was file data last changed */
+  int32_t d2_ctime;            /* when was inode data last changed */
+  uint32_t d2_zone[V2_NR_TZONES];/* block nums for direct, ind, and dbl ind */
+} d2_inode;
+
+struct buf {
+  /* Data portion of the buffer. */
+  union fsdata_u *bp;
+
+  /* Header portion of the buffer. */
+  struct buf *b_next;          /* used to link all free bufs in a chain */
+  struct buf *b_prev;          /* used to link all free bufs the other way */
+  struct buf *b_hash;          /* used to link bufs on hash chains */
+  uint32_t b_blocknr;          /* block number of its (minor) device */
+  dev_t b_dev;                 /* major | minor device where block resides */
+  char b_dirt;                 /* BP_CLEAN or BP_DIRTY */
+  char b_count;                        /* number of users of this buffer */
+  unsigned int b_bytes;                /* Number of bytes allocated in bp */
+};
+
+#endif
+