Make mkfs.mfs cross compilable
This commit is contained in:
parent
a82a56d788
commit
bb226763a0
10 changed files with 510 additions and 92 deletions
|
@ -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 \
|
||||
|
|
|
@ -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
5
tools/mkfs.mfs/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
HOSTPROGNAME= ${_TOOL_PREFIX}mkfs.mfs
|
||||
HOST_SRCDIR= usr.sbin/mkfs.mfs
|
||||
|
||||
LDADD= #defined
|
||||
.include "${.CURDIR}/../Makefile.host"
|
|
@ -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>
|
||||
|
|
|
@ -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
107
usr.sbin/mkfs.mfs/const.h
Normal 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
|
||||
|
21
usr.sbin/mkfs.mfs/mfsdir.h
Normal file
21
usr.sbin/mkfs.mfs/mfsdir.h
Normal 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 */
|
|
@ -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
83
usr.sbin/mkfs.mfs/super.h
Normal 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
44
usr.sbin/mkfs.mfs/type.h
Normal 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
|
||||
|
Loading…
Reference in a new issue