Make mkfs.mfs cross compilable

This commit is contained in:
Thomas Veerman 2012-06-12 20:45:29 +02:00 committed by Thomas Veerman
parent a82a56d788
commit bb226763a0
10 changed files with 510 additions and 92 deletions

View 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 \

View 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 \

5
tools/mkfs.mfs/Makefile Normal file
View file

@ -0,0 +1,5 @@
HOSTPROGNAME= ${_TOOL_PREFIX}mkfs.mfs
HOST_SRCDIR= usr.sbin/mkfs.mfs
LDADD= #defined
.include "${.CURDIR}/../Makefile.host"

View 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>

View 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>

107
usr.sbin/mkfs.mfs/const.h Normal file
View file

@ -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

View file

@ -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 */

View file

@ -20,27 +20,21 @@
#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);
}
}
}

83
usr.sbin/mkfs.mfs/super.h Normal file
View file

@ -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

44
usr.sbin/mkfs.mfs/type.h Normal file
View file

@ -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