./usr/sbin/log minix-sys
./usr/sbin/lwip minix-sys
./usr/sbin/memory minix-sys
+./usr/sbin/mkfs.mfs3 minix-sys
./usr/sbin/mkproto minix-sys
./usr/sbin/mmc minix-sys
./usr/sbin/mtree minix-sys
isodir.1 isoinfo.1 isoread.1 \
last.1 loadfont.1 loadkeys.1 logger.1 \
look.1 lp.1 lspci.1 mail.1 \
- mesg.1 mixer.1 mkfs.mfs.1 \
+ mesg.1 mixer.1 \
mkproto.1 mount.1 mt.1 nice.1 nm.1 nohup.1 od.1 \
paste.1 ping.1 playwave.1 pr.1 prep.1 \
profile.1 ps.1 rcp.1 recwave.1 \
MLINKS += ash.1 wait.1
MLINKS += compress.1 uncompress.1
MLINKS += cp.1 mv.1
-MLINKS += cp.1 ln.1
MLINKS += cp.1 cpdir.1
MLINKS += svc.1 ci.1
MLINKS += svc.1 co.1
HOSTPROGNAME= ${_TOOL_PREFIX}mkfs.mfs
-HOST_SRCDIR= usr.sbin/mkfs.mfs
+HOST_SRCDIR= usr.sbin/mkfs.mfs/v3
.include "${.CURDIR}/../Makefile.host"
-PROG= mkfs.mfs
-SRCS= mkfs.c
-BINDIR= /sbin
-MAN=
-
-.if ${HOST_OSTYPE:C/\-.*//:U} == "Minix" || !defined(HOSTPROGNAME)
-LDADD+= -lminlib -lcompat_minix
+SUBDIR= v3
+.if !defined(HOSTPROGNAME)
+#SUBDIR+= v1 v2 # Original V1 and V2 file systems
+#SUBDIR+= v1l v2l # Linux-extended variants
+#SUBDIR+= mfs3v2 # V2 as handled by regular MINIX 3.x; hacky
.endif
-.include <bsd.prog.mk>
+.include <bsd.subdir.mk>
--- /dev/null
+SRCS= mkfs.c
+BINDIR?= /usr/sbin
+MAN?=
+
+.include <bsd.own.mk>
+.include "${.PARSEDIR}/../Makefile.inc"
+
+.PATH: ${.CURDIR}/..
+
+CPPFLAGS+= -I${.CURDIR}
+
+.if ${HOST_OSTYPE:C/\-.*//:U} == "Minix" || !defined(HOSTPROGNAME)
+#DPADD
+LDADD+= -lminlib -lcompat_minix
+.endif
+
+.include <bsd.prog.mk>
--- /dev/null
+PROG= mkfs.mfs3v2
+
+.include <../Makefile.mkfs>
--- /dev/null
+/* "V2" minixFS as handled by MINIX 3.x
+ *
+ * The difference with the normal V2 file systems is due to the use of
+ * the V3 declaration for the super block (struct super) and the directory
+ * entries (struct direct); this allows to use more than 65,535 inodes
+ * and filenames of up to 60 characters.
+ * A normal MINIX 2.0.x installation cannot read these file systems.
+ *
+ * The differences with a V3 file system with a block-size of 1024 are
+ * limited to the use of a different magic number, since the inodes
+ * have the same layout in both V2 and V3 file systems.
+ */
+
+/* Constants; unchanged from regular V2... */
+#include "../v2/const.h"
--- /dev/null
+/* Directory entry structure; unchanged from V3 */
+#include "../v3/mfsdir.h"
--- /dev/null
+/* Super block; unchanged from regular V3 */
+#include "../v3/super.h"
--- /dev/null
+/* Inode structure; unchanged from regular V2; V3 is identical anyway */
+#include "../v2/type.h"
--- /dev/null
+PROG= mkfs.mfsv1
+
+.include <../Makefile.mkfs>
--- /dev/null
+#ifndef _MKFS_MFS_CONST_H__
+#define _MKFS_MFS_CONST_H__
+
+/* Tables sizes */
+#define NR_DZONES 7 /* # direct zone numbers in a V1 inode */
+#define NR_TZONES 9 /* total # zone numbers in a V1 inode */
+
+/* V1 file systems are special in that zone numbers are only 16-bit */
+#define zone_t uint16_t
+
+/* Blocks are of a fixed size */
+#define MFS_STATIC_BLOCK_SIZE 1024
+
+#define SUPER_BLOCK_BYTES MFS_STATIC_BLOCK_SIZE /* 1 block */
+
+/* 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: magic number contained in super-block. */
+#define SUPER_V1 0x137F /* magic # for V1 file systems */
+#define SUPER_MAGIC SUPER_V1
+
+/* Miscellaneous constants */
+#define SU_UID ((uid_t) 0) /* super_user's uid_t */
+#define SECTOR_SIZE 512
+
+#define BOOT_BLOCK ((block_t) 0) /* block number of boot block */
+#define SUPER_BLOCK ((block_t) 1) /* block number of super block */
+#define START_BLOCK ((block_t) 2) /* first block of FS (not counting SB) */
+
+#define ROOT_INODE ((ino_t) 1) /* inode number for root directory */
+
+/* Derived sizes pertaining to the file system. */
+#define FS_BITMAP_CHUNKS(b) ((b)/usizeof(bitchunk_t)) /*# map chunks/blk*/
+#define FS_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
+#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
+
+#define ZONE_NUM_SIZE usizeof (zone_t) /* # bytes in zone */
+#define INODE_SIZE usizeof (struct inode) /* bytes in dsk ino */
+#define INODES_PER_BLOCK(b) ((b)/INODE_SIZE) /* # V2 dsk inodes/blk */
+#define INDIRECTS(b) ((b)/ZONE_NUM_SIZE) /* # zones/indir block */
+
+#define DIR_ENTRY_SIZE usizeof(struct direct) /* # bytes/dir entry */
+#define NR_DIR_ENTRIES(b) ((b)/DIR_ENTRY_SIZE) /* # dir entries/blk */
+
+#endif
--- /dev/null
+#ifndef _MKFS_MFSDIR_H
+#define _MKFS_MFSDIR_H
+
+/* Minix MFS V1/V2 on-disk directory filename. */
+#define MFS_DIRSIZ 14
+
+struct direct {
+ uint16_t d_ino;
+ char d_name[MFS_DIRSIZ];
+} __packed;
+
+#endif /* _MKFS_MFSDIR_H */
--- /dev/null
+#ifndef _MKFS_MFS_SUPER_H__
+#define _MKFS_MFS_SUPER_H__
+
+/* Super block table. 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
+ * 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
+ */
+
+struct super_block {
+ uint16_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; /* number of first data zone (small) */
+ int16_t s_log_zone_size; /* log2 of blocks/zone */
+ uint32_t s_max_size; /* maximum file size on this device */
+ int16_t s_magic; /* magic number to recognize super-blocks */
+} superblock;
+
+/* Some members have been overidden in later versions: */
+#define s_firstdatazone_old s_firstdatazone
+#define s_zones s_nzones
+
+#undef MFSFLAG_CLEAN
+#undef MFSFLAG_MANDATORY_MASK
+
+#endif
--- /dev/null
+#ifndef _MKFS_MFS_TYPE_H__
+#define _MKFS_MFS_TYPE_H__
+
+/* Declaration of the V1 inode as it is on the disk (not in core). */
+struct inode { /* V1 disk inode */
+ uint16_t i_mode; /* file type, protection, etc. */
+ uint16_t i_uid; /* user id of the file's owner. */
+ uint32_t i_size; /* current file size in bytes */
+ uint32_t i_mtime; /* when was file data last changed */
+ uint8_t i_gid; /* group number */
+ uint8_t i_nlinks; /* how many links to this file. */
+ uint16_t i_zone[NR_TZONES]; /* zone nums for direct, ind, and dbl ind */
+};
+
+/* Note: in V1 there was only one kind of timestamp kept in inodes! */
+#define MFS_INODE_ONLY_MTIME
+
+#endif
--- /dev/null
+PROG= mkfs.mfsv1l
+
+.include <../Makefile.mkfs>
--- /dev/null
+/* Extended V1 minixFS as defined by Linux
+ * The difference with the normal V1 file systems as used on MINIX are the
+ * size of the file names in the directoru entries, which are extended
+ * to 30 characters (instead of 14.)
+ */
+
+/* Constants; unchanged from regular V1... */
+#include "../v1/const.h"
+
+/* ... except for magic number contained in super-block: */
+#define SUPER_V1L 0x138F /* magic # for "Linux" extended V1 minixFS */
+#undef SUPER_MAGIC
+#define SUPER_MAGIC SUPER_V1L
--- /dev/null
+#ifndef _MKFS_MFSDIR_H
+#define _MKFS_MFSDIR_H
+
+/* Linux-extended Minix MFS V1/V2 on-disk directory entry. */
+#define MFS_DIRSIZ 30
+
+struct direct {
+ uint16_t d_ino;
+ char d_name[MFS_DIRSIZ];
+} __packed;
+
+#endif /* _MKFS_MFSDIR_H */
--- /dev/null
+/* Super block; unchanged from regular V1 */
+#include "../v1/super.h"
--- /dev/null
+/* Inode structure; unchanged from regular V1 */
+#include "../v1/type.h"
--- /dev/null
+PROG= mkfs.mfsv2
+
+.include <../Makefile.mkfs>
--- /dev/null
+#ifndef _MKFS_MFS_CONST_H__
+#define _MKFS_MFS_CONST_H__
+
+/* Tables sizes */
+#define NR_DZONES 7 /* # direct zone numbers in a V2 inode */
+#define NR_TZONES 10 /* total # zone numbers in a V2 inode */
+
+/* Blocks are of a fixed size */
+#define MFS_STATIC_BLOCK_SIZE 1024
+
+#define SUPER_BLOCK_BYTES MFS_STATIC_BLOCK_SIZE /* 1 block */
+
+/* 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: magic number contained in super-block. */
+#define SUPER_V2 0x2468 /* magic # for V2 file systems */
+#define SUPER_MAGIC SUPER_V2
+
+/* Miscellaneous constants */
+#define SU_UID ((uid_t) 0) /* super_user's uid_t */
+#define SECTOR_SIZE 512
+
+#define BOOT_BLOCK ((block_t) 0) /* block number of boot block */
+#define SUPER_BLOCK ((block_t) 1) /* block number of super block */
+#define START_BLOCK ((block_t) 2) /* first block of FS (not counting SB) */
+
+#define ROOT_INODE ((ino_t) 1) /* inode number for root directory */
+
+/* Derived sizes pertaining to the file system. */
+#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)
+
+#define ZONE_NUM_SIZE usizeof (zone_t) /* # bytes in zone */
+#define INODE_SIZE usizeof (struct inode) /* bytes in dsk ino */
+#define INODES_PER_BLOCK(b) ((b)/INODE_SIZE) /* # V2 dsk inodes/blk */
+#define INDIRECTS(b) ((b)/ZONE_NUM_SIZE) /* # zones/indir block */
+
+#define DIR_ENTRY_SIZE usizeof(struct direct) /* # bytes/dir entry */
+#define NR_DIR_ENTRIES(b) ((b)/DIR_ENTRY_SIZE) /* # dir entries/blk */
+#endif
--- /dev/null
+#ifndef _MKFS_MFSDIR_H
+#define _MKFS_MFSDIR_H
+
+/* Minix MFS V1/V2 on-disk directory filename. */
+#define MFS_DIRSIZ 14
+
+struct direct {
+ uint16_t d_ino;
+ char d_name[MFS_DIRSIZ];
+} __packed;
+
+#endif /* _MKFS_MFSDIR_H */
--- /dev/null
+#ifndef _MKFS_MFS_SUPER_H__
+#define _MKFS_MFS_SUPER_H__
+
+/* Super block table. 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
+ * 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
+ */
+
+struct super_block {
+ uint16_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; /* number of first data zone (small) */
+ int16_t s_log_zone_size; /* log2 of blocks/zone */
+ uint32_t s_max_size; /* maximum file size on this device */
+ int16_t s_magic; /* magic number to recognize super-blocks */
+ int16_t s_pad; /* try to avoid compiler-dependent padding */
+ uint32_t s_zones; /* number of zones (replaces s_nzones in V2) */
+} superblock;
+
+#define s_firstdatazone_old s_firstdatazone
+
+#undef MFSFLAG_CLEAN
+#undef MFSFLAG_MANDATORY_MASK
+
+#endif
--- /dev/null
+#ifndef _MKFS_MFS_TYPE_H__
+#define _MKFS_MFS_TYPE_H__
+
+/* Declaration of the V2/V3 inode as it is on the disk (not in core). */
+struct inode { /* V2/V3 disk inode */
+ uint16_t i_mode; /* file type, protection, etc. */
+ uint16_t i_nlinks; /* how many links to this file. */
+ uint16_t i_uid; /* user id of the file's owner. */
+ uint16_t i_gid; /* group number */
+ uint32_t i_size; /* current file size in bytes */
+ uint32_t i_atime; /* when was file data last accessed */
+ uint32_t i_mtime; /* when was file data last changed */
+ uint32_t i_ctime; /* when was inode data last changed */
+ uint32_t i_zone[NR_TZONES]; /* zone nums for direct, ind, and dbl ind */
+};
+#endif
--- /dev/null
+PROG= mkfs.mfsv2l
+
+.include <../Makefile.mkfs>
--- /dev/null
+/* Extended V2 minixFS as defined by Linux
+ * The difference with the normal V2 file systems as used on MINIX are the
+ * size of the file names in the directoru entries, which are extended
+ * to 30 characters (instead of 14.)
+ */
+
+/* Constants; unchanged from regular V2... */
+#include "../v2/const.h"
+
+/* ... except for magic number contained in super-block: */
+#define SUPER_V2L 0x2478 /* magic # for "Linux" extended V2 minixFS */
+#undef SUPER_MAGIC
+#define SUPER_MAGIC SUPER_V2L
--- /dev/null
+/* Directory entry structure; unchanged from V1L */
+#include "../v1l/mfsdir.h"
--- /dev/null
+/* Super block; unchanged from regular V2 */
+#include "../v2/super.h"
--- /dev/null
+/* Inode structure; unchanged from regular V2 */
+#include "../v2/type.h"
--- /dev/null
+PROG= mkfs.mfs
+BINDIR= /sbin
+# XXX consider section 8
+MAN= mkfs.mfs.1
+
+.ifndef HOSTPROGNAME
+SYMLINKS+= $(BINDIR)/$(PROG) /usr/sbin/mkfs.mfs3
+.endif
+
+.include <../Makefile.mkfs>
-.TH MKFS 1
-.SH NAME
-mkfs \- make a file system
-.SH SYNOPSIS
-\fBmkfs \fR[\fB\-Ldot\fR] [\fB\-B \fIblocksize\fR] [\fB\-i \fIinodes\fR] [\fB\-b \fIblocks\fR] \fIspecial \fIprototype\fR
-.br
-.de FL
-.TP
-\\fB\\$1\\fR
-\\$2
-..
-.de EX
-.TP 20
-\\fB\\$1\\fR
-# \\$2
-..
-.SH OPTIONS
-.TP 5
-.B \-L
-# Make a listing on standard output
-.TP 5
-.B \-d
-# Use mod time of \fImkfs\fR binary for all files
-.TP 5
-.B \-o
-# Use a drive other than 0 or 1 (safety precaution)
-.TP 5
-.B \-t
-# Do not test if file system fits on the medium
-.TP 5
-.B \-1
-# Make a version 1 file system (for backward compatibility)
-.TP 5
-.B \-i
-# Number of i-nodes (files)
-.TP 5
-.B \-B
-# Filesystem block size (in bytes)
-.TP 5
-.B \-b
-# Filesystem size (in blocks)
-.TP 5
-.B \-x
-# Extra space after dynamic sizing (blocks and inodes)
-.SH EXAMPLES
-.TP 20
-.B mkfs /dev/fd1 proto
-# Make a file system on \fI/dev/fd1\fR
-.TP 20
-.B mkfs -b 360 /dev/fd1
-# Make empty 360 block file system
-.TP 20
-.B mkfs /dev/fd1 360
-# Alternate way to specify the size
-.SH DESCRIPTION
-.PP
-.I Mkfs
+.Dd April 28, 2013
+.Dt MKFS.MFS 1
+.Os MINIX 3
+.Sh NAME
+.Nm mkfs.mfs
+.Nd make a file system
+.Sh SYNOPSIS
+.Nm
+.Op Fl ldtv
+.Op Fl B Ar blocksize
+.Op Fl i Ar inodes
+.Op Fl b Ar blocks
+.Op Fl z Ar zone_shift
+.Op Fl x Ar extra_space
+.Ar special
+.Op Ar prototype
+.Sh OPTIONS
+The following options are available:
+.Bl -tag -width indent
+.It Fl l
+Make a listing on standard output
+.It Fl d
+Use mod time of
+.Nm
+binary for all files
+.It Fl t
+Do not test if file system fits on the medium
+.It Fl v
+Be verbose on standard error stream; more
+.It Fl v
+options add to verbosity
+.It Fl i Ar inodes
+Number of i-nodes (files)
+.It Fl B Ar blocksize
+Filesystem block size (in bytes)
+.It Fl b Ar blocks
+Filesystem size (in blocks)
+.It Fl x Ar extra_space
+Extra space after dynamic sizing (blocks and inodes)
+.It Fl z Ar zone_shift
+Logarithm of the size of a zone with respect to a zone.
+With the default value of 0 zones are of the same size as blocks;
+with 1, each zone is made of two blocks; etc.
+.El
+.Sh EXAMPLES
+.Bl -enum
+.It
+Make a file system on
+.Pa /dev/ram1
+.Bd
+.Nm
+.Cm /dev/ram1 proto
+.Ed
+.It
+Make empty 300,000-block file system
+.Bd
+.Nm
+.Cm -b 300000 /dev/c0d0p0s0
+.Ed
+.It
+Alternate way to specify the size
+.Bd
+.Nm
+.Cm /dev/c0d0p0s0 300000
+.Ed
+.El
+.Sh DESCRIPTION
+The
+.Nm
builds a file system and copies specified files to it.
The prototype file tells which directories and files to copy to it.
If the prototype file cannot be opened, and its name is just a string of
A sample prototype file follows.
The text following the \fI#\fR sign in the example below is comment.
In real prototype files, comments are not allowed.
-.PP
-.nf
-.ta 0.20i 0.70i 1.10i 3i 3.5i 4i
+.Bd -literal
boot # boot block file (ignored)
360 63 # blocks and i-nodes
d--755 1 1 # root directory
$ # \fI/user/ast\fP is empty
$ # end of \fI/user\fP
$ # end of root directory
-.PP
-.fi
+.Ed
+.Pp
The first entry on each line (except the first 3 and the $ lines, which
terminate directories) is the name the file or directory will get on the
new file system.
Next comes its mode, with the first character being
-\fB\-dbcs\fR for regular files, directories, block special files and character
-special files, symlinks, respectively.
+.Cm -dbcs
+for regular files, directories, block special files, character
+special files, and symlinks, respectively.
The next two characters are used to specify the SETUID and SETGID bits, as
shown above.
The last three characters of the mode are the
-.I rwx
-protection bits.
-.PP
+.Cm rwx
+protection bits, in octal notation.
+.Pp
Following the mode are the uid and gid.
For special files, the major and minor devices are needed.
-.PP
-The maximum size of a file system is 1 Gb for a version 2 file system,
-and 64 Mb for a version 1 file system. Alas the 8086
-.I fsck
-runs out of memory on a V2 file system larger than 128 Mb, so for the 8086
-version of
-\s-1MINIX 3\s-1
-you have to limit yourself to file systems of that size.
-.SH "SEE ALSO"
-.BR mkproto (1),
-.BR fsck (1),
-.BR mount (1).
+.Sh "SEE ALSO"
+.Xr mkproto 1 ,
+.Xr fsck.mfs 1 ,
+.Xr mount 1 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Andy Tanenbaum, Paul Ogilvie, Frans Meulenbroeks, Bruce Evans
\ No newline at end of file