summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.CVS7
-rw-r--r--bsdfsck/fsck.h2
-rw-r--r--bsdfsck/preen.c2
-rw-r--r--bsdfsck/utilities.c2
-rwxr-xr-xconfigure163
-rw-r--r--configure.in7
-rw-r--r--serverboot/Makefile53
-rw-r--r--serverboot/assert.h50
-rw-r--r--serverboot/bootstrap.c438
-rw-r--r--serverboot/bunzip2.c169
-rw-r--r--serverboot/def_pager_setup.c152
-rw-r--r--serverboot/default_pager.c3921
-rw-r--r--serverboot/defs.h95
-rw-r--r--serverboot/dir.h142
-rw-r--r--serverboot/disk_inode.h101
-rw-r--r--serverboot/disk_inode_ffs.h99
-rw-r--r--serverboot/elf-load.c143
-rw-r--r--serverboot/exec.c147
-rw-r--r--serverboot/ext2_file_io.c983
-rw-r--r--serverboot/ffs_compat.c65
-rw-r--r--serverboot/ffs_compat.h54
-rw-r--r--serverboot/ffs_file_io.c969
-rw-r--r--serverboot/file_io.c317
-rw-r--r--serverboot/file_io.h200
-rw-r--r--serverboot/fs.h455
-rw-r--r--serverboot/gets.c90
-rw-r--r--serverboot/gunzip.c188
-rw-r--r--serverboot/kalloc.c291
-rw-r--r--serverboot/load.c555
-rw-r--r--serverboot/mach-exec.h130
-rw-r--r--serverboot/minix_ffs_compat.c62
-rw-r--r--serverboot/minix_ffs_compat.h43
-rw-r--r--serverboot/minix_file_io.c851
-rw-r--r--serverboot/minix_fs.h107
-rw-r--r--serverboot/minix_super.h49
-rw-r--r--serverboot/panic.c58
-rw-r--r--serverboot/queue.h316
-rw-r--r--serverboot/strfcns.c74
-rw-r--r--serverboot/wiring.c175
-rw-r--r--serverboot/wiring.h35
-rw-r--r--ufs-fsck/utilities.c2
-rw-r--r--ufs/Makefile2
-rw-r--r--ufs/alloc.c6
-rw-r--r--ufs/dir.c2
-rw-r--r--ufs/inode.c2
-rw-r--r--ufs/ufs.h34
-rw-r--r--ufs/xinl.c2
47 files changed, 174 insertions, 11636 deletions
diff --git a/README.CVS b/README.CVS
index 781acdeb..92a2392d 100644
--- a/README.CVS
+++ b/README.CVS
@@ -17,6 +17,13 @@ GNU Mach at least 1.3
GNU C library CVS from 2004-03-09 or later
GNU C compiler at least 3.3.2
+Optionally, a Sun RPC implementation is needed to build the NFS
+translator and daemon:
+
+GNU C library at most 2.13
+TI-RPC (currently fails to build on GNU, see
+ <http://lists.debian.org/debian-hurd/2010/12/msg00007.html>.)
+
Obviously, you also need somewhat recent versions of binutils, make,
bash and some other tools. No hard requirements are currently known
for these, though.
diff --git a/bsdfsck/fsck.h b/bsdfsck/fsck.h
index c418f66c..04bb7698 100644
--- a/bsdfsck/fsck.h
+++ b/bsdfsck/fsck.h
@@ -209,7 +209,7 @@ struct inodesc {
* To check if a block has been found as a duplicate it is only
* necessary to search from duplist through muldup. To find the
* total number of times that a block has been found as a duplicate
- * the entire list must be searched for occurences of the block
+ * the entire list must be searched for occurrences of the block
* in question. The following diagram shows a sample list where
* w (found twice), x (found once), y (found three times), and z
* (found once) are duplicate block numbers:
diff --git a/bsdfsck/preen.c b/bsdfsck/preen.c
index 7893a5e1..5650f900 100644
--- a/bsdfsck/preen.c
+++ b/bsdfsck/preen.c
@@ -51,7 +51,7 @@ struct part {
struct part *next; /* forward link of partitions on disk */
char *name; /* device name */
char *fsname; /* mounted filesystem name */
- long auxdata; /* auxillary data for application */
+ long auxdata; /* auxiliary data for application */
} *badlist, **badnext = &badlist;
struct disk {
diff --git a/bsdfsck/utilities.c b/bsdfsck/utilities.c
index 2141e7f8..1c281b1b 100644
--- a/bsdfsck/utilities.c
+++ b/bsdfsck/utilities.c
@@ -520,7 +520,7 @@ errexit(s1, s2, s3, s4)
}
/*
- * An unexpected inconsistency occured.
+ * An unexpected inconsistency occurred.
* Die if preening, otherwise just print message and continue.
*/
/* VARARGS1 */
diff --git a/configure b/configure
index db1574fb..1fab7980 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,9 @@
#! /bin/sh
# From configure.in Id: configure.in,v 1.38 2008/11/17 11:34:18 tschwinge Exp .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67.
+# Generated by GNU Autoconf 2.67 for GNU Hurd 0.3.
+#
+# Report bugs to <bug-hurd@gnu.org>.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -229,10 +231,11 @@ fi
$as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
- $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and bug-hurd@gnu.org
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
fi
exit 1
fi
@@ -548,12 +551,12 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-PACKAGE_URL=
+PACKAGE_NAME='GNU Hurd'
+PACKAGE_TARNAME='hurd'
+PACKAGE_VERSION='0.3'
+PACKAGE_STRING='GNU Hurd 0.3'
+PACKAGE_BUGREPORT='bug-hurd@gnu.org'
+PACKAGE_URL='http://www.gnu.org/software/hurd/'
ac_unique_file="hurd/hurd_types.h"
ac_default_prefix=
@@ -595,6 +598,7 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
+HAVE_SUN_RPC
LIBNCURSESW
NCURSESW_INCLUDE
boot_store_types
@@ -729,7 +733,7 @@ sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
@@ -1231,7 +1235,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures GNU Hurd 0.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1279,7 +1283,7 @@ Fine tuning of the installation directories:
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/hurd]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1295,7 +1299,9 @@ _ACEOF
fi
if test -n "$ac_init_help"; then
-
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of GNU Hurd 0.3:";;
+ esac
cat <<\_ACEOF
Optional Features:
@@ -1336,7 +1342,9 @@ Some influential environment variables:
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
-Report bugs to the package provider.
+Report bugs to <bug-hurd@gnu.org>.
+GNU Hurd home page: <http://www.gnu.org/software/hurd/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>.
_ACEOF
ac_status=$?
fi
@@ -1399,7 +1407,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-configure
+GNU Hurd configure 0.3
generated by GNU Autoconf 2.67
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1671,6 +1679,10 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------- ##
+## Report this to bug-hurd@gnu.org ##
+## ------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
@@ -1764,7 +1776,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by $as_me, which was
+It was created by GNU Hurd $as_me 0.3, which was
generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@
@@ -2023,7 +2035,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;}
|| { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
done
@@ -2165,7 +2177,7 @@ fi
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
@@ -2198,7 +2210,7 @@ fi
$as_echo "$ac_cv_host" >&6; }
case $ac_cv_host in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
esac
host=$ac_cv_host
ac_save_IFS=$IFS; IFS='-'
@@ -2219,12 +2231,12 @@ gnu*) ;;
none) as_fn_error $? "
*** You must specify a host of $host_cpu-gnu or $host_cpu-$host_vendor-gnu
*** to configure; you will need to use the same host specification
-*** to configure other packages for the GNU/Hurd system." "$LINENO" 5 ;;
+*** to configure other packages for the GNU/Hurd system." "$LINENO" 5 ;;
*) as_fn_error $? "this is the gnu os, host cannot be $host_os
*** Host configuration must be \`MACHINE-gnu' or \`MACHINE-VENDOR-gnu'.
*** To cross-compile, you must specify both --host and --build;
*** for example \`--build=$host --host=$host_cpu-gnu'.
-*** Run $0 --help for more information." "$LINENO" 5 ;;
+*** Run $0 --help for more information." "$LINENO" 5 ;;
esac
case "$host_cpu" in
@@ -2727,7 +2739,7 @@ fi
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -2842,7 +2854,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -2885,7 +2897,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -2944,7 +2956,7 @@ $as_echo "$ac_try_echo"; } >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
@@ -2996,7 +3008,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -4049,7 +4061,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=c
@@ -4329,7 +4341,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Please install required libraries or use --without-parted.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
@@ -4382,7 +4394,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Please install required libraries or use --without-parted.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
@@ -4434,7 +4446,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Please install required libraries or use --without-parted.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
@@ -4486,7 +4498,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Please install required libraries or use --without-parted.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
@@ -4608,6 +4620,75 @@ $as_echo "$hurd_cv_includedir_ncursesw" >&6; }
+# Check for Sun RPC headers and library.
+ac_fn_c_check_header_mongrel "$LINENO" "rpc/types.h" "ac_cv_header_rpc_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_rpc_types_h" = x""yes; then :
+ HAVE_SUN_RPC=yes
+else
+ HAVE_SUN_RPC=no
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clnt_create" >&5
+$as_echo_n "checking for library containing clnt_create... " >&6; }
+if test "${ac_cv_search_clnt_create+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clnt_create ();
+int
+main ()
+{
+return clnt_create ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' ; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_clnt_create=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_clnt_create+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_clnt_create+set}" = set; then :
+
+else
+ ac_cv_search_clnt_create=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clnt_create" >&5
+$as_echo "$ac_cv_search_clnt_create" >&6; }
+ac_res=$ac_cv_search_clnt_create
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ :
+else
+ HAVE_SUN_RPC=no
+fi
+
+
+
if test -f ./$ac_unique_file; then
# Configuring in source directory; don't create any Makefiles.
makefiles=
@@ -5164,7 +5245,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by $as_me, which was
+This file was extended by GNU Hurd $as_me 0.3, which was
generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5211,13 +5292,15 @@ Usage: $0 [OPTION]... [TAG]...
Configuration files:
$config_files
-Report bugs to the package provider."
+Report bugs to <bug-hurd@gnu.org>.
+GNU Hurd home page: <http://www.gnu.org/software/hurd/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-config.status
+GNU Hurd config.status 0.3
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
@@ -5332,7 +5415,7 @@ do
"config.make") CONFIG_FILES="$CONFIG_FILES config.make" ;;
"${makefiles}") CONFIG_FILES="$CONFIG_FILES ${makefiles}" ;;
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -5538,7 +5621,7 @@ do
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -5566,7 +5649,7 @@ do
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -5593,7 +5676,7 @@ $as_echo "$as_me: creating $ac_file" >&6;}
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
diff --git a/configure.in b/configure.in
index 978de1e2..0891aecc 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script.
AC_REVISION([$Id: configure.in,v 1.38 2008/11/17 11:34:18 tschwinge Exp $])
AC_PREREQ(2.54) dnl Minimum Autoconf version required.
-AC_INIT
+AC_INIT([GNU Hurd], [0.3], [bug-hurd@gnu.org])
AC_CONFIG_SRCDIR([hurd/hurd_types.h]) dnl File to look for in srcdir.
AC_PREFIX_DEFAULT() dnl Default to empty prefix, not /usr/local.
@@ -271,6 +271,11 @@ AC_SUBST([have_x11])
AC_SUBST([XKB_BASE])
AC_SUBST([X11_KEYSYMDEF_H])
+# Check for Sun RPC headers and library.
+AC_CHECK_HEADER([rpc/types.h], [HAVE_SUN_RPC=yes], [HAVE_SUN_RPC=no])
+AC_SEARCH_LIBS([clnt_create], [], [:], [HAVE_SUN_RPC=no])
+AC_SUBST([HAVE_SUN_RPC])
+
if test -f ./$ac_unique_file; then
# Configuring in source directory; don't create any Makefiles.
makefiles=
diff --git a/serverboot/Makefile b/serverboot/Makefile
deleted file mode 100644
index 653d5963..00000000
--- a/serverboot/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 1997,99,2001,02 Free Software Foundation, Inc.
-# This file is part of the GNU Hurd.
-#
-# The GNU Hurd is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# The GNU Hurd is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with the GNU Hurd; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-dir := serverboot
-makemode := utility
-
-SRCS = bootstrap.c ffs_compat.c load.c wiring.c \
- ffs_file_io.c minix_ffs_compat.c file_io.c \
- minix_file_io.c ext2_file_io.c strfcns.c exec.c \
- panic.c elf-load.c gunzip.c bunzip2.c
-LCLHDRS = assert.h disk_inode_ffs.h fs.h queue.h defs.h \
- minix_ffs_compat.h wiring.h dir.h ffs_compat.h minix_fs.h \
- disk_inode.h file_io.h minix_super.h mach-exec.h
-EXTRA_DIST = def_pager_setup.c default_pager.c kalloc.c
-target = serverboot
-HURDLIBS = threads
-installationdir = $(bootdir)
-
-UNZIP_OBJS = unzip.o inflate.o util.o do-bunzip2.o
-OBJS = $(subst .c,.o,$(SRCS)) \
- boot_script.o userland-boot.o \
- $(UNZIP_OBJS)
-
-include ../Makeconf
-
-vpath boot_script.c $(srcdir)/../boot
-vpath userland-boot.c $(srcdir)/../boot
-
-# Look for zip stuff
-vpath %.c $(srcdir) $(srcdir)/../exec
-
-# If SMALL_BZIP2 is defined, use relatively small memory.
-# It's crucial for serverboot, because swap is not enabled yet.
-CPPFLAGS += -I$(srcdir)/../exec -DGZIP -DBZIP2 -DSMALL_BZIP2
-
-LDFLAGS += -static
-
-# Don't even bother.
-CFLAGS := $(filter-out -Wall,$(CFLAGS))
diff --git a/serverboot/assert.h b/serverboot/assert.h
deleted file mode 100644
index 9f70aec3..00000000
--- a/serverboot/assert.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#ifndef _ASSERT_H_
-#define _ASSERT_H_
-
-#ifdef ASSERTIONS
-extern void Assert();
-
-#define assert(ex) \
- do { \
- if (!(ex)) \
- Assert(__FILE__, __LINE__); \
- } while (0)
-
-#ifdef lint
-#define assert_static(x)
-#else /* lint */
-#define assert_static(x) assert(x)
-#endif /* lint */
-
-#else /* ASSERTIONS */
-#define assert(ex)
-#define assert_static(ex)
-#endif /* ASSERTIONS */
-
-#endif /* _ASSERT_H_ */
diff --git a/serverboot/bootstrap.c b/serverboot/bootstrap.c
deleted file mode 100644
index 64f7c5eb..00000000
--- a/serverboot/bootstrap.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * Bootstrap the various built-in servers.
- */
-
-#include <mach.h>
-#include <mach/message.h>
-#include <sys/reboot.h>
-
-#include <file_io.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include "../boot/boot_script.h"
-
-#if 0
-/*
- * Use 8 Kbyte stacks instead of the default 64K.
- * Use 4 Kbyte waiting stacks instead of the default 8K.
- */
-#if defined(alpha)
-vm_size_t cthread_stack_size = 16 * 1024;
-#else
-vm_size_t cthread_stack_size = 8 * 1024;
-#endif
-#endif
-
-extern
-vm_size_t cthread_wait_stack_size;
-
-mach_port_t bootstrap_master_device_port; /* local name */
-mach_port_t bootstrap_master_host_port; /* local name */
-
-int boot_load_program();
-
-char *root_name;
-char boot_script_name[MAXPATHLEN];
-
-extern void default_pager();
-extern void default_pager_initialize();
-extern void default_pager_setup();
-
-/*
- * Convert ASCII to integer.
- */
-int atoi(str)
- register const char *str;
-{
- register int n;
- register int c;
- int is_negative = 0;
-
- n = 0;
- while (*str == ' ')
- str++;
- if (*str == '-') {
- is_negative = 1;
- str++;
- }
- while ((c = *str++) >= '0' && c <= '9') {
- n = n * 10 + (c - '0');
- }
- if (is_negative)
- n = -n;
- return (n);
-}
-
-__main ()
-{
-}
-
-static void
-boot_panic (kern_return_t err)
-{
-#define PFX "bootstrap: "
- char *err_string = boot_script_error_string (err);
- char panic_string[strlen (err_string) + sizeof (PFX)];
- strcpy (panic_string, PFX);
- strcat (panic_string, err_string);
- panic (panic_string);
-#undef PFX
-}
-
-void
-safe_gets (char *str, int maxlen)
-{
- char *c = fgets (str, maxlen, stdin);
- if (c == 0) {
- perror ("fgets");
- panic ("cannot read from console");
- }
- c = strchr (c, '\n');
- if (c)
- *c = '\0';
- printf ("\r\n");
-}
-
-printf_init (device_t master)
-{
- mach_port_t cons;
- kern_return_t rc;
- rc = device_open (master, D_READ|D_WRITE, "console", &cons);
- if (rc)
- while (1) {
- volatile int x = 0;
- (void) host_reboot(bootstrap_master_host_port, RB_DEBUGGER);
- x = x / x;
- }
- stdin = mach_open_devstream (cons, "r");
- stdout = stderr = mach_open_devstream (cons, "w");
- mach_port_deallocate (mach_task_self (), cons);
- setbuf (stdout, 0);
-}
-
-/*
- * Bootstrap task.
- * Runs in user spacep.
- *
- * Called as 'boot -switches host_port device_port root_name'
- *
- */
-main(argc, argv)
- int argc;
- char **argv;
-{
- int die = 0;
- int script_paging_file (const struct cmd *cmd, integer_t *val)
- {
- printf ("*** paging files no longer supported in boot scripts ***\n\a"
- "*** use swapon %s and/or /etc/fstab instead ***\n",
- cmd->path);
- return 0;
- }
- int script_serverboot_ctl (const struct cmd *cmd, integer_t *val)
- {
- const char *const ctl = cmd->path;
- if (!strcmp (ctl, "die"))
- die = 1;
- else
- printf ("(serverboot): Unknown control word `%s' ignored\n", ctl);
- return 0;
- }
-
- void prompt_for_root ()
- {
- static char new_root[MAXPATHLEN/2];
-
- if (!root_name)
- root_name = "UNKNOWN";
- printf ("Root device name? [%s] ", root_name);
- safe_gets(new_root, sizeof(new_root));
-
- if (new_root[0] != '\0') {
- root_name = new_root;
- (void) strbuild(boot_script_name,
- "/dev/",
- root_name,
- "/boot/servers.boot",
- (char *)0);
- }
- }
-
- register kern_return_t result;
- struct file scriptf;
-
- task_t my_task = mach_task_self();
-
- char *flag_string;
-
- boolean_t ask_boot_script = 0;
- boolean_t ask_root_name = 0;
-
- /*
- * Use 4Kbyte cthread wait stacks.
- */
- cthread_wait_stack_size = 4 * 1024;
-
- /*
- * Arg 1 is flags
- */
- if (argv[1][0] != '-')
- panic("bootstrap: no flags");
-
- flag_string = argv[1];
-
- /*
- * Parse the arguments.
- */
- if (argc >= 5)
- {
- /*
- * Arg 0 is program name
- */
-
- /*
- * Arg 2 is host port number
- */
- bootstrap_master_host_port = atoi(argv[2]);
-
- /*
- * Arg 3 is device port number
- */
- bootstrap_master_device_port = atoi(argv[3]);
-
- /*
- * Arg 4 is root name
- */
- root_name = argv[4];
- }
- else if (argc == 3)
- {
- root_name = argv[2];
-
- get_privileged_ports (&bootstrap_master_host_port,
- &bootstrap_master_device_port);
- }
-
- printf_init(bootstrap_master_device_port);
-#ifdef pleasenoXXX
- panic_init(bootstrap_master_host_port);
-#endif
-
-
- /*
- * If the '-a' (ask) switch was specified, or if no
- * root device was specificed, ask for the root device.
- */
-
- if (!root_name || root_name [0] == '\0' || index(flag_string, 'a'))
- prompt_for_root ();
-
- (void) strbuild(boot_script_name,
- "/dev/",
- root_name,
- "/boot/servers.boot",
- (char *)0);
- /*
- * If the '-q' (query) switch was specified, ask for the
- * server boot script.
- */
-
- if (index(flag_string, 'q'))
- ask_boot_script = TRUE;
-
- while (TRUE) {
- if (ask_root_name)
- prompt_for_root ();
-
- if (ask_boot_script) {
- char new_boot_script[MAXPATHLEN];
-
- printf("Server boot script? [%s] ", boot_script_name);
- safe_gets(new_boot_script, sizeof(new_boot_script));
- if (new_boot_script[0] != '\0')
- strcpy(boot_script_name, new_boot_script);
- }
-
- result = open_file(bootstrap_master_device_port,
- boot_script_name,
- &scriptf);
- if (result == D_NO_SUCH_DEVICE)
- {
- printf ("Root device `%s' does not exist!\n", root_name);
- ask_root_name = ask_boot_script = TRUE;
- continue;
- }
- else
- ask_root_name = FALSE;
- if (result != 0) {
- printf("Can't open server boot script %s: %s\n",
- boot_script_name,
- strerror (result));
- ask_boot_script = TRUE;
- continue;
- }
- break;
- }
-
- /*
- * If the server boot script name was changed,
- * then use the new device name as the root device.
- */
- {
- char *dev, *end;
- int len;
-
- dev = boot_script_name;
- if (strncmp(dev, "/dev/", 5) == 0)
- dev += 5;
- end = strchr(dev, '/');
- len = end ? end-dev : strlen(dev);
- memcpy(root_name, dev, len);
- root_name[len] = 0;
- }
-
- {
- char *cmdline;
-
- /* Initialize boot script variables. */
- if (boot_script_set_variable ("host-port", VAL_PORT,
- (integer_t) bootstrap_master_host_port)
- || boot_script_set_variable ("device-port", VAL_PORT,
- (integer_t) bootstrap_master_device_port)
- || boot_script_set_variable ("root-device", VAL_STR,
- (integer_t) root_name)
- || boot_script_set_variable ("boot-args", VAL_STR,
- (integer_t) flag_string)
- || boot_script_define_function ("add-paging-file", VAL_NONE,
- &script_paging_file)
- || boot_script_define_function ("add-raw-paging-file", VAL_NONE,
- &script_paging_file)
- || boot_script_define_function ("add-linux-paging-file",
- VAL_NONE,
- &script_paging_file)
- || boot_script_define_function ("serverboot",
- VAL_NONE,
- &script_serverboot_ctl)
- )
- panic ("bootstrap: error setting boot script variables");
-
- cmdline = getenv ("MULTIBOOT_CMDLINE");
- if (cmdline != NULL
- && boot_script_set_variable ("kernel-command-line",
- VAL_STR,
- (integer_t) cmdline))
- panic ("bootstrap: error setting boot script variables");
-
- parse_script (&scriptf);
- close_file (&scriptf);
- }
-
- if (index (flag_string, 'd'))
- {
- char xx[5];
- printf ("Hit return to boot...");
- safe_gets (xx, sizeof xx);
- }
-
- result = boot_script_exec ();
-
- if (result)
- boot_panic (result);
-
-#if 0
- {
- /*
- * Delete the old stack (containing only the arguments).
- */
- vm_offset_t addr = (vm_offset_t) argv;
-
- vm_offset_t r_addr;
- vm_size_t r_size;
- vm_prot_t r_protection, r_max_protection;
- vm_inherit_t r_inheritance;
- boolean_t r_is_shared;
- memory_object_name_t r_object_name;
- vm_offset_t r_offset;
- kern_return_t kr;
-
- r_addr = addr;
-
- kr = vm_region(my_task,
- &r_addr,
- &r_size,
- &r_protection,
- &r_max_protection,
- &r_inheritance,
- &r_is_shared,
- &r_object_name,
- &r_offset);
- if ((kr == KERN_SUCCESS) && MACH_PORT_VALID(r_object_name))
- (void) mach_port_deallocate(my_task, r_object_name);
- if ((kr == KERN_SUCCESS) &&
- (r_addr <= addr) &&
- ((r_protection & (VM_PROT_READ|VM_PROT_WRITE)) ==
- (VM_PROT_READ|VM_PROT_WRITE)))
- (void) vm_deallocate(my_task, r_addr, r_size);
- }
-#endif
-
- printf ("(serverboot): terminating\n");
- while (1)
- task_terminate (mach_task_self ());
- /*NOTREACHED*/
-}
-
-/* Parse the boot script. */
-parse_script (struct file *f)
-{
- char *p, *line, *buf;
- int amt, fd, err;
- int n = 0;
-
- buf = malloc (f->f_size + 1); /* add one for null terminator we will write */
- err = read_file (f, 0, buf, f->f_size, 0);
- if (err)
- panic ("bootstrap: error reading boot script file: %s", strerror (err));
-
- line = p = buf;
- while (1)
- {
- while (p < buf + f->f_size && *p != '\n')
- p++;
- *p = '\0';
- err = boot_script_parse_line (0, line);
- if (err)
- boot_panic (err);
- if (p == buf + f->f_size)
- break;
- line = ++p;
- }
- free (buf);
-}
diff --git a/serverboot/bunzip2.c b/serverboot/bunzip2.c
deleted file mode 100644
index 9f79ade5..00000000
--- a/serverboot/bunzip2.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Modified by okuji@kuicr.kyoto-u.ac.jp for use in serverboot. */
-/* Decompressing store backend
-
- Copyright (C) 1997 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include <stdio.h>
-#include <string.h>
-#include <setjmp.h>
-#include <cthreads.h>
-#include <errno.h>
-
-#include <file_io.h>
-
-#define IN_BUFFERING (256*1024)
-#define OUT_BUFFERING (512*1024)
-
-static struct mutex bunzip2_lock = MUTEX_INITIALIZER;
-
-/* Uncompress the contents of FROM, which should contain a valid bzip2 file,
- into memory, returning the result buffer in BUF & BUF_LEN. */
-int
-serverboot_bunzip2 (struct file *from, void **buf, size_t *buf_len)
-{
- /* Callbacks from do_bunzip2 for I/O and error interface. */
- extern int (*unzip_read) (char *buf, size_t maxread);
- extern void (*unzip_write) (const char *buf, size_t nwrite);
- extern void (*unzip_read_error) (void);
- extern void (*unzip_error) (const char *msg);
-
- /* How we return errors from our hook functions. */
- jmp_buf zerr_jmp_buf;
- int zerr;
-
- size_t offset = 0; /* Offset of read point in FROM. */
-
- /* Read at most MAXREAD (or 0 if eof) bytes into BUF from our current
- position in FROM. */
- int zread (char *buf, size_t maxread)
- {
- vm_size_t resid;
- size_t did_read;
-
- if (from->f_size - offset < maxread)
- did_read = from->f_size - offset;
- else
- did_read = maxread;
-
- zerr = read_file (from, offset, buf, did_read, &resid);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- did_read -= resid;
- offset += did_read;
-
- return did_read;
- }
-
- size_t out_buf_offs = 0; /* Position in the output buffer. */
-
- /* Write uncompress data to our output buffer. */
- void zwrite (const char *wbuf, size_t nwrite)
- {
- size_t old_buf_len = *buf_len;
-
- if (out_buf_offs + nwrite > old_buf_len)
- /* Have to grow the output buffer. */
- {
- void *old_buf = *buf;
- void *new_buf = old_buf + old_buf_len; /* First try. */
- size_t new_buf_len = round_page (old_buf_len + old_buf_len + nwrite);
-
- /* Try to grow the buffer. */
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len - old_buf_len,
- 0);
- if (zerr)
- /* Can't do that, try to make a bigger buffer elsewhere. */
- {
- new_buf = old_buf;
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len, 1);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- if (out_buf_offs > 0)
- /* Copy the old buffer into the start of the new & free it. */
- bcopy (old_buf, new_buf, out_buf_offs);
-
- vm_deallocate (mach_task_self (),
- (vm_address_t)old_buf, old_buf_len);
-
- *buf = new_buf;
- }
-
- *buf_len = new_buf_len;
- }
-
- bcopy (wbuf, *buf + out_buf_offs, nwrite);
- out_buf_offs += nwrite;
- }
-
- void zreaderr (void)
- {
- zerr = EIO;
- longjmp (zerr_jmp_buf, 1);
- }
- void zerror (const char *msg)
- {
- zerr = EINVAL;
- longjmp (zerr_jmp_buf, 2);
- }
-
- /* Try to guess a reasonable output buffer size. */
- *buf_len = round_page (from->f_size * 2);
- zerr = vm_allocate (mach_task_self (), (vm_address_t *)buf, *buf_len, 1);
- if (zerr)
- return zerr;
-
- mutex_lock (&bunzip2_lock);
-
- unzip_read = zread;
- unzip_write = zwrite;
- unzip_read_error = zreaderr;
- unzip_error = zerror;
-
- if (! setjmp (zerr_jmp_buf))
- {
- /* Call the bunzip2 engine. */
- do_bunzip2 ();
- zerr = 0;
- }
-
- mutex_unlock (&bunzip2_lock);
-
- if (zerr)
- {
- if (*buf_len > 0)
- vm_deallocate (mach_task_self (), (vm_address_t)*buf, *buf_len);
- }
- else if (out_buf_offs < *buf_len)
- /* Trim the output buffer to be the right length. */
- {
- size_t end = round_page (out_buf_offs);
- if (end < *buf_len)
- vm_deallocate (mach_task_self (),
- (vm_address_t)(*buf + end), *buf_len - end);
- *buf_len = out_buf_offs;
- }
-
- return zerr;
-}
diff --git a/serverboot/def_pager_setup.c b/serverboot/def_pager_setup.c
deleted file mode 100644
index 5e2073ec..00000000
--- a/serverboot/def_pager_setup.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-#include <mach.h>
-#include <mach/mig_errors.h>
-#include <mach/default_pager_types.h>
-
-#include <file_io.h>
-
-extern void *kalloc();
-
-/*
- * Create a paging partition given a file name
- */
-extern void create_paging_partition();
-
-kern_return_t
-add_paging_file(master_device_port, file_name, linux_signature)
- mach_port_t master_device_port;
- char *file_name;
- int linux_signature;
-{
- register struct file_direct *fdp;
- register kern_return_t result;
- struct file pfile;
- boolean_t isa_file;
-
- bzero((char *) &pfile, sizeof(struct file));
-
- result = open_file(master_device_port, file_name, &pfile);
- if (result != KERN_SUCCESS)
- return result;
-
- fdp = (struct file_direct *) kalloc(sizeof *fdp);
- bzero((char *) fdp, sizeof *fdp);
-
- isa_file = file_is_structured(&pfile);
-
- result = open_file_direct(pfile.f_dev, fdp, isa_file);
- if (result)
- panic("Can't open paging file %s: %s\n",
- file_name, strerror (result));
-
- result = add_file_direct(fdp, &pfile);
- if (result)
- panic("Can't read disk addresses: %s\n", strerror (result));
-
- close_file(&pfile);
-
- /*
- * Set up the default paging partition
- */
- create_paging_partition(file_name, fdp, isa_file, linux_signature);
-
- return result;
-}
-
-/*
- * Destroy a paging_partition given a file name
- */
-kern_return_t
-remove_paging_file(file_name)
- char *file_name;
-{
- struct file_direct *fdp = 0;
- kern_return_t kr;
-
- kr = destroy_paging_partition(file_name, &fdp);
- if (kr == KERN_SUCCESS) {
- remove_file_direct(fdp);
- kfree(fdp, sizeof(*fdp));
- }
- return kr;
-}
-
-kern_return_t
-default_pager_paging_storage (mach_port_t pager,
- mach_port_t device,
- recnum_t *runs, mach_msg_type_number_t nrun,
- default_pager_filename_t name,
- boolean_t add)
-{
- return MIG_BAD_ID;
-}
-
-#if 0 /* no longer used */
-/*
- * Set up default pager
- */
-extern char *strbuild();
-
-boolean_t
-default_pager_setup(master_device_port, server_dir_name)
- mach_port_t master_device_port;
- char *server_dir_name;
-{
- register kern_return_t result;
-
- char paging_file_name[MAXPATHLEN+1];
-
- (void) strbuild(paging_file_name,
- server_dir_name,
- "/paging_file",
- (char *)0);
-
- while (TRUE) {
- result = add_paging_file(master_device_port, paging_file_name);
- if (result == KERN_SUCCESS)
- break;
- printf("Can't open paging file %s: %d\n",
- paging_file_name,
- result);
-
- bzero(paging_file_name, sizeof(paging_file_name));
- printf("Paging file name ? ");
- safe_gets(paging_file_name, sizeof(paging_file_name));
-
- if (paging_file_name[0] == 0) {
- printf("*** WARNING: running without paging area!\n");
- return FALSE;
- }
- }
-
- /*
- * Our caller will become the default pager - later
- */
-
- return TRUE;
-}
-#endif
diff --git a/serverboot/default_pager.c b/serverboot/default_pager.c
deleted file mode 100644
index 41c2768d..00000000
--- a/serverboot/default_pager.c
+++ /dev/null
@@ -1,3921 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Default pager. Pages to paging partition.
- *
- * MUST BE ABLE TO ALLOCATE WIRED-DOWN MEMORY!!!
- */
-
-#include <mach.h>
-#include <mach/message.h>
-#include <mach/notify.h>
-#include <mach/mig_errors.h>
-#include <mach/thread_switch.h>
-#include <mach/task_info.h>
-#include <mach/default_pager_types.h>
-
-#include <cthreads.h>
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <queue.h>
-#include <wiring.h>
-
-#include <assert.h>
-#include <stdio.h>
-
-#include <file_io.h>
-
-#include "default_pager_S.h"
-
-#define debug 0
-
-extern void *kalloc();
-
-static char my_name[] = "(default pager):";
-
-static struct mutex printf_lock = MUTEX_INITIALIZER;
-
-#define dprintf(f, x...) \
- ({ mutex_lock (&printf_lock); printf (f , ##x); fflush (stdout); mutex_unlock (&printf_lock); })
-#define ddprintf(f, x...) ((void)0)
-
-/*
- * parallel vs serial switch
- */
-#define PARALLEL 1
-
-#if 0
-#define CHECKSUM 1
-#endif
-
-#define USE_PRECIOUS 1
-
-#define ptoa(p) ((p)*vm_page_size)
-#define atop(a) ((a)/vm_page_size)
-
-/*
-
- */
-/*
- * Bitmap allocation.
- */
-typedef unsigned int bm_entry_t;
-#define NB_BM 32
-#define BM_MASK 0xffffffff
-
-#define howmany(a,b) (((a) + (b) - 1)/(b))
-
-/*
- * Value to indicate no block assigned
- */
-#define NO_BLOCK ((vm_offset_t)-1)
-
-/*
- * 'Partition' structure for each paging area.
- * Controls allocation of blocks within paging area.
- */
-struct part {
- struct mutex p_lock; /* for bitmap/free */
- vm_size_t total_size; /* total number of blocks */
- vm_size_t free; /* number of blocks free */
- unsigned int id; /* named lookup */
- bm_entry_t *bitmap; /* allocation map */
- boolean_t going_away; /* destroy attempt in progress */
- struct file_direct *file; /* file paged to */
-};
-typedef struct part *partition_t;
-
-struct {
- struct mutex lock;
- int n_partitions;
- partition_t *partition_list;/* array, for quick mapping */
-} all_partitions; /* list of all such */
-
-typedef unsigned char p_index_t;
-
-#define P_INDEX_INVALID ((p_index_t)-1)
-
-#define no_partition(x) ((x) == P_INDEX_INVALID)
-
-partition_t partition_of(x)
- int x;
-{
- if (x >= all_partitions.n_partitions || x < 0)
- panic("partition_of x%x", x);
- return all_partitions.partition_list[x];
-}
-
-void set_partition_of(x, p)
- int x;
- partition_t p;
-{
- if (x >= all_partitions.n_partitions || x < 0)
- panic("set_partition_of x%x", x);
- all_partitions.partition_list[x] = p;
-}
-
-/*
- * Simple mapping from (file)NAME to id
- * Saves space, filenames can be long.
- */
-unsigned int
-part_id(const unsigned char *name)
-{
- register unsigned int len, id, xorid;
-
- len = strlen(name);
- id = xorid = 0;
- while (len--) {
- xorid ^= *name;
- id += *name++;
- }
- return (id << 8) | xorid;
-}
-
-partition_init()
-{
- mutex_init(&all_partitions.lock);
- all_partitions.n_partitions = 0;
-}
-
-static partition_t
-new_partition (const char *name, struct file_direct *fdp,
- int check_linux_signature)
-{
- register partition_t part;
- register vm_size_t size, bmsize;
- vm_offset_t raddr;
- mach_msg_type_number_t rsize;
- int rc;
- unsigned int id = part_id(name);
-
- mutex_lock(&all_partitions.lock);
- {
- unsigned int i;
- for (i = 0; i < all_partitions.n_partitions; i++)
- {
- part = partition_of(i);
- if (part && part->id == id)
- {
- printf ("(default pager): Already paging to partition %s!\n",
- name);
- mutex_unlock(&all_partitions.lock);
- return 0;
- }
- }
- }
- mutex_unlock(&all_partitions.lock);
-
- size = atop(fdp->fd_size * fdp->fd_bsize);
- bmsize = howmany(size, NB_BM) * sizeof(bm_entry_t);
-
- part = (partition_t) kalloc(sizeof(struct part));
- mutex_init(&part->p_lock);
- part->total_size = size;
- part->free = size;
- part->id = id;
- part->bitmap = (bm_entry_t *)kalloc(bmsize);
- part->going_away= FALSE;
- part->file = fdp;
-
- bzero((char *)part->bitmap, bmsize);
-
- if (check_linux_signature < 0)
- {
- if (check_linux_signature != -3)
- printf("(default pager): "
- "Paging to raw partition %s (%uk paging space)\n",
- name, part->total_size * (vm_page_size / 1024));
- return part;
- }
-
-#define LINUX_PAGE_SIZE 4096 /* size of pages in Linux swap partitions */
- rc = page_read_file_direct(part->file,
- 0, LINUX_PAGE_SIZE,
- &raddr,
- &rsize);
- if (rc)
- panic("(default pager): cannot read first page of %s! rc=%#x\n",
- name, rc);
- while (rsize < LINUX_PAGE_SIZE)
- {
- /* Filesystem block size is smaller than page size,
- so we must do several reads to get the whole page. */
- vm_address_t baddr, bsize;
- rc = page_read_file_direct(part->file,
- rsize, LINUX_PAGE_SIZE-rsize,
- &baddr,
- &bsize);
- if (rc)
- panic("(default pager): "
- "cannot read first page of %s! rc=%#x at %#x\n",
- name, rc, rsize);
-
- memcpy ((char *) raddr + rsize, (void *) baddr, bsize);
- rsize += bsize;
- vm_deallocate (mach_task_self (), baddr, bsize);
- }
-
- if (!memcmp("SWAP-SPACE", (char *) raddr + LINUX_PAGE_SIZE-10, 10))
- {
- /* The partition's first page has a Linux swap signature.
- This means the beginning of the page contains a bitmap
- of good pages, and all others are bad. */
- unsigned int i, j, bad, max;
- int waste;
-
- printf("(default pager): Found Linux 2.0 swap signature in %s\n",
- name);
-
- /* The first page, and the pages corresponding to the bits
- occupied by the signature in the final 10 bytes of the page,
- are always unavailable ("bad"). */
- *(u_int32_t *)raddr &= ~(u_int32_t) 1;
- memset((char *) raddr + LINUX_PAGE_SIZE-10, 0, 10);
-
- max = LINUX_PAGE_SIZE / sizeof(u_int32_t);
- if (max > (part->total_size + 31) / 32)
- max = (part->total_size + 31) / 32;
-
- bad = 0;
- for (i = 0; i < max; ++i)
- {
- u_int32_t bm = ((u_int32_t *) raddr)[i];
- if (bm == ~(u_int32_t) 0)
- continue;
- /* There are some zero bits in this word. */
- for (j = 0; j < 32; ++j)
- if ((bm & (1 << j)) == 0)
- {
- unsigned int p = i*32 + j;
- if (p >= part->total_size)
- break;
- ++bad;
- part->bitmap[p / NB_BM] |= 1 << (p % NB_BM);
- }
- }
- part->free -= bad;
-
- --bad; /* Don't complain about first page. */
- waste = part->total_size - (8 * (LINUX_PAGE_SIZE-10));
- if (waste > 0)
- {
- /* The wasted pages were already marked "bad". */
- bad -= waste;
- if (bad > 0)
- printf("\
-(default pager): Paging to %s, %dk swap-space (%dk bad, %dk wasted at end)\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024),
- bad * (LINUX_PAGE_SIZE / 1024),
- waste * (LINUX_PAGE_SIZE / 1024));
- else
- printf("\
-(default pager): Paging to %s, %dk swap-space (%dk wasted at end)\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024),
- waste * (LINUX_PAGE_SIZE / 1024));
- }
- else if (bad > 0)
- printf("\
-(default pager): Paging to %s, %dk swap-space (excludes %dk marked bad)\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024),
- bad * (LINUX_PAGE_SIZE / 1024));
- else
- printf("\
-(default pager): Paging to %s, %dk swap-space\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024));
- }
- else if (!memcmp("SWAPSPACE2",
- (char *) raddr + LINUX_PAGE_SIZE-10, 10))
- {
- struct
- {
- u_int8_t bootbits[1024];
- u_int32_t version;
- u_int32_t last_page;
- u_int32_t nr_badpages;
- u_int32_t padding[125];
- u_int32_t badpages[1];
- } *hdr = (void *) raddr;
-
- printf("\
-(default pager): Found Linux 2.2 swap signature (v%u) in %s...",
- hdr->version, name);
-
- part->bitmap[0] |= 1; /* first page unusable */
- part->free--;
-
- switch (hdr->version)
- {
- default:
- if (check_linux_signature)
- {
- printf ("version %u unknown! SKIPPING %s!\n",
- hdr->version,
- name);
- vm_deallocate(mach_task_self(), raddr, rsize);
- kfree(part->bitmap, bmsize);
- kfree(part, sizeof *part);
- return 0;
- }
- else
- printf ("version %u unknown! IGNORING SIGNATURE PAGE!"
- " %dk swap-space\n",
- hdr->version,
- part->free * (LINUX_PAGE_SIZE / 1024));
- break;
-
- case 1:
- {
- unsigned int waste, i;
- if (hdr->last_page > part->total_size)
- {
- printf ("signature says %uk, partition has only %uk! ",
- hdr->last_page * (LINUX_PAGE_SIZE / 1024),
- part->total_size * (LINUX_PAGE_SIZE / 1024));
- waste = 0;
- }
- else
- {
- waste = part->total_size - hdr->last_page;
- part->total_size = hdr->last_page;
- part->free = part->total_size - 1;
- }
- for (i = 0; i < hdr->nr_badpages; ++i)
- {
- const u_int32_t bad = hdr->badpages[i];
- part->bitmap[bad / NB_BM] |= 1 << (bad % NB_BM);
- part->free--;
- }
- printf ("%uk swap-space",
- part->free * (LINUX_PAGE_SIZE / 1024));
- if (hdr->nr_badpages != 0)
- printf (" (excludes %uk marked bad)",
- hdr->nr_badpages * (LINUX_PAGE_SIZE / 1024));
- if (waste != 0)
- printf (" (excludes %uk at end of partition)",
- waste * (LINUX_PAGE_SIZE / 1024));
- printf ("\n");
- }
- }
- }
- else if (check_linux_signature)
- {
- printf ("(default pager): "
- "Cannot find Linux swap signature page! "
- "SKIPPING %s (%uk partition)!",
- name, part->total_size * (vm_page_size / 1024));
- kfree(part->bitmap, bmsize);
- kfree(part, sizeof *part);
- part = 0;
- }
- else
- printf("(default pager): "
- "Paging to raw partition %s (%uk paging space)\n",
- name, part->total_size * (vm_page_size / 1024));
-
- vm_deallocate(mach_task_self(), raddr, rsize);
-
- return part;
-}
-
-/*
- * Create a partition descriptor,
- * add it to the list of all such.
- * size is in BYTES.
- */
-void
-create_paging_partition(const char *name,
- struct file_direct *fdp, int isa_file,
- int linux_signature)
-{
- register partition_t part;
-
- part = new_partition (name, fdp, linux_signature);
- if (!part)
- return;
-
- mutex_lock(&all_partitions.lock);
- {
- register int i;
-
- for (i = 0; i < all_partitions.n_partitions; i++)
- if (partition_of(i) == 0) break;
-
- if (i == all_partitions.n_partitions) {
- register partition_t *new_list, *old_list;
- register int n;
-
- n = i ? (i<<1) : 2;
- new_list = (partition_t *)
- kalloc( n * sizeof(partition_t) );
- if (new_list == 0) no_paging_space(TRUE);
- bzero(new_list, n*sizeof(partition_t));
- if (i) {
- old_list = all_partitions.partition_list;
- bcopy(old_list, new_list, i*sizeof(partition_t));
- }
- all_partitions.partition_list = new_list;
- all_partitions.n_partitions = n;
- if (i) kfree(old_list, i*sizeof(partition_t));
- }
- set_partition_of(i, part);
- }
- mutex_unlock(&all_partitions.lock);
-
-#if 0
- dprintf("%s Added paging %s %s\n", my_name,
- (isa_file) ? "file" : "device", name);
-#endif
- overcommitted(TRUE, part->free);
-}
-
-/*
- * Choose the most appropriate default partition
- * for an object of SIZE bytes.
- * Return the partition locked, unless
- * the object has no CUR_PARTition.
- */
-p_index_t
-choose_partition(size, cur_part)
- unsigned int size;
- register p_index_t cur_part;
-{
- register partition_t part;
- register boolean_t found = FALSE;
- register int i;
-
- mutex_lock(&all_partitions.lock);
- for (i = 0; i < all_partitions.n_partitions; i++) {
-
- /* the undesireable one ? */
- if (i == cur_part)
- continue;
-
-ddprintf ("choose_partition(%x,%d,%d)\n",size,cur_part,i);
- /* one that was removed ? */
- if ((part = partition_of(i)) == 0)
- continue;
-
- /* one that is being removed ? */
- if (part->going_away)
- continue;
-
- /* is it big enough ? */
- mutex_lock(&part->p_lock);
- if (ptoa(part->free) >= size) {
- if (cur_part != P_INDEX_INVALID) {
- mutex_unlock(&all_partitions.lock);
- return (p_index_t)i;
- } else
- found = TRUE;
- }
- mutex_unlock(&part->p_lock);
-
- if (found) break;
- }
- mutex_unlock(&all_partitions.lock);
- return (found) ? (p_index_t)i : P_INDEX_INVALID;
-}
-
-/*
- * Allocate a page in a paging partition
- * The partition is returned unlocked.
- */
-vm_offset_t
-pager_alloc_page(pindex, lock_it)
- p_index_t pindex;
-{
- register int bm_e;
- register int bit;
- register int limit;
- register bm_entry_t *bm;
- partition_t part;
- static char here[] = "%spager_alloc_page";
-
- if (no_partition(pindex))
- return (NO_BLOCK);
-ddprintf ("pager_alloc_page(%d,%d)\n",pindex,lock_it);
- part = partition_of(pindex);
-
- /* unlikely, but possible deadlock against destroy_partition */
- if (!part || part->going_away)
- return (NO_BLOCK);
-
- if (lock_it)
- mutex_lock(&part->p_lock);
-
- if (part->free == 0) {
- /* out of paging space */
- mutex_unlock(&part->p_lock);
- return (NO_BLOCK);
- }
-
- limit = howmany(part->total_size, NB_BM);
- bm = part->bitmap;
- for (bm_e = 0; bm_e < limit; bm_e++, bm++)
- if (*bm != BM_MASK)
- break;
-
- if (bm_e == limit)
- panic(here,my_name);
-
- /*
- * Find and set the proper bit
- */
- {
- register bm_entry_t b = *bm;
-
- for (bit = 0; bit < NB_BM; bit++)
- if ((b & (1<<bit)) == 0)
- break;
- if (bit == NB_BM)
- panic(here,my_name);
-
- *bm = b | (1<<bit);
- part->free--;
-
- }
-
- mutex_unlock(&part->p_lock);
-
- return (bm_e*NB_BM+bit);
-}
-
-/*
- * Deallocate a page in a paging partition
- */
-void
-pager_dealloc_page(pindex, page, lock_it)
- p_index_t pindex;
- register vm_offset_t page;
-{
- register partition_t part;
- register int bit, bm_e;
-
- /* be paranoid */
- if (no_partition(pindex))
- panic("%sdealloc_page",my_name);
-ddprintf ("pager_dealloc_page(%d,%x,%d)\n",pindex,page,lock_it);
- part = partition_of(pindex);
-
- if (page >= part->total_size)
- panic("%sdealloc_page",my_name);
-
- bm_e = page / NB_BM;
- bit = page % NB_BM;
-
- if (lock_it)
- mutex_lock(&part->p_lock);
-
- part->bitmap[bm_e] &= ~(1<<bit);
- part->free++;
-
- if (lock_it)
- mutex_unlock(&part->p_lock);
-}
-
-/*
-
- */
-/*
- * Allocation info for each paging object.
- *
- * Most operations, even pager_write_offset and pager_put_checksum,
- * just need a read lock. Higher-level considerations prevent
- * conflicting operations on a single page. The lock really protects
- * the underlying size and block map memory, so pager_extend needs a
- * write lock.
- *
- * An object can now span multiple paging partitions. The allocation
- * info we keep is a pair (offset,p_index) where the index is in the
- * array of all partition ptrs, and the offset is partition-relative.
- * Size wise we are doing ok fitting the pair into a single integer:
- * the offset really is in pages so we have vm_page_size bits available
- * for the partition index.
- */
-#define DEBUG_READER_CONFLICTS 0
-
-#if DEBUG_READER_CONFLICTS
-int default_pager_read_conflicts = 0;
-#endif
-
-union dp_map {
-
- struct {
- unsigned int p_offset : 24,
- p_index : 8;
- } block;
-
- union dp_map *indirect;
-};
-typedef union dp_map *dp_map_t;
-
-/* quick check for part==block==invalid */
-#define no_block(e) ((e).indirect == (dp_map_t)NO_BLOCK)
-#define invalidate_block(e) ((e).indirect = (dp_map_t)NO_BLOCK)
-
-struct dpager {
- struct mutex lock; /* lock for extending block map */
- /* XXX should be read-write lock */
-#if DEBUG_READER_CONFLICTS
- int readers;
- boolean_t writer;
-#endif
- dp_map_t map; /* block map */
- vm_size_t size; /* size of paging object, in pages */
- vm_size_t limit; /* limit (bytes) allowed to grow to */
- p_index_t cur_partition;
-#ifdef CHECKSUM
- vm_offset_t *checksum; /* checksum - parallel to block map */
-#define NO_CHECKSUM ((vm_offset_t)-1)
-#endif /* CHECKSUM */
-};
-typedef struct dpager *dpager_t;
-
-/*
- * A paging object uses either a one- or a two-level map of offsets
- * into a paging partition.
- */
-#define PAGEMAP_ENTRIES 64
- /* number of pages in a second-level map */
-#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t))
-
-#define INDIRECT_PAGEMAP_ENTRIES(npgs) \
- ((((npgs)-1)/PAGEMAP_ENTRIES) + 1)
-#define INDIRECT_PAGEMAP_SIZE(npgs) \
- (INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *))
-#define INDIRECT_PAGEMAP(size) \
- (size > PAGEMAP_ENTRIES)
-
-#define ROUNDUP_TO_PAGEMAP(npgs) \
- (((npgs) + PAGEMAP_ENTRIES - 1) & ~(PAGEMAP_ENTRIES - 1))
-
-/*
- * Object sizes are rounded up to the next power of 2,
- * unless they are bigger than a given maximum size.
- */
-vm_size_t max_doubled_size = 4 * 1024 * 1024; /* 4 meg */
-
-/*
- * Attach a new paging object to a paging partition
- */
-void
-pager_alloc(pager, part, size)
- register dpager_t pager;
- p_index_t part;
- register vm_size_t size; /* in BYTES */
-{
- register int i;
- register dp_map_t mapptr, emapptr;
-
- mutex_init(&pager->lock);
-#if DEBUG_READER_CONFLICTS
- pager->readers = 0;
- pager->writer = FALSE;
-#endif
- pager->cur_partition = part;
-
- /*
- * Convert byte size to number of pages, then increase to the nearest
- * power of 2.
- */
- size = atop(size);
- if (size <= atop(max_doubled_size)) {
- i = 1;
- while (i < size)
- i <<= 1;
- size = i;
- } else
- size = ROUNDUP_TO_PAGEMAP(size);
-
- /*
- * Allocate and initialize the block map
- */
- {
- register vm_size_t alloc_size;
- dp_map_t init_value;
-
- if (INDIRECT_PAGEMAP(size)) {
- alloc_size = INDIRECT_PAGEMAP_SIZE(size);
- init_value = (dp_map_t)0;
- } else {
- alloc_size = PAGEMAP_SIZE(size);
- init_value = (dp_map_t)NO_BLOCK;
- }
-
- mapptr = (dp_map_t) kalloc(alloc_size);
- for (emapptr = &mapptr[(alloc_size-1) / sizeof(vm_offset_t)];
- emapptr >= mapptr;
- emapptr--)
- emapptr->indirect = init_value;
-
- }
- pager->map = mapptr;
- pager->size = size;
- pager->limit = (vm_size_t)-1;
-
-#ifdef CHECKSUM
- if (INDIRECT_PAGEMAP(size)) {
- mapptr = (vm_offset_t *)
- kalloc(INDIRECT_PAGEMAP_SIZE(size));
- for (i = INDIRECT_PAGEMAP_ENTRIES(size); --i >= 0;)
- mapptr[i] = 0;
- } else {
- mapptr = (vm_offset_t *) kalloc(PAGEMAP_SIZE(size));
- for (i = 0; i < size; i++)
- mapptr[i] = NO_CHECKSUM;
- }
- pager->checksum = mapptr;
-#endif /* CHECKSUM */
-}
-
-/*
- * Return size (in bytes) of space actually allocated to this pager.
- * The pager is read-locked.
- */
-
-vm_size_t
-pager_allocated(pager)
- register dpager_t pager;
-{
- vm_size_t size;
- register dp_map_t map, emap;
- vm_size_t asize;
-
- size = pager->size; /* in pages */
- asize = 0; /* allocated, in pages */
- map = pager->map;
-
- if (INDIRECT_PAGEMAP(size)) {
- for (emap = &map[INDIRECT_PAGEMAP_ENTRIES(size)];
- map < emap; map++) {
-
- register dp_map_t map2, emap2;
-
- if ((map2 = map->indirect) == 0)
- continue;
-
- for (emap2 = &map2[PAGEMAP_ENTRIES];
- map2 < emap2; map2++)
- if ( ! no_block(*map2) )
- asize++;
-
- }
- } else {
- for (emap = &map[size]; map < emap; map++)
- if ( ! no_block(*map) )
- asize++;
- }
-
- return ptoa(asize);
-}
-
-/*
- * Find offsets (in the object) of pages actually allocated to this pager.
- * Returns the number of allocated pages, whether or not they all fit.
- * The pager is read-locked.
- */
-
-unsigned int
-pager_pages(pager, pages, numpages)
- dpager_t pager;
- register default_pager_page_t *pages;
- unsigned int numpages;
-{
- vm_size_t size;
- dp_map_t map, emap;
- unsigned int actual;
- vm_offset_t offset;
-
- size = pager->size; /* in pages */
- map = pager->map;
- actual = 0;
- offset = 0;
-
- if (INDIRECT_PAGEMAP(size)) {
- for (emap = &map[INDIRECT_PAGEMAP_ENTRIES(size)];
- map < emap; map++) {
-
- register dp_map_t map2, emap2;
-
- if ((map2 = map->indirect) == 0) {
- offset += vm_page_size * PAGEMAP_ENTRIES;
- continue;
- }
- for (emap2 = &map2[PAGEMAP_ENTRIES];
- map2 < emap2; map2++)
- if ( ! no_block(*map2) ) {
- if (actual++ < numpages)
- pages++->dpp_offset = offset;
- }
- offset += vm_page_size;
- }
- } else {
- for (emap = &map[size]; map < emap; map++)
- if ( ! no_block(*map) ) {
- if (actual++ < numpages)
- pages++->dpp_offset = offset;
- }
- offset += vm_page_size;
- }
- return actual;
-}
-
-/*
- * Extend the map for a paging object.
- *
- * XXX This implementation can allocate an arbitrary large amount
- * of wired memory when extending a big block map. Because vm-privileged
- * threads call pager_extend, this can crash the system by exhausting
- * system memory.
- */
-void
-pager_extend(pager, new_size)
- register dpager_t pager;
- register vm_size_t new_size; /* in pages */
-{
- register dp_map_t new_mapptr;
- register dp_map_t old_mapptr;
- register int i;
- register vm_size_t old_size;
-
- mutex_lock(&pager->lock); /* XXX lock_write */
-#if DEBUG_READER_CONFLICTS
- pager->writer = TRUE;
-#endif
- /*
- * Double current size until we cover new size.
- * If object is 'too big' just use new size.
- */
- old_size = pager->size;
-
- if (new_size <= atop(max_doubled_size)) {
- i = old_size;
- while (i < new_size)
- i <<= 1;
- new_size = i;
- } else
- new_size = ROUNDUP_TO_PAGEMAP(new_size);
-
- if (INDIRECT_PAGEMAP(old_size)) {
- /*
- * Pager already uses two levels. Allocate
- * a larger indirect block.
- */
- new_mapptr = (dp_map_t)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- old_mapptr = pager->map;
- for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i].indirect = (dp_map_t)0;
- kfree((char *)old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
- pager->map = new_mapptr;
- pager->size = new_size;
-#ifdef CHECKSUM
- new_mapptr = (vm_offset_t *)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- old_mapptr = pager->checksum;
- for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i] = 0;
- kfree((char *)old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
- pager->checksum = new_mapptr;
-#endif /* CHECKSUM */
-#if DEBUG_READER_CONFLICTS
- pager->writer = FALSE;
-#endif
- mutex_unlock(&pager->lock);
-#if 0
- ddprintf ("pager_extend 1 mapptr %x [3b] = %x\n", new_mapptr,
- new_mapptr[0x3b]);
- if (new_mapptr[0x3b].indirect > 0x10000
- && new_mapptr[0x3b].indirect != NO_BLOCK)
- panic ("debug panic");
-#endif
- return;
- }
-
- if (INDIRECT_PAGEMAP(new_size)) {
- /*
- * Changing from direct map to indirect map.
- * Allocate both indirect and direct map blocks,
- * since second-level (direct) block must be
- * full size (PAGEMAP_SIZE(PAGEMAP_ENTRIES)).
- */
-
- /*
- * Allocate new second-level map first.
- */
- new_mapptr = (dp_map_t) kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- old_mapptr = pager->map;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < PAGEMAP_ENTRIES; i++)
- invalidate_block(new_mapptr[i]);
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- old_mapptr = new_mapptr;
-
-#if 0
- ddprintf ("pager_extend 2 mapptr %x [3b] = %x\n", new_mapptr,
- new_mapptr[0x3b]);
- if (new_mapptr[0x3b].indirect > 0x10000
- && new_mapptr[0x3b].indirect != NO_BLOCK)
- panic ("debug panic");
-#endif
-
- /*
- * Now allocate indirect map.
- */
- new_mapptr = (dp_map_t)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- new_mapptr[0].indirect = old_mapptr;
- for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i].indirect = 0;
- pager->map = new_mapptr;
- pager->size = new_size;
-#ifdef CHECKSUM
- /*
- * Allocate new second-level map first.
- */
- new_mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- old_mapptr = pager->checksum;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < PAGEMAP_ENTRIES; i++)
- new_mapptr[i] = NO_CHECKSUM;
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- old_mapptr = new_mapptr;
-
- /*
- * Now allocate indirect map.
- */
- new_mapptr = (vm_offset_t *)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- new_mapptr[0] = (vm_offset_t) old_mapptr;
- for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i] = 0;
- pager->checksum = new_mapptr;
-#endif /* CHECKSUM */
-#if DEBUG_READER_CONFLICTS
- pager->writer = FALSE;
-#endif
- mutex_unlock(&pager->lock);
- return;
- }
- /*
- * Enlarging a direct block.
- */
- new_mapptr = (dp_map_t) kalloc(PAGEMAP_SIZE(new_size));
- old_mapptr = pager->map;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < new_size; i++)
- invalidate_block(new_mapptr[i]);
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- pager->map = new_mapptr;
- pager->size = new_size;
-#ifdef CHECKSUM
- new_mapptr = (vm_offset_t *)
- kalloc(PAGEMAP_SIZE(new_size));
- old_mapptr = pager->checksum;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < new_size; i++)
- new_mapptr[i] = NO_CHECKSUM;
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- pager->checksum = new_mapptr;
-#endif /* CHECKSUM */
-#if DEBUG_READER_CONFLICTS
- pager->writer = FALSE;
-#endif
- mutex_unlock(&pager->lock);
-}
-
-/* Truncate a memory object. First, any pages between the new size
- and the (larger) old size are deallocated. Then, the size of
- the pagemap may be reduced, an indirect map may be turned into
- a direct map.
-
- The pager must be locked by the caller. */
-static void
-pager_truncate(dpager_t pager, vm_size_t new_size) /* in pages */
-{
- dp_map_t new_mapptr;
- dp_map_t old_mapptr;
- int i;
- vm_size_t old_size;
-
- /* This deallocates the pages necessary to truncate a direct map
- previously of size NEW_SIZE to the smaller size OLD_SIZE. */
- inline void dealloc_direct (dp_map_t mapptr,
- vm_size_t old_size, vm_size_t new_size)
- {
- vm_size_t i;
- for (i = new_size; i < old_size; ++i)
- {
- const union dp_map entry = mapptr[i];
- pager_dealloc_page(entry.block.p_index, entry.block.p_offset,
- TRUE);
- invalidate_block(mapptr[i]);
- }
- }
-
- old_size = pager->size;
-
- if (INDIRECT_PAGEMAP(old_size))
- {
- /* First handle the entire second-levels blocks that are being freed. */
- for (i = INDIRECT_PAGEMAP_ENTRIES(new_size);
- i < INDIRECT_PAGEMAP_ENTRIES(old_size);
- ++i)
- {
- const dp_map_t mapptr = pager->map[i].indirect;
- pager->map[i].indirect = (dp_map_t)0;
- dealloc_direct (mapptr, PAGEMAP_ENTRIES, 0);
- kfree ((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- }
-
- /* Now truncate what's now the final nonempty direct block. */
- dealloc_direct (pager->map[(new_size - 1) / PAGEMAP_ENTRIES].indirect,
- old_size & (PAGEMAP_ENTRIES - 1),
- new_size & (PAGEMAP_ENTRIES - 1));
-
- if (INDIRECT_PAGEMAP (new_size))
- {
- if (INDIRECT_PAGEMAP_SIZE (new_size) >= vm_page_size)
- /* XXX we know how kalloc.c works; avoid copying. */
- kfree ((char *) round_page ((vm_address_t) pager->map
- + INDIRECT_PAGEMAP_SIZE (new_size)),
- round_page (INDIRECT_PAGEMAP_SIZE (old_size))
- - round_page (INDIRECT_PAGEMAP_SIZE (new_size)));
- else
- {
- const dp_map_t old_mapptr = pager->map;
- pager->map = (dp_map_t) kalloc (INDIRECT_PAGEMAP_SIZE(new_size));
- memcpy (pager->map, old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
- kfree ((char *) old_mapptr, INDIRECT_PAGEMAP_SIZE (old_size));
- }
- }
- else
- {
- /* We are truncating to a size small enough that it goes to using
- a one-level map. We already have that map, as the first and only
- nonempty element in our indirect map. */
- const dp_map_t mapptr = pager->map[0].indirect;
- kfree((char *)pager->map, INDIRECT_PAGEMAP_SIZE(old_size));
- pager->map = mapptr;
- old_size = PAGEMAP_ENTRIES;
- }
- }
-
- if (new_size == 0)
- new_size = 1;
-
- if (! INDIRECT_PAGEMAP(old_size))
- {
- /* First deallocate pages in the truncated region. */
- dealloc_direct (pager->map, old_size, new_size);
- /* Now reduce the size of the direct map itself. We don't bother
- with kalloc/kfree if it's not shrinking enough that kalloc.c
- would actually use less. */
- if (PAGEMAP_SIZE (new_size) <= PAGEMAP_SIZE (old_size) / 2)
- {
- const dp_map_t old_mapptr = pager->map;
- pager->map = (dp_map_t) kalloc (PAGEMAP_SIZE (new_size));
- memcpy (pager->map, old_mapptr, PAGEMAP_SIZE (old_size));
- kfree ((char *) old_mapptr, PAGEMAP_SIZE (old_size));
- }
- }
-
- pager->size = new_size;
-
-#ifdef CHECKSUM
-#error write me
-#endif /* CHECKSUM */
-}
-
-
-/*
- * Given an offset within a paging object, find the
- * corresponding block within the paging partition.
- * Return NO_BLOCK if none allocated.
- */
-union dp_map
-pager_read_offset(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register vm_offset_t f_page;
- union dp_map pager_offset;
-
- f_page = atop(offset);
-
-#if DEBUG_READER_CONFLICTS
- if (pager->readers > 0)
- default_pager_read_conflicts++; /* would have proceeded with
- read/write lock */
-#endif
- mutex_lock(&pager->lock); /* XXX lock_read */
-#if DEBUG_READER_CONFLICTS
- pager->readers++;
-#endif
- if (f_page >= pager->size)
- {
- ddprintf ("%spager_read_offset pager %x: bad page %d >= size %d",
- my_name, pager, f_page, pager->size);
- mutex_unlock(&pager->lock);
- return (union dp_map) (union dp_map *) NO_BLOCK;
-#if 0
- panic("%spager_read_offset",my_name);
-#endif
- }
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register dp_map_t mapptr;
-
- mapptr = pager->map[f_page/PAGEMAP_ENTRIES].indirect;
- if (mapptr == 0)
- invalidate_block(pager_offset);
- else
- pager_offset = mapptr[f_page%PAGEMAP_ENTRIES];
- }
- else {
- pager_offset = pager->map[f_page];
- }
-
-#if DEBUG_READER_CONFLICTS
- pager->readers--;
-#endif
- mutex_unlock(&pager->lock);
- return (pager_offset);
-}
-
-#if USE_PRECIOUS
-/*
- * Release a single disk block.
- */
-pager_release_offset(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register union dp_map entry;
-
- offset = atop(offset);
-
- mutex_lock(&pager->lock); /* XXX lock_read */
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register dp_map_t mapptr;
-
- mapptr = pager->map[offset / PAGEMAP_ENTRIES].indirect;
- entry = mapptr[offset % PAGEMAP_ENTRIES];
- invalidate_block(mapptr[offset % PAGEMAP_ENTRIES]);
- } else {
- entry = pager->map[offset];
- invalidate_block(pager->map[offset]);
- }
-
- mutex_unlock(&pager->lock);
-
- pager_dealloc_page(entry.block.p_index, entry.block.p_offset, TRUE);
-}
-#endif /*USE_PRECIOUS*/
-
-
-/*
- * Move a page from one partition to another
- * New partition is locked, old partition is
- * locked unless LOCK_OLD sez otherwise.
- */
-union dp_map
-pager_move_page(block)
- union dp_map block;
-{
- partition_t old_part, new_part;
- p_index_t old_pindex, new_pindex;
- union dp_map ret;
- vm_size_t size;
- vm_offset_t raddr, offset, new_offset;
- kern_return_t rc;
- static char here[] = "%spager_move_page";
-
- old_pindex = block.block.p_index;
- invalidate_block(ret);
-
- /* See if we have room to put it anywhere else */
- new_pindex = choose_partition( ptoa(1), old_pindex);
- if (no_partition(new_pindex))
- return ret;
-
- /* this unlocks the new partition */
- new_offset = pager_alloc_page(new_pindex, FALSE);
- if (new_offset == NO_BLOCK)
- panic(here,my_name);
-
- /*
- * Got the resources, now move the data
- */
-ddprintf ("pager_move_page(%x,%d,%d)\n",block.block.p_offset,old_pindex,new_pindex);
- old_part = partition_of(old_pindex);
- offset = ptoa(block.block.p_offset);
- rc = page_read_file_direct (old_part->file,
- offset,
- vm_page_size,
- &raddr,
- &size);
- if (rc != 0)
- panic(here,my_name);
-
- /* release old */
- pager_dealloc_page(old_pindex, block.block.p_offset, FALSE);
-
- new_part = partition_of(new_pindex);
- offset = ptoa(new_offset);
- rc = page_write_file_direct (new_part->file,
- offset,
- raddr,
- size,
- &size);
- if (rc != 0)
- panic(here,my_name);
-
- (void) vm_deallocate( mach_task_self(), raddr, size);
-
- ret.block.p_offset = new_offset;
- ret.block.p_index = new_pindex;
-
- return ret;
-}
-
-#ifdef CHECKSUM
-/*
- * Return the checksum for a block.
- */
-int
-pager_get_checksum(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register vm_offset_t f_page;
- int checksum;
-
- f_page = atop(offset);
-
- mutex_lock(&pager->lock); /* XXX lock_read */
- if (f_page >= pager->size)
- panic("%spager_get_checksum",my_name);
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register vm_offset_t *mapptr;
-
- mapptr = (vm_offset_t *)pager->checksum[f_page/PAGEMAP_ENTRIES];
- if (mapptr == 0)
- checksum = NO_CHECKSUM;
- else
- checksum = mapptr[f_page%PAGEMAP_ENTRIES];
- }
- else {
- checksum = pager->checksum[f_page];
- }
-
- mutex_unlock(&pager->lock);
- return (checksum);
-}
-
-/*
- * Remember the checksum for a block.
- */
-int
-pager_put_checksum(pager, offset, checksum)
- register dpager_t pager;
- vm_offset_t offset;
- int checksum;
-{
- register vm_offset_t f_page;
- static char here[] = "%spager_put_checksum";
-
- f_page = atop(offset);
-
- mutex_lock(&pager->lock); /* XXX lock_read */
- if (f_page >= pager->size)
- panic(here,my_name);
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register vm_offset_t *mapptr;
-
- mapptr = (vm_offset_t *)pager->checksum[f_page/PAGEMAP_ENTRIES];
- if (mapptr == 0)
- panic(here,my_name);
-
- mapptr[f_page%PAGEMAP_ENTRIES] = checksum;
- }
- else {
- pager->checksum[f_page] = checksum;
- }
- mutex_unlock(&pager->lock);
-}
-
-/*
- * Compute a checksum - XOR each 32-bit word.
- */
-int
-compute_checksum(addr, size)
- vm_offset_t addr;
- vm_size_t size;
-{
- register int checksum = NO_CHECKSUM;
- register int *ptr;
- register int count;
-
- ptr = (int *)addr;
- count = size / sizeof(int);
-
- while (--count >= 0)
- checksum ^= *ptr++;
-
- return (checksum);
-}
-#endif /* CHECKSUM */
-
-/*
- * Given an offset within a paging object, find the
- * corresponding block within the paging partition.
- * Allocate a new block if necessary.
- *
- * WARNING: paging objects apparently may be extended
- * without notice!
- */
-union dp_map
-pager_write_offset(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register vm_offset_t f_page;
- register dp_map_t mapptr;
- register union dp_map block;
-
- invalidate_block(block);
-
- f_page = atop(offset);
-
-#if DEBUG_READER_CONFLICTS
- if (pager->readers > 0)
- default_pager_read_conflicts++; /* would have proceeded with
- read/write lock */
-#endif
- mutex_lock(&pager->lock); /* XXX lock_read */
-#if DEBUG_READER_CONFLICTS
- pager->readers++;
-#endif
-
- /* Catch the case where we had no initial fit partition
- for this object, but one was added later on */
- if (no_partition(pager->cur_partition)) {
- p_index_t new_part;
- vm_size_t size;
-
- size = (f_page > pager->size) ? f_page : pager->size;
- new_part = choose_partition(ptoa(size), P_INDEX_INVALID);
- if (no_partition(new_part))
- new_part = choose_partition(ptoa(1), P_INDEX_INVALID);
- if (no_partition(new_part))
- /* give up right now to avoid confusion */
- goto out;
- else
- pager->cur_partition = new_part;
- }
-
- while (f_page >= pager->size) {
- ddprintf ("pager_write_offset: extending: %x %x\n", f_page, pager->size);
-
- /*
- * Paging object must be extended.
- * Remember that offset is 0-based, but size is 1-based.
- */
-#if DEBUG_READER_CONFLICTS
- pager->readers--;
-#endif
- mutex_unlock(&pager->lock);
- pager_extend(pager, f_page + 1);
-#if DEBUG_READER_CONFLICTS
- if (pager->readers > 0)
- default_pager_read_conflicts++; /* would have proceeded with
- read/write lock */
-#endif
- mutex_lock(&pager->lock); /* XXX lock_read */
-#if DEBUG_READER_CONFLICTS
- pager->readers++;
-#endif
- ddprintf ("pager_write_offset: done extending: %x %x\n", f_page, pager->size);
- }
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- ddprintf ("pager_write_offset: indirect\n");
- mapptr = pager->map[f_page/PAGEMAP_ENTRIES].indirect;
- if (mapptr == 0) {
- /*
- * Allocate the indirect block
- */
- register int i;
- ddprintf ("pager_write_offset: allocating indirect\n");
-
- mapptr = (dp_map_t) kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- if (mapptr == 0) {
- /* out of space! */
- no_paging_space(TRUE);
- goto out;
- }
- pager->map[f_page/PAGEMAP_ENTRIES].indirect = mapptr;
- for (i = 0; i < PAGEMAP_ENTRIES; i++)
- invalidate_block(mapptr[i]);
-#ifdef CHECKSUM
- {
- register vm_offset_t *cksumptr;
- register int j;
-
- cksumptr = (vm_offset_t *)
- kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- if (cksumptr == 0) {
- /* out of space! */
- no_paging_space(TRUE);
- goto out;
- }
- pager->checksum[f_page/PAGEMAP_ENTRIES]
- = (vm_offset_t)cksumptr;
- for (j = 0; j < PAGEMAP_ENTRIES; j++)
- cksumptr[j] = NO_CHECKSUM;
- }
-#endif /* CHECKSUM */
- }
- f_page %= PAGEMAP_ENTRIES;
- }
- else {
- mapptr = pager->map;
- }
-
- block = mapptr[f_page];
- ddprintf ("pager_write_offset: block starts as %x[%x] %x\n", mapptr, f_page, block);
- if (no_block(block)) {
- vm_offset_t off;
-
- /* get room now */
- off = pager_alloc_page(pager->cur_partition, TRUE);
- if (off == NO_BLOCK) {
- /*
- * Before giving up, try all other partitions.
- */
- p_index_t new_part;
-
- ddprintf ("pager_write_offset: could not allocate block\n");
- /* returns it locked (if any one is non-full) */
- new_part = choose_partition( ptoa(1), pager->cur_partition);
- if ( ! no_partition(new_part) ) {
-
-#if debug
-dprintf("%s partition %x filled,", my_name, pager->cur_partition);
-dprintf("extending object %x (size %x) to %x.\n",
- pager, pager->size, new_part);
-#endif
-
- /* this one tastes better */
- pager->cur_partition = new_part;
-
- /* this unlocks the partition too */
- off = pager_alloc_page(pager->cur_partition, FALSE);
-
- }
-
- if (off == NO_BLOCK) {
- /*
- * Oh well.
- */
- overcommitted(FALSE, 1);
- goto out;
- }
- ddprintf ("pager_write_offset: decided to allocate block\n");
- }
- block.block.p_offset = off;
- block.block.p_index = pager->cur_partition;
- mapptr[f_page] = block;
- ddprintf ("pager_write_offset: mapptr %x [3b] = %x\n", mapptr,
- mapptr[0x3b]);
- ddprintf ("pager_write_offset: block is finally %x\n", block);
- }
-
-out:
-
-#if DEBUG_READER_CONFLICTS
- pager->readers--;
-#endif
- mutex_unlock(&pager->lock);
- return (block);
-}
-
-/*
- * Deallocate all of the blocks belonging to a paging object.
- * No locking needed because no other operations can be in progress.
- */
-void
-pager_dealloc(pager)
- register dpager_t pager;
-{
- register int i, j;
- register dp_map_t mapptr;
- register union dp_map block;
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
- mapptr = pager->map[i].indirect;
- if (mapptr != 0) {
- for (j = 0; j < PAGEMAP_ENTRIES; j++) {
- block = mapptr[j];
- if ( ! no_block(block) )
- pager_dealloc_page(block.block.p_index,
- block.block.p_offset, TRUE);
- }
- kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- }
- }
- kfree((char *)pager->map, INDIRECT_PAGEMAP_SIZE(pager->size));
-#ifdef CHECKSUM
- for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
- mapptr = (vm_offset_t *)pager->checksum[i];
- if (mapptr) {
- kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- }
- }
- kfree((char *)pager->checksum,
- INDIRECT_PAGEMAP_SIZE(pager->size));
-#endif /* CHECKSUM */
- }
- else {
- mapptr = pager->map;
- for (i = 0; i < pager->size; i++ ) {
- block = mapptr[i];
- if ( ! no_block(block) )
- pager_dealloc_page(block.block.p_index,
- block.block.p_offset, TRUE);
- }
- kfree((char *)pager->map, PAGEMAP_SIZE(pager->size));
-#ifdef CHECKSUM
- kfree((char *)pager->checksum, PAGEMAP_SIZE(pager->size));
-#endif /* CHECKSUM */
- }
-}
-
-/*
- * Move all the pages of a PAGER that live in a
- * partition PINDEX somewhere else.
- * Pager should be write-locked, partition too.
- * Returns FALSE if it could not do it, but
- * some pages might have been moved nonetheless.
- */
-boolean_t
-pager_realloc(pager, pindex)
- register dpager_t pager;
- p_index_t pindex;
-{
- register dp_map_t map, emap;
- vm_size_t size;
- union dp_map block;
-
- size = pager->size; /* in pages */
- map = pager->map;
-
- if (INDIRECT_PAGEMAP(size)) {
- for (emap = &map[INDIRECT_PAGEMAP_ENTRIES(size)];
- map < emap; map++) {
-
- register dp_map_t map2, emap2;
-
- if ((map2 = map->indirect) == 0)
- continue;
-
- for (emap2 = &map2[PAGEMAP_ENTRIES];
- map2 < emap2; map2++)
- if ( map2->block.p_index == pindex) {
-
- block = pager_move_page(*map2);
- if (!no_block(block))
- *map2 = block;
- else
- return FALSE;
- }
-
- }
- goto ok;
- }
-
- /* A small one */
- for (emap = &map[size]; map < emap; map++)
- if (map->block.p_index == pindex) {
- block = pager_move_page(*map);
- if (!no_block(block))
- *map = block;
- else
- return FALSE;
- }
-ok:
- pager->cur_partition = choose_partition(0, P_INDEX_INVALID);
- return TRUE;
-}
-
-/*
-
- */
-
-/*
- * Read/write routines.
- */
-#define PAGER_SUCCESS 0
-#define PAGER_ABSENT 1
-#define PAGER_ERROR 2
-
-/*
- * Read data from a default pager. Addr is the address of a buffer
- * to fill. Out_addr returns the buffer that contains the data;
- * if it is different from <addr>, it must be deallocated after use.
- */
-int
-default_read(ds, addr, size, offset, out_addr, deallocate, external)
- register dpager_t ds;
- vm_offset_t addr; /* pointer to block to fill */
- register vm_size_t size;
- register vm_offset_t offset;
- vm_offset_t *out_addr;
- /* returns pointer to data */
- boolean_t deallocate;
- boolean_t external;
-{
- register union dp_map block;
- vm_offset_t raddr;
- vm_size_t rsize;
- register int rc;
- boolean_t first_time;
- register partition_t part;
-#ifdef CHECKSUM
- vm_size_t original_size = size;
-#endif /* CHECKSUM */
- vm_offset_t original_offset = offset;
-
- /*
- * Find the block in the paging partition
- */
- block = pager_read_offset(ds, offset);
- if ( no_block(block) ) {
- if (external) {
- /*
- * An external object is requesting unswapped data,
- * zero fill the page and return.
- */
- bzero((char *) addr, vm_page_size);
- *out_addr = addr;
- return (PAGER_SUCCESS);
- }
- return (PAGER_ABSENT);
- }
-
- /*
- * Read it, trying for the entire page.
- */
- offset = ptoa(block.block.p_offset);
-ddprintf ("default_read(%x,%x,%x,%d)\n",addr,size,offset,block.block.p_index);
- part = partition_of(block.block.p_index);
- first_time = TRUE;
- *out_addr = addr;
-
- do {
- rc = page_read_file_direct(part->file,
- offset,
- size,
- &raddr,
- &rsize);
- if (rc != 0)
- return (PAGER_ERROR);
-
- /*
- * If we got the entire page on the first read, return it.
- */
- if (first_time && rsize == size) {
- *out_addr = raddr;
- break;
- }
- /*
- * Otherwise, copy the data into the
- * buffer we were passed, and try for
- * the next piece.
- */
- first_time = FALSE;
- bcopy((char *)raddr, (char *)addr, rsize);
- addr += rsize;
- offset += rsize;
- size -= rsize;
- } while (size != 0);
-
-#if USE_PRECIOUS
- if (deallocate)
- pager_release_offset(ds, original_offset);
-#endif /*USE_PRECIOUS*/
-
-#ifdef CHECKSUM
- {
- int write_checksum,
- read_checksum;
-
- write_checksum = pager_get_checksum(ds, original_offset);
- read_checksum = compute_checksum(*out_addr, original_size);
- if (write_checksum != read_checksum) {
- panic(
- "PAGER CHECKSUM ERROR: offset 0x%x, written 0x%x, read 0x%x",
- original_offset, write_checksum, read_checksum);
- }
- }
-#endif /* CHECKSUM */
- return (PAGER_SUCCESS);
-}
-
-int
-default_write(ds, addr, size, offset)
- register dpager_t ds;
- register vm_offset_t addr;
- register vm_size_t size;
- register vm_offset_t offset;
-{
- register union dp_map block;
- partition_t part;
- vm_size_t wsize;
- register int rc;
-
- ddprintf ("default_write: pager offset %x\n", offset);
-
- /*
- * Find block in paging partition
- */
- block = pager_write_offset(ds, offset);
- if ( no_block(block) )
- return (PAGER_ERROR);
-
-#ifdef CHECKSUM
- /*
- * Save checksum
- */
- {
- int checksum;
-
- checksum = compute_checksum(addr, size);
- pager_put_checksum(ds, offset, checksum);
- }
-#endif /* CHECKSUM */
- offset = ptoa(block.block.p_offset);
-ddprintf ("default_write(%x,%x,%x,%d)\n",addr,size,offset,block.block.p_index);
- part = partition_of(block.block.p_index);
-
- /*
- * There are various assumptions made here,we
- * will not get into the next disk 'block' by
- * accident. It might well be non-contiguous.
- */
- do {
- rc = page_write_file_direct(part->file,
- offset,
- addr,
- size,
- &wsize);
- if (rc != 0) {
- dprintf("*** PAGER ERROR: default_write: ");
- dprintf("ds=0x%x addr=0x%x size=0x%x offset=0x%x resid=0x%x\n",
- ds, addr, size, offset, wsize);
- return (PAGER_ERROR);
- }
- addr += wsize;
- offset += wsize;
- size -= wsize;
- } while (size != 0);
- return (PAGER_SUCCESS);
-}
-
-boolean_t
-default_has_page(ds, offset)
- dpager_t ds;
- vm_offset_t offset;
-{
- return ( ! no_block(pager_read_offset(ds, offset)) );
-}
-/*
-
- */
-
-/*
- * Mapping between pager port and paging object.
- */
-struct dstruct {
- queue_chain_t links; /* Link in pager-port list */
-
- struct mutex lock; /* Lock for the structure */
- struct condition
- waiting_seqno, /* someone waiting on seqno */
- waiting_read, /* someone waiting on readers */
- waiting_write, /* someone waiting on writers */
- waiting_refs; /* someone waiting on refs */
-
- memory_object_t pager; /* Pager port */
- mach_port_seqno_t seqno; /* Pager port sequence number */
- mach_port_t pager_request; /* Request port */
- mach_port_urefs_t request_refs; /* Request port user-refs */
- mach_port_t pager_name; /* Name port */
- mach_port_urefs_t name_refs; /* Name port user-refs */
- boolean_t external; /* Is an external object? */
-
- unsigned int readers; /* Reads in progress */
- unsigned int writers; /* Writes in progress */
-
- /* This is the reply port of an outstanding
- default_pager_object_set_size call. */
- mach_port_t lock_request;
-
- unsigned int errors; /* Pageout error count */
- struct dpager dpager; /* Actual pager */
-};
-typedef struct dstruct * default_pager_t;
-#define DEFAULT_PAGER_NULL ((default_pager_t)0)
-
-#if PARALLEL
-#define dstruct_lock_init(ds) mutex_init(&ds->lock)
-#define dstruct_lock(ds) mutex_lock(&ds->lock)
-#define dstruct_unlock(ds) mutex_unlock(&ds->lock)
-#else /* PARALLEL */
-#define dstruct_lock_init(ds)
-#define dstruct_lock(ds)
-#define dstruct_unlock(ds)
-#endif /* PARALLEL */
-
-/*
- * List of all pagers. A specific pager is
- * found directly via its port, this list is
- * only used for monitoring purposes by the
- * default_pager_object* calls
- */
-struct pager_port {
- queue_head_t queue;
- struct mutex lock;
- int count; /* saves code */
- queue_head_t leak_queue;
-} all_pagers;
-
-#define pager_port_list_init() \
-{ \
- mutex_init(&all_pagers.lock); \
- queue_init(&all_pagers.queue); \
- queue_init(&all_pagers.leak_queue); \
- all_pagers.count = 0; \
-}
-
-void pager_port_list_insert(port, ds)
- mach_port_t port;
- default_pager_t ds;
-{
- mutex_lock(&all_pagers.lock);
- queue_enter(&all_pagers.queue, ds, default_pager_t, links);
- all_pagers.count++;
- mutex_unlock(&all_pagers.lock);
-}
-
-/* given a data structure return a good port-name to associate it to */
-#define pnameof(_x_) (((vm_offset_t)(_x_))+1)
-/* reverse, assumes no-odd-pointers */
-#define dnameof(_x_) (((vm_offset_t)(_x_))&~1)
-
-/* The magic typecast */
-#define pager_port_lookup(_port_) \
- ((! MACH_PORT_VALID(_port_) || \
- ((default_pager_t)dnameof(_port_))->pager != (_port_)) ? \
- DEFAULT_PAGER_NULL : (default_pager_t)dnameof(_port_))
-
-void pager_port_list_delete(ds)
- default_pager_t ds;
-{
- mutex_lock(&all_pagers.lock);
- queue_remove(&all_pagers.queue, ds, default_pager_t, links);
- all_pagers.count--;
- mutex_unlock(&all_pagers.lock);
-}
-
-/*
- * Destroy a paging partition.
- * XXX this is not re-entrant XXX
- */
-kern_return_t
-destroy_paging_partition(name, pp_private)
- char *name;
- void **pp_private;
-{
- register unsigned int id = part_id(name);
- register partition_t part;
- boolean_t all_ok = TRUE;
- default_pager_t entry;
- int pindex;
-
- /*
- * Find and take partition out of list
- * This prevents choose_partition from
- * getting in the way.
- */
- mutex_lock(&all_partitions.lock);
- for (pindex = 0; pindex < all_partitions.n_partitions; pindex++) {
- part = partition_of(pindex);
- if (part && (part->id == id)) break;
- }
- if (pindex == all_partitions.n_partitions) {
- mutex_unlock(&all_partitions.lock);
- return KERN_INVALID_ARGUMENT;
- }
- part->going_away = TRUE;
- mutex_unlock(&all_partitions.lock);
-
- /*
- * This might take a while..
- */
-all_over_again:
-#if debug
-dprintf("Partition x%x (id x%x) for %s, all_ok %d\n", part, id, name, all_ok);
-#endif
- all_ok = TRUE;
- mutex_lock(&part->p_lock);
-
- mutex_lock(&all_pagers.lock);
- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) {
-
- dstruct_lock(entry);
-
- if (!mutex_try_lock(&entry->dpager.lock)) {
-
- dstruct_unlock(entry);
- mutex_unlock(&all_pagers.lock);
- mutex_unlock(&part->p_lock);
-
- /* yield the processor */
- (void) thread_switch(MACH_PORT_NULL,
- SWITCH_OPTION_NONE, 0);
-
- goto all_over_again;
-
- }
-
- /*
- * See if we can relocate all the pages of this object
- * currently on this partition on some other partition
- */
- all_ok = pager_realloc(&entry->dpager, pindex);
-
- mutex_unlock(&entry->dpager.lock);
- dstruct_unlock(entry);
-
- if (!all_ok) break;
-
- }
- mutex_unlock(&all_pagers.lock);
-
- if (all_ok) {
- /* No need to unlock partition, there are no refs left */
-
- set_partition_of(pindex, 0);
- *pp_private = part->file;
- kfree(part->bitmap, howmany(part->total_size, NB_BM) * sizeof(bm_entry_t));
- kfree(part, sizeof(struct part));
- dprintf("%s Removed paging partition %s\n", my_name, name);
- return KERN_SUCCESS;
- }
-
- /*
- * Put partition back in.
- */
- part->going_away = FALSE;
-
- return KERN_FAILURE;
-}
-
-
-/*
- * We use the sequence numbers on requests to regulate
- * our parallelism. In general, we allow multiple reads and writes
- * to proceed in parallel, with the exception that reads must
- * wait for previous writes to finish. (Because the kernel might
- * generate a data-request for a page on the heels of a data-write
- * for the same page, and we must avoid returning stale data.)
- * terminate requests wait for proceeding reads and writes to finish.
- */
-
-unsigned int default_pager_total = 0; /* debugging */
-unsigned int default_pager_wait_seqno = 0; /* debugging */
-unsigned int default_pager_wait_read = 0; /* debugging */
-unsigned int default_pager_wait_write = 0; /* debugging */
-unsigned int default_pager_wait_refs = 0; /* debugging */
-
-#if PARALLEL
-/*
- * Waits for correct sequence number. Leaves pager locked.
- */
-void pager_port_lock(ds, seqno)
- default_pager_t ds;
- mach_port_seqno_t seqno;
-{
- default_pager_total++;
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 1\n", &ds, ds, seqno);
- dstruct_lock(ds);
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 2\n", &ds, ds, seqno);
- while (ds->seqno != seqno) {
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 3\n", &ds, ds, seqno);
- default_pager_wait_seqno++;
- condition_wait(&ds->waiting_seqno, &ds->lock);
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 4\n", &ds, ds, seqno);
- }
-}
-
-/*
- * Increments sequence number and unlocks pager.
- */
-void pager_port_unlock(ds)
- default_pager_t ds;
-{
- ds->seqno++;
-ddprintf ("pager_port_unlock <%p>: <%p>: seqno => %d\n", &ds, ds, ds->seqno);
- dstruct_unlock(ds);
-ddprintf ("pager_port_unlock <%p>: <%p>: 2\n", &ds, ds);
- condition_broadcast(&ds->waiting_seqno);
-ddprintf ("pager_port_unlock <%p>: <%p>: 3\n", &ds, ds);
-}
-
-/*
- * Start a read - one more reader. Pager must be locked.
- */
-void pager_port_start_read(ds)
- default_pager_t ds;
-{
- ds->readers++;
-}
-
-/*
- * Wait for readers. Unlocks and relocks pager if wait needed.
- */
-void pager_port_wait_for_readers(ds)
- default_pager_t ds;
-{
- while (ds->readers != 0) {
- default_pager_wait_read++;
- condition_wait(&ds->waiting_read, &ds->lock);
- }
-}
-
-/*
- * Finish a read. Pager is unlocked and returns unlocked.
- */
-void pager_port_finish_read(ds)
- default_pager_t ds;
-{
- dstruct_lock(ds);
- if (--ds->readers == 0) {
- dstruct_unlock(ds);
- condition_broadcast(&ds->waiting_read);
- }
- else {
- dstruct_unlock(ds);
- }
-}
-
-/*
- * Start a write - one more writer. Pager must be locked.
- */
-void pager_port_start_write(ds)
- default_pager_t ds;
-{
- ds->writers++;
-}
-
-/*
- * Wait for writers. Unlocks and relocks pager if wait needed.
- */
-void pager_port_wait_for_writers(ds)
- default_pager_t ds;
-{
- while (ds->writers != 0) {
- default_pager_wait_write++;
- condition_wait(&ds->waiting_write, &ds->lock);
- }
-}
-
-/*
- * Finish a write. Pager is unlocked and returns unlocked.
- */
-void pager_port_finish_write(ds)
- default_pager_t ds;
-{
- dstruct_lock(ds);
- if (--ds->writers == 0) {
- dstruct_unlock(ds);
- condition_broadcast(&ds->waiting_write);
- }
- else {
- dstruct_unlock(ds);
- }
-}
-
-/*
- * Wait for concurrent default_pager_objects.
- * Unlocks and relocks pager if wait needed.
- */
-void pager_port_wait_for_refs(ds)
- default_pager_t ds;
-{
- while (ds->name_refs == 0) {
- default_pager_wait_refs++;
- condition_wait(&ds->waiting_refs, &ds->lock);
- }
-}
-
-/*
- * Finished creating name refs - wake up waiters.
- */
-void pager_port_finish_refs(ds)
- default_pager_t ds;
-{
- condition_broadcast(&ds->waiting_refs);
-}
-
-#else /* PARALLEL */
-
-#define pager_port_lock(ds,seqno)
-#define pager_port_unlock(ds)
-#define pager_port_start_read(ds)
-#define pager_port_wait_for_readers(ds)
-#define pager_port_finish_read(ds)
-#define pager_port_start_write(ds)
-#define pager_port_wait_for_writers(ds)
-#define pager_port_finish_write(ds)
-#define pager_port_wait_for_refs(ds)
-#define pager_port_finish_refs(ds)
-
-#endif /* PARALLEL */
-
-/*
- * Default pager.
- */
-task_t default_pager_self; /* Our task port. */
-
-mach_port_t default_pager_default_port; /* Port for memory_object_create. */
-
-/* We catch exceptions on ourself & startup using this port. */
-mach_port_t default_pager_exception_port;
-
-mach_port_t default_pager_internal_set; /* Port set for internal objects. */
-mach_port_t default_pager_external_set; /* Port set for external objects. */
-mach_port_t default_pager_default_set; /* Port set for "default" thread. */
-
-typedef struct default_pager_thread {
- cthread_t dpt_thread; /* Server thread. */
- vm_offset_t dpt_buffer; /* Read buffer. */
- boolean_t dpt_internal; /* Do we handle internal objects? */
-} default_pager_thread_t;
-
-#if PARALLEL
- /* determine number of threads at run time */
-#define DEFAULT_PAGER_INTERNAL_COUNT (0)
-
-#else /* PARALLEL */
-#define DEFAULT_PAGER_INTERNAL_COUNT (1)
-#endif /* PARALLEL */
-
-/* Memory created by default_pager_object_create should mostly be resident. */
-#define DEFAULT_PAGER_EXTERNAL_COUNT (1)
-
-unsigned int default_pager_internal_count = DEFAULT_PAGER_INTERNAL_COUNT;
- /* Number of "internal" threads. */
-unsigned int default_pager_external_count = DEFAULT_PAGER_EXTERNAL_COUNT;
- /* Number of "external" threads. */
-
-default_pager_t pager_port_alloc(size)
- vm_size_t size;
-{
- default_pager_t ds;
- p_index_t part;
-
- ds = (default_pager_t) kalloc(sizeof *ds);
- if (ds == DEFAULT_PAGER_NULL)
- panic("%spager_port_alloc",my_name);
- bzero((char *) ds, sizeof *ds);
-
- dstruct_lock_init(ds);
-
- /*
- * Get a suitable partition. If none big enough
- * just pick one and overcommit. If no partitions
- * at all.. well just fake one so that we will
- * kill specific objects on pageouts rather than
- * panicing the system now.
- */
- part = choose_partition(size, P_INDEX_INVALID);
- if (no_partition(part)) {
- overcommitted(FALSE, atop(size));
- part = choose_partition(0,P_INDEX_INVALID);
-#if debug
- if (no_partition(part))
- dprintf("%s No paging space at all !!\n", my_name);
-#endif
- }
- pager_alloc(&ds->dpager, part, size);
-
- return ds;
-}
-
-mach_port_urefs_t default_pager_max_urefs = 10000;
-
-/*
- * Check user reference count on pager_request port.
- * Pager must be locked.
- * Unlocks and re-locks pager if needs to call kernel.
- */
-void pager_port_check_request(ds, pager_request)
- default_pager_t ds;
- mach_port_t pager_request;
-{
- mach_port_delta_t delta;
- kern_return_t kr;
-
- assert(ds->pager_request == pager_request);
-
- if (++ds->request_refs > default_pager_max_urefs) {
- delta = 1 - ds->request_refs;
- ds->request_refs = 1;
-
- dstruct_unlock(ds);
-
- /*
- * Deallocate excess user references.
- */
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_SEND, delta);
- if (kr != KERN_SUCCESS)
- panic("%spager_port_check_request",my_name);
-
- dstruct_lock(ds);
- }
-}
-
-void default_pager_add(ds, internal)
- default_pager_t ds;
- boolean_t internal;
-{
- mach_port_t pager = ds->pager;
- mach_port_t pset;
- mach_port_mscount_t sync;
- mach_port_t previous;
- kern_return_t kr;
- static char here[] = "%sdefault_pager_add";
-
- /*
- * The port currently has a make-send count of zero,
- * because either we just created the port or we just
- * received the port in a memory_object_create request.
- */
-
- if (internal) {
- /* possibly generate an immediate no-senders notification */
- sync = 0;
- pset = default_pager_internal_set;
- ds->external = FALSE;
- } else {
- /* delay notification till send right is created */
- sync = 1;
- pset = default_pager_external_set;
- ds->external = TRUE;
- }
-
- kr = mach_port_request_notification(default_pager_self, pager,
- MACH_NOTIFY_NO_SENDERS, sync,
- pager, MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &previous);
- if ((kr != KERN_SUCCESS) || (previous != MACH_PORT_NULL))
- panic(here,my_name);
-
- kr = mach_port_move_member(default_pager_self, pager, pset);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-}
-
-/*
- * Routine: memory_object_create
- * Purpose:
- * Handle requests for memory objects from the
- * kernel.
- * Notes:
- * Because we only give out the default memory
- * manager port to the kernel, we don't have to
- * be so paranoid about the contents.
- */
-kern_return_t
-seqnos_memory_object_create(old_pager, seqno, new_pager, new_size,
- new_pager_request, new_pager_name, new_page_size)
- mach_port_t old_pager;
- mach_port_seqno_t seqno;
- mach_port_t new_pager;
- vm_size_t new_size;
- mach_port_t new_pager_request;
- mach_port_t new_pager_name;
- vm_size_t new_page_size;
-{
- register default_pager_t ds;
- kern_return_t kr;
-
- assert(old_pager == default_pager_default_port);
- assert(MACH_PORT_VALID(new_pager_request));
- assert(MACH_PORT_VALID(new_pager_name));
- assert(new_page_size == vm_page_size);
-
- ds = pager_port_alloc(new_size);
-rename_it:
- kr = mach_port_rename( default_pager_self,
- new_pager, (mach_port_t)pnameof(ds));
- if (kr != KERN_SUCCESS) {
- default_pager_t ds1;
-
- if (kr != KERN_NAME_EXISTS)
- panic("%s m_o_create", my_name);
- ds1 = (default_pager_t) kalloc(sizeof *ds1);
- *ds1 = *ds;
- mutex_lock(&all_pagers.lock);
- queue_enter(&all_pagers.leak_queue, ds, default_pager_t, links);
- mutex_unlock(&all_pagers.lock);
- ds = ds1;
- goto rename_it;
- }
-
- new_pager = (mach_port_t) pnameof(ds);
-
- /*
- * Set up associations between these ports
- * and this default_pager structure
- */
-
- ds->pager = new_pager;
- ds->pager_request = new_pager_request;
- ds->request_refs = 1;
- ds->pager_name = new_pager_name;
- ds->name_refs = 1;
-
- /*
- * After this, other threads might receive requests
- * for this memory object or find it in the port list.
- */
-
- pager_port_list_insert(new_pager, ds);
- default_pager_add(ds, TRUE);
-
- return(KERN_SUCCESS);
-}
-
-memory_object_copy_strategy_t default_pager_copy_strategy =
- MEMORY_OBJECT_COPY_DELAY;
-
-kern_return_t
-seqnos_memory_object_init(pager, seqno, pager_request, pager_name,
- pager_page_size)
- mach_port_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- mach_port_t pager_name;
- vm_size_t pager_page_size;
-{
- register default_pager_t ds;
- kern_return_t kr;
- static char here[] = "%sinit";
-
- assert(MACH_PORT_VALID(pager_request));
- assert(MACH_PORT_VALID(pager_name));
- assert(pager_page_size == vm_page_size);
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here, my_name);
- pager_port_lock(ds, seqno);
-
- if (ds->pager_request != MACH_PORT_NULL)
- panic(here, my_name);
-
- ds->pager_request = pager_request;
- ds->request_refs = 1;
- ds->pager_name = pager_name;
- ds->name_refs = 1;
-
- /*
- * Even if the kernel immediately terminates the object,
- * the pager_request port won't be destroyed until
- * we process the terminate request, which won't happen
- * until we unlock the object.
- */
-
- kr = memory_object_set_attributes(pager_request,
- TRUE,
- FALSE, /* do not cache */
- default_pager_copy_strategy);
- if (kr != KERN_SUCCESS)
- panic(here, my_name);
-
- pager_port_unlock(ds);
-
- return(KERN_SUCCESS);
-}
-
-kern_return_t
-seqnos_memory_object_terminate(pager, seqno, pager_request, pager_name)
- mach_port_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- mach_port_t pager_name;
-{
- register default_pager_t ds;
- mach_port_urefs_t request_refs, name_refs;
- kern_return_t kr;
- static char here[] = "%sterminate";
-
- /*
- * pager_request and pager_name are receive rights,
- * not send rights.
- */
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here, my_name);
-ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &kr, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
-
- /*
- * Wait for read and write requests to terminate.
- */
-
- pager_port_wait_for_readers(ds);
- pager_port_wait_for_writers(ds);
-
- /*
- * After memory_object_terminate both memory_object_init
- * and a no-senders notification are possible, so we need
- * to clean up the request and name ports but leave
- * the pager port.
- *
- * A concurrent default_pager_objects might be allocating
- * more references for the name port. In this case,
- * we must first wait for it to finish.
- */
-
- pager_port_wait_for_refs(ds);
-
- ds->pager_request = MACH_PORT_NULL;
- request_refs = ds->request_refs;
- ds->request_refs = 0;
- assert(ds->pager_name == pager_name);
- ds->pager_name = MACH_PORT_NULL;
- name_refs = ds->name_refs;
- ds->name_refs = 0;
-ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &kr, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
- /*
- * Now we deallocate our various port rights.
- */
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_SEND, -request_refs);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_name,
- MACH_PORT_RIGHT_SEND, -name_refs);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_name,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- return (KERN_SUCCESS);
-}
-
-void default_pager_no_senders(pager, seqno, mscount)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_mscount_t mscount;
-{
- register default_pager_t ds;
- kern_return_t kr;
- static char here[] = "%sno_senders";
-
- /*
- * Because we don't give out multiple send rights
- * for a memory object, there can't be a race
- * between getting a no-senders notification
- * and creating a new send right for the object.
- * Hence we don't keep track of mscount.
- */
-
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here,my_name);
- pager_port_lock(ds, seqno);
-
- /*
- * We shouldn't get a no-senders notification
- * when the kernel has the object cached.
- */
-
- if (ds->pager_request != MACH_PORT_NULL)
- panic(here,my_name);
-
- /*
- * Unlock the pager (though there should be no one
- * waiting for it).
- */
- dstruct_unlock(ds);
-
- /*
- * Remove the memory object port association, and then
- * the destroy the port itself. We must remove the object
- * from the port list before deallocating the pager,
- * because of default_pager_objects.
- */
-
- pager_port_list_delete(ds);
- pager_dealloc(&ds->dpager);
-
- kr = mach_port_mod_refs(default_pager_self, pager,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- /*
- * Do this *after* deallocating the port name
- */
- kfree((char *) ds, sizeof(*ds));
-
- /*
- * Recover memory that we might have wasted because
- * of name conflicts
- */
- mutex_lock(&all_pagers.lock);
-
- while (!queue_empty(&all_pagers.leak_queue)) {
-
- ds = (default_pager_t) queue_first(&all_pagers.leak_queue);
- queue_remove_first(&all_pagers.leak_queue, ds, default_pager_t, links);
- kfree((char *) ds, sizeof(*ds));
- }
-
- mutex_unlock(&all_pagers.lock);
-}
-
-int default_pager_pagein_count = 0;
-int default_pager_pageout_count = 0;
-
-kern_return_t
-seqnos_memory_object_data_request(pager, seqno, reply_to, offset,
- length, protection_required)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t reply_to;
- vm_offset_t offset;
- vm_size_t length;
- vm_prot_t protection_required;
-{
- default_pager_thread_t *dpt;
- default_pager_t ds;
- vm_offset_t addr;
- unsigned int errors;
- kern_return_t rc;
- static char here[] = "%sdata_request";
-
- dpt = (default_pager_thread_t *) cthread_data(cthread_self());
-
- if (length != vm_page_size)
- panic(here,my_name);
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here,my_name);
-ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
- pager_port_check_request(ds, reply_to);
- pager_port_wait_for_writers(ds);
- pager_port_start_read(ds);
-
- /*
- * Get error count while pager locked.
- */
- errors = ds->errors;
-
-ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
- if (errors) {
- dprintf("%s %s\n", my_name,
- "dropping data_request because of previous paging errors");
- (void) memory_object_data_error(reply_to,
- offset, vm_page_size,
- KERN_FAILURE);
- goto done;
- }
-
- if (offset >= ds->dpager.limit)
- rc = PAGER_ERROR;
- else
- rc = default_read(&ds->dpager, dpt->dpt_buffer,
- vm_page_size, offset,
- &addr, protection_required & VM_PROT_WRITE,
- ds->external);
-
- switch (rc) {
- case PAGER_SUCCESS:
- if (addr != dpt->dpt_buffer) {
- /*
- * Deallocates data buffer
- */
- (void) memory_object_data_supply(
- reply_to, offset,
- addr, vm_page_size, TRUE,
- VM_PROT_NONE,
- FALSE, MACH_PORT_NULL);
- } else {
- (void) memory_object_data_provided(
- reply_to, offset,
- addr, vm_page_size,
- VM_PROT_NONE);
- }
- break;
-
- case PAGER_ABSENT:
- (void) memory_object_data_unavailable(
- reply_to,
- offset,
- vm_page_size);
- break;
-
- case PAGER_ERROR:
- (void) memory_object_data_error(
- reply_to,
- offset,
- vm_page_size,
- KERN_FAILURE);
- break;
- }
-
- default_pager_pagein_count++;
-
- done:
- pager_port_finish_read(ds);
- return(KERN_SUCCESS);
-}
-
-/*
- * memory_object_data_initialize: check whether we already have each page, and
- * write it if we do not. The implementation is far from optimized, and
- * also assumes that the default_pager is single-threaded.
- */
-kern_return_t
-seqnos_memory_object_data_initialize(pager, seqno, pager_request,
- offset, addr, data_cnt)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- register
- vm_offset_t offset;
- register
- pointer_t addr;
- vm_size_t data_cnt;
-{
- vm_offset_t amount_sent;
- default_pager_t ds;
- static char here[] = "%sdata_initialize";
-
-#ifdef lint
- pager_request++;
-#endif /* lint */
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here,my_name);
-ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
- pager_port_check_request(ds, pager_request);
- pager_port_start_write(ds);
-ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
- for (amount_sent = 0;
- amount_sent < data_cnt;
- amount_sent += vm_page_size) {
-
- if (!default_has_page(&ds->dpager, offset + amount_sent)) {
- if (default_write(&ds->dpager,
- addr + amount_sent,
- vm_page_size,
- offset + amount_sent)
- != PAGER_SUCCESS) {
- dprintf("%s%s write error\n", my_name, here);
- dstruct_lock(ds);
- ds->errors++;
- dstruct_unlock(ds);
- }
- }
- }
-
- pager_port_finish_write(ds);
- if (vm_deallocate(default_pager_self, addr, data_cnt) != KERN_SUCCESS)
- panic(here,my_name);
-
- return(KERN_SUCCESS);
-}
-
-/*
- * memory_object_data_write: split up the stuff coming in from
- * a memory_object_data_write call
- * into individual pages and pass them off to default_write.
- */
-kern_return_t
-seqnos_memory_object_data_write(pager, seqno, pager_request,
- offset, addr, data_cnt)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- register
- vm_offset_t offset;
- register
- pointer_t addr;
- vm_size_t data_cnt;
-{
- register
- vm_size_t amount_sent;
- default_pager_t ds;
- static char here[] = "%sdata_write";
- int err;
-
-#ifdef lint
- pager_request++;
-#endif /* lint */
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 1\n", &err);
- if ((data_cnt % vm_page_size) != 0)
- {
- ddprintf ("fail 1: %d %d\n", data_cnt, vm_page_size);
- panic(here,my_name);
- }
-
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 2\n", &err);
- ds = pager_port_lookup(pager);
-ddprintf ("seqnos_memory_object_data_write <%p>: 3\n", &err);
- if (ds == DEFAULT_PAGER_NULL)
- {
- ddprintf ("fail 2: %d %d\n", pager, ds);
- panic(here,my_name);
- }
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 4\n", &err);
-ddprintf ("seqnos_memory_object_data_write <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &err, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
-ddprintf ("seqnos_memory_object_data_write <%p>: 5\n", &err);
- pager_port_check_request(ds, pager_request);
-ddprintf ("seqnos_memory_object_data_write <%p>: 6\n", &err);
- pager_port_start_write(ds);
-ddprintf ("seqnos_memory_object_data_write <%p>: 7\n", &err);
-ddprintf ("seqnos_memory_object_data_write <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &err, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 8\n", &err);
- for (amount_sent = 0;
- amount_sent < data_cnt;
- amount_sent += vm_page_size) {
-
- register int result;
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 9\n", &err);
- result = default_write(&ds->dpager,
- addr + amount_sent,
- vm_page_size,
- offset + amount_sent);
-ddprintf ("seqnos_memory_object_data_write <%p>: 10\n", &err);
- if (result != KERN_SUCCESS) {
-ddprintf ("seqnos_memory_object_data_write <%p>: 11\n", &err);
-#if debug
- dprintf("%s WRITE ERROR on default_pageout:", my_name);
- dprintf(" pager=%x, offset=0x%x, length=0x%x, result=%d\n",
- pager, offset+amount_sent, vm_page_size, result);
-#endif
- dstruct_lock(ds);
- ds->errors++;
- dstruct_unlock(ds);
- }
- default_pager_pageout_count++;
- }
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 12\n", &err);
- pager_port_finish_write(ds);
-ddprintf ("seqnos_memory_object_data_write <%p>: 13\n", &err);
- err = vm_deallocate(default_pager_self, addr, data_cnt);
-ddprintf ("seqnos_memory_object_data_write <%p>: 14\n", &err);
- if (err != KERN_SUCCESS)
- {
- ddprintf ("fail 3: %s %s %s %s\n", default_pager_self, addr, data_cnt, &err);
-
- panic(here,my_name);
- }
-
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 15\n", &err);
- return(KERN_SUCCESS);
-}
-
-/*ARGSUSED*/
-kern_return_t
-seqnos_memory_object_copy(old_memory_object, seqno, old_memory_control,
- offset, length, new_memory_object)
- memory_object_t old_memory_object;
- mach_port_seqno_t seqno;
- memory_object_control_t
- old_memory_control;
- vm_offset_t offset;
- vm_size_t length;
- memory_object_t new_memory_object;
-{
- panic("%scopy", my_name);
- return KERN_FAILURE;
-}
-
-/* We get this when our memory_object_lock_request has completed
- after we truncated an object. */
-kern_return_t
-seqnos_memory_object_lock_completed (memory_object_t pager,
- mach_port_seqno_t seqno,
- mach_port_t pager_request,
- vm_offset_t offset,
- vm_size_t length)
-{
- default_pager_t ds;
-
- ds = pager_port_lookup(pager);
- assert(ds != DEFAULT_PAGER_NULL);
-
- pager_port_lock(ds, seqno);
- pager_port_wait_for_readers(ds);
- pager_port_wait_for_writers(ds);
-
- /* Now that any in-core pages have been flushed, we can apply
- the limit to prevent any new page-ins. */
- assert (page_aligned (offset));
- ds->dpager.limit = offset;
-
- default_pager_object_set_size_reply (ds->lock_request, KERN_SUCCESS);
- ds->lock_request = MACH_PORT_NULL;
-
- if (ds->dpager.size > ds->dpager.limit / vm_page_size)
- /* Deallocate the old backing store pages and shrink the page map. */
- pager_truncate (&ds->dpager, ds->dpager.limit / vm_page_size);
-
- pager_port_unlock(ds, seqno);
-
- return KERN_SUCCESS;
-}
-
-kern_return_t
-seqnos_memory_object_data_unlock(pager, seqno, pager_request,
- offset, addr, data_cnt)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- vm_offset_t offset;
- pointer_t addr;
- vm_size_t data_cnt;
-{
- panic("%sdata_unlock",my_name);
- return(KERN_FAILURE);
-}
-
-kern_return_t
-seqnos_memory_object_supply_completed(pager, seqno, pager_request,
- offset, length,
- result, error_offset)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- vm_offset_t offset;
- vm_size_t length;
- kern_return_t result;
- vm_offset_t error_offset;
-{
- panic("%ssupply_completed",my_name);
- return(KERN_FAILURE);
-}
-
-kern_return_t
-seqnos_memory_object_data_return(pager, seqno, pager_request,
- offset, addr, data_cnt,
- dirty, kernel_copy)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- vm_offset_t offset;
- pointer_t addr;
- vm_size_t data_cnt;
- boolean_t dirty;
- boolean_t kernel_copy;
-{
- panic("%sdata_return",my_name);
- return(KERN_FAILURE);
-}
-
-kern_return_t
-seqnos_memory_object_change_completed(pager, seqno, may_cache, copy_strategy)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
-{
- panic("%schange_completed",my_name);
- return(KERN_FAILURE);
-}
-
-
-boolean_t default_pager_notify_server(in, out)
- mach_msg_header_t *in, *out;
-{
- register mach_no_senders_notification_t *n =
- (mach_no_senders_notification_t *) in;
-
- /*
- * The only send-once rights we create are for
- * receiving no-more-senders notifications.
- * Hence, if we receive a message directed to
- * a send-once right, we can assume it is
- * a genuine no-senders notification from the kernel.
- */
-
- if ((n->not_header.msgh_bits !=
- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE)) ||
- (n->not_header.msgh_id != MACH_NOTIFY_NO_SENDERS))
- return FALSE;
-
- assert(n->not_header.msgh_size == sizeof *n);
- assert(n->not_header.msgh_remote_port == MACH_PORT_NULL);
-
- assert(n->not_type.msgt_name == MACH_MSG_TYPE_INTEGER_32);
- assert(n->not_type.msgt_size == 32);
- assert(n->not_type.msgt_number == 1);
- assert(n->not_type.msgt_inline);
- assert(! n->not_type.msgt_longform);
-
- default_pager_no_senders(n->not_header.msgh_local_port,
- n->not_header.msgh_seqno, n->not_count);
-
- out->msgh_remote_port = MACH_PORT_NULL;
- return TRUE;
-}
-
-extern boolean_t seqnos_memory_object_server();
-extern boolean_t seqnos_memory_object_default_server();
-extern boolean_t default_pager_server();
-extern boolean_t exc_server();
-extern boolean_t bootstrap_server();
-extern void bootstrap_compat();
-
-mach_msg_size_t default_pager_msg_size_object = 128;
-
-boolean_t
-default_pager_demux_object(in, out)
- mach_msg_header_t *in;
- mach_msg_header_t *out;
-{
- /*
- * We receive memory_object_data_initialize messages in
- * the memory_object_default interface.
- */
-
-int rval;
-ddprintf ("DPAGER DEMUX OBJECT <%p>: %d\n", in, in->msgh_id);
-rval =
- (seqnos_memory_object_server(in, out) ||
- seqnos_memory_object_default_server(in, out) ||
- default_pager_notify_server(in, out) ||
- default_pager_server(in, out));
-ddprintf ("DPAGER DEMUX OBJECT DONE <%p>: %d\n", in, in->msgh_id);
-return rval;
-}
-
-mach_msg_size_t default_pager_msg_size_default = 8 * 1024;
-
-boolean_t
-default_pager_demux_default(in, out)
- mach_msg_header_t *in;
- mach_msg_header_t *out;
-{
- if (in->msgh_local_port == default_pager_default_port) {
- /*
- * We receive memory_object_create messages in
- * the memory_object_default interface.
- */
-
-int rval;
-ddprintf ("DPAGER DEMUX DEFAULT <%p>: %d\n", in, in->msgh_id);
-rval =
- (seqnos_memory_object_default_server(in, out) ||
- default_pager_server(in, out));
-ddprintf ("DPAGER DEMUX DEFAULT DONE <%p>: %d\n", in, in->msgh_id);
-return rval;
- } else if (in->msgh_local_port == default_pager_exception_port) {
- /*
- * We receive exception messages for
- * ourself and the startup task.
- */
-
- return exc_server(in, out);
- } else {
- panic(my_name);
- return FALSE;
- }
-}
-
-/*
- * We use multiple threads, for two reasons.
- *
- * First, memory objects created by default_pager_object_create
- * are "external", instead of "internal". This means the kernel
- * sends data (memory_object_data_write) to the object pageable.
- * To prevent deadlocks, the external and internal objects must
- * be managed by different threads.
- *
- * Second, the default pager uses synchronous IO operations.
- * Spreading requests across multiple threads should
- * recover some of the performance loss from synchronous IO.
- *
- * We have 3+ threads.
- * One receives memory_object_create and
- * default_pager_object_create requests.
- * One or more manage internal objects.
- * One or more manage external objects.
- */
-
-void
-default_pager_thread_privileges()
-{
- /*
- * Set thread privileges.
- */
- cthread_wire(); /* attach kernel thread to cthread */
- wire_thread(); /* grab a kernel stack and memory allocation
- privileges */
-}
-
-any_t
-default_pager_default_thread (arg)
- any_t arg;
-{
- kern_return_t kr;
- default_pager_thread_privileges ();
- for (;;) {
- kr = mach_msg_server(default_pager_demux_default,
- default_pager_msg_size_default,
- default_pager_default_set);
- panic(my_name, kr);
- }
-}
-
-
-
-any_t
-default_pager_thread(arg)
- any_t arg;
-{
- default_pager_thread_t *dpt = (default_pager_thread_t *) arg;
- mach_port_t pset;
- kern_return_t kr;
-
- cthread_set_data(cthread_self(), (any_t) dpt);
-
-
- /*
- * Threads handling external objects cannot have
- * privileges. Otherwise a burst of data-requests for an
- * external object could empty the free-page queue,
- * because the fault code only reserves real pages for
- * requests sent to internal objects.
- */
-
- if (dpt->dpt_internal) {
- default_pager_thread_privileges();
- pset = default_pager_internal_set;
- } else {
- pset = default_pager_external_set;
- }
-
- for (;;) {
- kr = mach_msg_server(default_pager_demux_object,
- default_pager_msg_size_object,
- pset);
- panic(my_name, kr);
- }
-}
-
-void
-start_default_pager_thread(internal)
- boolean_t internal;
-{
- default_pager_thread_t *dpt;
- kern_return_t kr;
-
- dpt = (default_pager_thread_t *) kalloc(sizeof *dpt);
- if (dpt == 0)
- panic(my_name);
-
- dpt->dpt_internal = internal;
-
- kr = vm_allocate(default_pager_self, &dpt->dpt_buffer,
- vm_page_size, TRUE);
- if (kr != KERN_SUCCESS)
- panic(my_name);
- wire_memory(dpt->dpt_buffer, vm_page_size,
- VM_PROT_READ|VM_PROT_WRITE);
-
- dpt->dpt_thread = cthread_fork(default_pager_thread, (any_t) dpt);
-}
-
-void
-default_pager_initialize(host_port)
- mach_port_t host_port;
-{
- memory_object_t DMM;
- kern_return_t kr;
-
- /*
- * This task will become the default pager.
- */
- default_pager_self = mach_task_self();
-
- /*
- * Initialize the "default pager" port.
- */
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE,
- &default_pager_default_port);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- DMM = default_pager_default_port;
- kr = vm_set_default_memory_manager(host_port, &DMM);
- if ((kr != KERN_SUCCESS) || MACH_PORT_VALID(DMM))
- panic(my_name);
-
- /*
- * Initialize the exception port.
- */
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE,
- &default_pager_exception_port);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- /*
- * Arrange for wiring privileges.
- */
- wire_setup(host_port);
-
- /*
- * Find out how many CPUs we have, to determine the number
- * of threads to create.
- */
- if (default_pager_internal_count == 0) {
- host_basic_info_data_t h_info;
- natural_t h_info_count;
-
- h_info_count = HOST_BASIC_INFO_COUNT;
- (void) host_info(host_port, HOST_BASIC_INFO,
- (host_info_t)&h_info, &h_info_count);
-
- /*
- * Random computation to get more parallelism on
- * multiprocessors.
- */
- default_pager_internal_count =
- (h_info.avail_cpus > 32 ? 32 : h_info.avail_cpus) / 4 + 3;
- }
-}
-
-/*
- * Initialize and Run the default pager
- */
-void
-default_pager()
-{
- kern_return_t kr;
- int i;
-
- default_pager_thread_privileges();
-
- /*
- * Wire down code, data, stack
- */
- wire_all_memory();
-
-
- /*
- * Initialize the list of all pagers.
- */
- pager_port_list_init();
-
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
- &default_pager_internal_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
- &default_pager_external_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
- &default_pager_default_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_move_member(default_pager_self,
- default_pager_default_port,
- default_pager_default_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_move_member(default_pager_self,
- default_pager_exception_port,
- default_pager_default_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- /*
- * Now we create the threads that will actually
- * manage objects.
- */
-
- for (i = 0; i < default_pager_internal_count; i++)
- start_default_pager_thread(TRUE);
-
- for (i = 0; i < default_pager_external_count; i++)
- start_default_pager_thread(FALSE);
-
- default_pager_default_thread(0); /* Become the default_pager server */
-#if 0
- cthread_fork (default_pager_default_thread, 0);
- /* cthread_exit (cthread_self ()); */
- thread_suspend (mach_thread_self ());
-#endif
-}
-
-/*
- * Create an external object.
- */
-kern_return_t
-S_default_pager_object_create (mach_port_t pager,
- mach_port_t *mem_obj,
- vm_size_t size)
-{
- default_pager_t ds;
- mach_port_t port;
- kern_return_t result;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- ds = pager_port_alloc(size);
-rename_it:
- port = (mach_port_t) pnameof(ds);
- result = mach_port_allocate_name(default_pager_self,
- MACH_PORT_RIGHT_RECEIVE, port);
- if (result != KERN_SUCCESS) {
- default_pager_t ds1;
-
- if (result != KERN_NAME_EXISTS) return (result);
-
- ds1 = (default_pager_t) kalloc(sizeof *ds1);
- *ds1 = *ds;
- mutex_lock(&all_pagers.lock);
- queue_enter(&all_pagers.leak_queue, ds, default_pager_t, links);
- mutex_unlock(&all_pagers.lock);
- ds = ds1;
- goto rename_it;
- }
-
- /*
- * Set up associations between these ports
- * and this default_pager structure
- */
-
- ds->pager = port;
- pager_port_list_insert(port, ds);
- default_pager_add(ds, FALSE);
-
- *mem_obj = port;
- return (KERN_SUCCESS);
-}
-
-kern_return_t
-S_default_pager_info (mach_port_t pager,
- default_pager_info_t *infop)
-{
- vm_size_t total, free;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- mutex_lock(&all_partitions.lock);
- paging_space_info(&total, &free);
- mutex_unlock(&all_partitions.lock);
-
- infop->dpi_total_space = ptoa(total);
- infop->dpi_free_space = ptoa(free);
- infop->dpi_page_size = vm_page_size;
- return KERN_SUCCESS;
-}
-
-kern_return_t
-S_default_pager_objects (mach_port_t pager,
- default_pager_object_array_t *objectsp,
- natural_t *ocountp,
- mach_port_array_t *portsp,
- natural_t *pcountp)
-{
- vm_offset_t oaddr; /* memory for objects */
- vm_size_t osize; /* current size */
- default_pager_object_t *objects;
- natural_t opotential;
-
- vm_offset_t paddr; /* memory for ports */
- vm_size_t psize; /* current size */
- mach_port_t *ports;
- natural_t ppotential;
-
- unsigned int actual;
- unsigned int num_pagers;
- kern_return_t kr;
- default_pager_t entry;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- /* start with the inline memory */
-
- num_pagers = 0;
-
- objects = *objectsp;
- opotential = *ocountp;
-
- ports = *portsp;
- ppotential = *pcountp;
-
- mutex_lock(&all_pagers.lock);
- /*
- * We will send no more than this many
- */
- actual = all_pagers.count;
- mutex_unlock(&all_pagers.lock);
-
- if (opotential < actual) {
- vm_offset_t newaddr;
- vm_size_t newsize;
-
- newsize = 2 * round_page(actual * sizeof *objects);
-
- kr = vm_allocate(default_pager_self, &newaddr, newsize, TRUE);
- if (kr != KERN_SUCCESS)
- goto nomemory;
-
- oaddr = newaddr;
- osize = newsize;
- opotential = osize/sizeof *objects;
- objects = (default_pager_object_t *) oaddr;
- }
-
- if (ppotential < actual) {
- vm_offset_t newaddr;
- vm_size_t newsize;
-
- newsize = 2 * round_page(actual * sizeof *ports);
-
- kr = vm_allocate(default_pager_self, &newaddr, newsize, TRUE);
- if (kr != KERN_SUCCESS)
- goto nomemory;
-
- paddr = newaddr;
- psize = newsize;
- ppotential = psize/sizeof *ports;
- ports = (mach_port_t *) paddr;
- }
-
- /*
- * Now scan the list.
- */
-
- mutex_lock(&all_pagers.lock);
-
- num_pagers = 0;
- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) {
-
- mach_port_t port;
- vm_size_t size;
-
- if ((num_pagers >= opotential) ||
- (num_pagers >= ppotential)) {
- /*
- * This should be rare. In any case,
- * we will only miss recent objects,
- * because they are added at the end.
- */
- break;
- }
-
- /*
- * Avoid interfering with normal operations
- */
- if (!mutex_try_lock(&entry->dpager.lock))
- goto not_this_one;
- size = pager_allocated(&entry->dpager);
- mutex_unlock(&entry->dpager.lock);
-
- dstruct_lock(entry);
-
- port = entry->pager_name;
- if (port == MACH_PORT_NULL) {
- /*
- * The object is waiting for no-senders
- * or memory_object_init.
- */
- dstruct_unlock(entry);
- goto not_this_one;
- }
-
- /*
- * We need a reference for the reply message.
- * While we are unlocked, the bucket queue
- * can change and the object might be terminated.
- * memory_object_terminate will wait for us,
- * preventing deallocation of the entry.
- */
-
- if (--entry->name_refs == 0) {
- dstruct_unlock(entry);
-
- /* keep the list locked, wont take long */
-
- kr = mach_port_mod_refs(default_pager_self,
- port, MACH_PORT_RIGHT_SEND,
- default_pager_max_urefs);
- if (kr != KERN_SUCCESS)
- panic("%sdefault_pager_objects",my_name);
-
- dstruct_lock(entry);
-
- entry->name_refs += default_pager_max_urefs;
- pager_port_finish_refs(entry);
- }
- dstruct_unlock(entry);
-
- /* the arrays are wired, so no deadlock worries */
-
- objects[num_pagers].dpo_object = (vm_offset_t) entry;
- objects[num_pagers].dpo_size = size;
- ports [num_pagers++] = port;
- continue;
-not_this_one:
- /*
- * Do not return garbage
- */
- objects[num_pagers].dpo_object = (vm_offset_t) 0;
- objects[num_pagers].dpo_size = 0;
- ports [num_pagers++] = MACH_PORT_NULL;
-
- }
-
- mutex_unlock(&all_pagers.lock);
-
- /*
- * Deallocate and clear unused memory.
- * (Returned memory will automagically become pageable.)
- */
-
- if (objects == *objectsp) {
- /*
- * Our returned information fit inline.
- * Nothing to deallocate.
- */
-
- *ocountp = num_pagers;
- } else if (actual == 0) {
- (void) vm_deallocate(default_pager_self, oaddr, osize);
-
- /* return zero items inline */
- *ocountp = 0;
- } else {
- vm_offset_t used;
-
- used = round_page(actual * sizeof *objects);
-
- if (used != osize)
- (void) vm_deallocate(default_pager_self,
- oaddr + used, osize - used);
-
- *objectsp = objects;
- *ocountp = num_pagers;
- }
-
- if (ports == *portsp) {
- /*
- * Our returned information fit inline.
- * Nothing to deallocate.
- */
-
- *pcountp = num_pagers;
- } else if (actual == 0) {
- (void) vm_deallocate(default_pager_self, paddr, psize);
-
- /* return zero items inline */
- *pcountp = 0;
- } else {
- vm_offset_t used;
-
- used = round_page(actual * sizeof *ports);
-
- if (used != psize)
- (void) vm_deallocate(default_pager_self,
- paddr + used, psize - used);
-
- *portsp = ports;
- *pcountp = num_pagers;
- }
-
- return KERN_SUCCESS;
-
- nomemory:
-
- {
- register int i;
- for (i = 0; i < num_pagers; i++)
- (void) mach_port_deallocate(default_pager_self, ports[i]);
- }
-
- if (objects != *objectsp)
- (void) vm_deallocate(default_pager_self, oaddr, osize);
-
- if (ports != *portsp)
- (void) vm_deallocate(default_pager_self, paddr, psize);
-
- return KERN_RESOURCE_SHORTAGE;
-}
-
-
-kern_return_t
-S_default_pager_object_pages (mach_port_t pager,
- mach_port_t object,
- default_pager_page_array_t *pagesp,
- natural_t *countp)
-{
- vm_offset_t addr; /* memory for page offsets */
- vm_size_t size; /* current memory size */
- default_pager_page_t *pages;
- natural_t potential, actual;
- kern_return_t kr;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- /* we start with the inline space */
-
- pages = *pagesp;
- potential = *countp;
-
- for (;;) {
- default_pager_t entry;
-
- mutex_lock(&all_pagers.lock);
- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) {
- dstruct_lock(entry);
- if (entry->pager_name == object) {
- mutex_unlock(&all_pagers.lock);
- goto found_object;
- }
- dstruct_unlock(entry);
- }
- mutex_unlock(&all_pagers.lock);
-
- /* did not find the object */
-
- if (pages != *pagesp)
- (void) vm_deallocate(default_pager_self, addr, size);
- return KERN_INVALID_ARGUMENT;
-
- found_object:
-
- if (!mutex_try_lock(&entry->dpager.lock)) {
- /* oh well bad luck */
-
- dstruct_unlock(entry);
-
- /* yield the processor */
- (void) thread_switch(MACH_PORT_NULL,
- SWITCH_OPTION_NONE, 0);
- continue;
- }
-
- actual = pager_pages(&entry->dpager, pages, potential);
- mutex_unlock(&entry->dpager.lock);
- dstruct_unlock(entry);
-
- if (actual <= potential)
- break;
-
- /* allocate more memory */
-
- if (pages != *pagesp)
- (void) vm_deallocate(default_pager_self, addr, size);
- size = round_page(actual * sizeof *pages);
- kr = vm_allocate(default_pager_self, &addr, size, TRUE);
- if (kr != KERN_SUCCESS)
- return kr;
- pages = (default_pager_page_t *) addr;
- potential = size/sizeof *pages;
- }
-
- /*
- * Deallocate and clear unused memory.
- * (Returned memory will automagically become pageable.)
- */
-
- if (pages == *pagesp) {
- /*
- * Our returned information fit inline.
- * Nothing to deallocate.
- */
-
- *countp = actual;
- } else if (actual == 0) {
- (void) vm_deallocate(default_pager_self, addr, size);
-
- /* return zero items inline */
- *countp = 0;
- } else {
- vm_offset_t used;
-
- used = round_page(actual * sizeof *pages);
-
- if (used != size)
- (void) vm_deallocate(default_pager_self,
- addr + used, size - used);
-
- *pagesp = pages;
- *countp = actual;
- }
- return KERN_SUCCESS;
-}
-
-
-kern_return_t
-S_default_pager_object_set_size (mach_port_t pager,
- mach_port_t reply_to,
- mach_port_seqno_t seqno,
- vm_size_t limit)
-{
- kern_return_t kr;
- default_pager_t ds;
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- return KERN_INVALID_ARGUMENT;
-
- pager_port_lock(ds, seqno);
- pager_port_check_request(ds, reply_to);
- pager_port_wait_for_readers(ds);
- pager_port_wait_for_writers(ds);
-
- limit = round_page (limit);
- if (ds->dpager.size <= limit / vm_page_size)
- {
- /* The limit has not been exceeded heretofore. Just change it. */
- ds->dpager.limit = limit;
- kr = KERN_SUCCESS;
- }
- else if (ds->lock_request == MACH_PORT_NULL)
- {
- /* Tell the kernel to flush from core all the pages being removed.
- We will get the memory_object_lock_completed callback when they
- have been flushed. We handle that by completing the limit update
- and posting the reply to the pending truncation. */
- kr = memory_object_lock_request (ds->pager_request,
- limit,
- ds->dpager.size * vm_page_size - limit,
- MEMORY_OBJECT_RETURN_NONE, TRUE,
- VM_PROT_ALL, ds->pager);
- if (kr != KERN_SUCCESS)
- panic ("memory_object_lock_request: %d", kr);
- ds->lock_request = reply_to;
- kr = MIG_NO_REPLY;
- }
- else
- /* There is already another call in progress. Tough titties. */
- kr = KERN_FAILURE;
-
- pager_port_unlock(ds, seqno);
-
- return kr;
-}
-
-/*
- * Add/remove extra paging space
- */
-
-extern mach_port_t bootstrap_master_device_port;
-extern mach_port_t bootstrap_master_host_port;
-
-kern_return_t
-S_default_pager_paging_file (pager, mdport, file_name, add)
- mach_port_t pager;
- mach_port_t mdport;
- default_pager_filename_t file_name;
- boolean_t add;
-{
- kern_return_t kr;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
-#if 0
-dprintf("bmd %x md %x\n", bootstrap_master_device_port, mdport);
-#endif
- if (add) {
- kr = add_paging_file(bootstrap_master_device_port,
- file_name, 0);
- } else {
- kr = remove_paging_file(file_name);
- }
-
- /* XXXX more code needed */
- if (mdport != bootstrap_master_device_port)
- mach_port_deallocate( mach_task_self(), mdport);
-
- return kr;
-}
-
-default_pager_register_fileserver(pager, fileserver)
- mach_port_t pager;
- mach_port_t fileserver;
-{
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-#if notyet
- mach_port_deallocate(mach_task_self(), fileserver);
- if (0) dp_helper_paging_space(0,0,0);/*just linkit*/
-#endif
- return KERN_SUCCESS;
-}
-
-/*
- * When things do not quite workout...
- */
-no_paging_space(out_of_memory)
- boolean_t out_of_memory;
-{
- static char here[] = "%s *** NOT ENOUGH PAGING SPACE ***";
-
- if (out_of_memory)
- dprintf("*** OUT OF MEMORY *** ");
- panic(here, my_name);
-}
-
-overcommitted(got_more_space, space)
- boolean_t got_more_space;
- vm_size_t space; /* in pages */
-{
- vm_size_t pages_free, pages_total;
-
- static boolean_t user_warned = FALSE;
- static vm_size_t pages_shortage = 0;
-
- paging_space_info(&pages_total, &pages_free);
-
- /*
- * If user added more space, see if it is enough
- */
- if (got_more_space) {
- pages_free -= pages_shortage;
- if (pages_free > 0) {
- pages_shortage = 0;
- if (user_warned)
- dprintf("%s paging space ok now.\n", my_name);
- } else
- pages_shortage = pages_free;
- user_warned = FALSE;
- return;
- }
- /*
- * We ran out of gas, let user know.
- */
- pages_free -= space;
- pages_shortage = (pages_free > 0) ? 0 : -pages_free;
- if (!user_warned && pages_shortage) {
- user_warned = TRUE;
- dprintf("%s paging space over-committed.\n", my_name);
- }
-#if debug
- user_warned = FALSE;
- dprintf("%s paging space over-committed [+%d (%d) pages].\n",
- my_name, space, pages_shortage);
-#endif
-}
-
-paging_space_info(totp, freep)
- vm_size_t *totp, *freep;
-{
- register vm_size_t total, free;
- register partition_t part;
- register int i;
-
- total = free = 0;
- for (i = 0; i < all_partitions.n_partitions; i++) {
-
- if ((part = partition_of(i)) == 0) continue;
-
- /* no need to lock: by the time this data
- gets back to any remote requestor it
- will be obsolete anyways */
- total += part->total_size;
- free += part->free;
-#if debug
- dprintf("Partition %d: x%x total, x%x free\n",
- i, part->total_size, part->free);
-#endif
- }
- *totp = total;
- *freep = free;
-}
-
-/*
- * Catch exceptions.
- */
-
-kern_return_t
-catch_exception_raise(exception_port, thread, task, exception, code, subcode)
- mach_port_t exception_port;
- mach_port_t thread, task;
- int exception, code, subcode;
-{
- ddprintf ("(default_pager)catch_exception_raise(%d,%d,%d)\n",
- exception, code, subcode);
- panic(my_name);
-
- /* mach_msg_server will deallocate thread/task for us */
-
- return KERN_FAILURE;
-}
diff --git a/serverboot/defs.h b/serverboot/defs.h
deleted file mode 100644
index 7b872fd6..00000000
--- a/serverboot/defs.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Common definitions for Berkeley Fast File System.
- */
-
-/*
- * Compatibility definitions for disk IO.
- */
-
-/*
- * Disk devices do all IO in 512-byte blocks.
- */
-#define DEV_BSIZE 512
-
-/*
- * Conversion between bytes and disk blocks.
- */
-#define btodb(byte_offset) ((byte_offset) >> 9)
-#define dbtob(block_number) ((block_number) << 9)
-
-/*
- * Compatibility definitions for old type names.
- */
-
-typedef struct _quad_ {
- unsigned int val[2]; /* 2 int values make... */
-} quad; /* an 8-byte item */
-
-#if 0
-typedef unsigned char u_char; /* unsigned char */
-typedef unsigned short u_short; /* unsigned short */
-typedef unsigned int u_int; /* unsigned int */
-
-typedef unsigned int time_t; /* an unsigned int */
-typedef unsigned int daddr_t; /* an unsigned int */
-typedef unsigned int off_t; /* another unsigned int */
-
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
-typedef unsigned int ino_t;
-#endif
-
-#define NBBY 8
-
-/*
- * The file system is made out of blocks of at most MAXBSIZE units,
- * with smaller units (fragments) only in the last direct block.
- * MAXBSIZE primarily determines the size of buffers in the buffer
- * pool. It may be made larger without any effect on existing
- * file systems; however, making it smaller may make some file
- * systems unmountable.
- *
- * Note that the disk devices are assumed to have DEV_BSIZE "sectors"
- * and that fragments must be some multiple of this size.
- */
-#define MAXBSIZE 8192
-#define MAXFRAG 8
-
-/*
- * MAXPATHLEN defines the longest permissible path length
- * after expanding symbolic links.
- *
- * MAXSYMLINKS defines the maximum number of symbolic links
- * that may be expanded in a path name. It should be set
- * high enough to allow all legitimate uses, but halt infinite
- * loops reasonably quickly.
- */
-
-#define MAXPATHLEN 1024
-#define MAXSYMLINKS 8
-
diff --git a/serverboot/dir.h b/serverboot/dir.h
deleted file mode 100644
index 208df5ce..00000000
--- a/serverboot/dir.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)dir.h 7.6 (Berkeley) 5/9/89
- */
-
-#ifndef _BOOT_UFS_DIR_H_
-#define _BOOT_UFS_DIR_H_
-
-/*
- * A directory consists of some number of blocks of DIRBLKSIZ
- * bytes, where DIRBLKSIZ is chosen such that it can be transferred
- * to disk in a single atomic operation (e.g. 512 bytes on most machines).
- *
- * Each DIRBLKSIZ byte block contains some number of directory entry
- * structures, which are of variable length. Each directory entry has
- * a struct direct at the front of it, containing its inode number,
- * the length of the entry, and the length of the name contained in
- * the entry. These are followed by the name padded to a 4 byte boundary
- * with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- *
- * The macro DIRSIZ(dp) gives the amount of space required to represent
- * a directory entry. Free space in a directory is represented by
- * entries which have dp->d_reclen > DIRSIZ(dp). All DIRBLKSIZ bytes
- * in a directory block are claimed by the directory entries. This
- * usually results in the last entry in a directory having a large
- * dp->d_reclen. When entries are deleted from a directory, the
- * space is returned to the previous entry in the same directory
- * block by increasing its dp->d_reclen. If the first entry of
- * a directory block is free, then its dp->d_ino is set to 0.
- * Entries other than the first in a directory do not normally have
- * dp->d_ino set to 0.
- */
-#define DIRBLKSIZ DEV_BSIZE
-#define MAXNAMLEN 255
-
-struct direct {
- u_int d_ino; /* inode number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
- char d_name[MAXNAMLEN + 1]; /* name with length <= MAXNAMLEN */
-};
-
-/*
- * The DIRSIZ macro gives the minimum record length which will hold
- * the directory entry. This requires the amount of space in struct direct
- * without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- */
-#undef DIRSIZ
-#define DIRSIZ(dp) \
- ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
-
-#ifdef KERNEL
-/*
- * Template for manipulating directories.
- * Should use struct direct's, but the name field
- * is MAXNAMLEN - 1, and this just won't do.
- */
-struct dirtemplate {
- u_int dot_ino;
- short dot_reclen;
- short dot_namlen;
- char dot_name[4]; /* must be multiple of 4 */
- u_int dotdot_ino;
- short dotdot_reclen;
- short dotdot_namlen;
- char dotdot_name[4]; /* ditto */
-};
-#endif
-
-/*
- * The following information should be obtained from <dirent.h>
- * and is provided solely (and temporarily) for backward compatibility.
- */
-#ifndef KERNEL
-#define d_fileno d_ino /* compatibility with POSIX */
-#ifndef DEV_BSIZE
-#define DEV_BSIZE 512
-#endif
-/*
- * Definitions for library routines operating on directories.
- */
-typedef struct _dirdesc {
- int dd_fd;
- int dd_loc;
- int dd_size;
- char dd_buf[DIRBLKSIZ];
-} DIR;
-
-#define dirfd(dirp) ((dirp)->dd_fd)
-
-#ifndef NULL
-#define NULL 0
-#endif
-extern DIR *opendir();
-extern struct direct *readdir();
-extern int telldir();
-extern void seekdir();
-#define rewinddir(dirp) seekdir((dirp), (long)0)
-extern void closedir();
-#endif /* not KERNEL */
-#endif /* _BOOT_UFS_DIR_H_ */
diff --git a/serverboot/disk_inode.h b/serverboot/disk_inode.h
deleted file mode 100644
index 6eed9104..00000000
--- a/serverboot/disk_inode.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)inode.h 7.5 (Berkeley) 7/3/89
- */
-
-#ifndef _BOOT_UFS_DISK_INODE_H_
-#define _BOOT_UFS_DISK_INODE_H_
-
-/*
- * The I node is the focus of all file activity in the BSD Fast File System.
- * There is a unique inode allocated for each active file,
- * each current directory, each mounted-on file, text file, and the root.
- * An inode is 'named' by its dev/inumber pair. (iget/iget.c)
- * Data in icommon is read in from permanent inode on volume.
- */
-
-#define FFS_NDADDR 12 /* direct addresses in inode */
-#define FFS_NIADDR 3 /* indirect addresses in inode */
-
-#define FFS_MAX_FASTLINK_SIZE ((FFS_NDADDR + FFS_NIADDR) * sizeof(daddr_t))
-
-struct icommon {
- u_short ic_mode; /* 0: mode and type of file */
- short ic_nlink; /* 2: number of links to file */
- short ic_uid; /* 4: owner's user id */
- short ic_gid; /* 6: owner's group id */
- quad ic_size; /* 8: number of bytes in file */
- time_t ic_atime; /* 16: time last accessed */
- int ic_atspare;
- time_t ic_mtime; /* 24: time last modified */
- int ic_mtspare;
- time_t ic_ctime; /* 32: last time inode changed */
- int ic_ctspare;
- union {
- struct {
- daddr_t Mb_db[FFS_NDADDR]; /* 40: disk block addresses */
- daddr_t Mb_ib[FFS_NIADDR]; /* 88: indirect blocks */
- } ic_Mb;
- char ic_Msymlink[FFS_MAX_FASTLINK_SIZE];
- /* 40: symbolic link name */
- } ic_Mun;
-#define ic_db ic_Mun.ic_Mb.Mb_db
-#define ic_ib ic_Mun.ic_Mb.Mb_ib
-#define ic_symlink ic_Mun.ic_Msymlink
- int ic_flags; /* 100: status, currently unused */
- int ic_blocks; /* 104: blocks actually held */
- int ic_gen; /* 108: generation number */
- int ic_spare[4]; /* 112: reserved, currently unused */
-} i_ic;
-
-/*
- * Same structure, but on disk.
- */
-struct dinode {
- union {
- struct icommon di_com;
- char di_char[128];
- } di_un;
-};
-#define di_ic di_un.di_com
-
-#endif /* _BOOT_UFS_DISK_INODE_H_ */
diff --git a/serverboot/disk_inode_ffs.h b/serverboot/disk_inode_ffs.h
deleted file mode 100644
index ab352f84..00000000
--- a/serverboot/disk_inode_ffs.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)inode.h 7.5 (Berkeley) 7/3/89
- */
-
-#ifndef _BOOT_UFS_DISK_INODE_FFS_H_
-#define _BOOT_UFS_DISK_INODE_FFS_H_
-
-#define NDADDR FFS_NDADDR
-#define NIADDR FFS_NIADDR
-
-#define MAX_FASTLINK_SIZE FFS_MAX_FASTLINK_SIZE
-
-#define IC_FASTLINK 0x0001 /* Symbolic link in inode */
-
-#define i_mode i_ic.ic_mode
-#define i_nlink i_ic.ic_nlink
-#define i_uid i_ic.ic_uid
-#define i_gid i_ic.ic_gid
-#if BYTE_MSF
-#define i_size i_ic.ic_size.val[1]
-#else /* BYTE_LSF */
-#define i_size i_ic.ic_size.val[0]
-#endif
-#define i_db i_ic.ic_db
-#define i_ib i_ic.ic_ib
-#define i_atime i_ic.ic_atime
-#define i_mtime i_ic.ic_mtime
-#define i_ctime i_ic.ic_ctime
-#define i_blocks i_ic.ic_blocks
-#define i_rdev i_ic.ic_db[0]
-#define i_symlink i_ic.ic_symlink
-#define i_flags i_ic.ic_flags
-#define i_gen i_ic.ic_gen
-
-/* modes */
-#define IFMT 0xf000 /* type of file */
-#define IFCHR 0x2000 /* character special */
-#define IFDIR 0x4000 /* directory */
-#define IFBLK 0x6000 /* block special */
-#define IFREG 0x8000 /* regular */
-#define IFLNK 0xa000 /* symbolic link */
-#define IFSOCK 0xc000 /* socket */
-
-
-#define ISUID 0x0800 /* set user id on execution */
-#define ISGID 0x0400 /* set group id on execution */
-#define ISVTX 0x0200 /* save swapped text even after use */
-#define IREAD 0x0100 /* read, write, execute permissions */
-#define IWRITE 0x0080
-#define IEXEC 0x0040
-
-#define f_fs u.ffs.ffs_fs
-#define i_ic u.ffs.ffs_ic
-#define f_nindir u.ffs.ffs_nindir
-#define f_blk u.ffs.ffs_blk
-#define f_blksize u.ffs.ffs_blksize
-#define f_blkno u.ffs.ffs_blkno
-
-#endif /* _BOOT_UFS_DISK_INODE_FFS_H_ */
diff --git a/serverboot/elf-load.c b/serverboot/elf-load.c
deleted file mode 100644
index 603eadf0..00000000
--- a/serverboot/elf-load.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990
- * Open Software Foundation, Inc.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation, and that the name of ("OSF") or Open Software
- * Foundation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior permission.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY
- * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
- */
-/*
- * OSF Research Institute MK6.1 (unencumbered) 1/31/1995
- */
-
-#include <alloca.h>
-#include <mach/machine/vm_types.h>
-#include <elf.h>
-#include "mach-exec.h"
-
-int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec,
- void *handle, exec_info_t *out_info)
-{
- vm_size_t actual;
- union { Elf32_Ehdr h; Elf64_Ehdr h64; } x;
- int i;
- int result;
-
- /* Read the ELF header. */
- if ((result = (*read)(handle, 0, &x, sizeof(x), &actual)) != 0)
- return result;
- if (actual < sizeof(x))
- return EX_NOT_EXECUTABLE;
-
- if ((x.h.e_ident[EI_MAG0] != ELFMAG0) ||
- (x.h.e_ident[EI_MAG1] != ELFMAG1) ||
- (x.h.e_ident[EI_MAG2] != ELFMAG2) ||
- (x.h.e_ident[EI_MAG3] != ELFMAG3))
- return EX_NOT_EXECUTABLE;
-
- /* Make sure the file is of the right architecture. */
-#ifdef i386
-# define MY_CLASS ELFCLASS32
-# define MY_DATA ELFDATA2LSB
-# define MY_MACHINE EM_386
-#elif defined __alpha__
-# define MY_CLASS ELFCLASS64
-# define MY_DATA ELFDATA2LSB
-# define MY_MACHINE EM_ALPHA
-#else
-#error Not ported to this architecture!
-#endif
-
- if ((x.h.e_ident[EI_CLASS] != MY_CLASS) ||
- (x.h.e_ident[EI_DATA] != MY_DATA))
- return EX_WRONG_ARCH;
-
- if (MY_CLASS == ELFCLASS64)
- {
- Elf64_Phdr *phdr, *ph;
- vm_size_t phsize;
-
- if (x.h64.e_machine != MY_MACHINE)
- return EX_WRONG_ARCH;
-
- /* XXX others */
- out_info->entry = (vm_offset_t) x.h64.e_entry;
- out_info->init_dp = 0; /* ? */
-
- phsize = x.h64.e_phnum * x.h64.e_phentsize;
- phdr = (Elf64_Phdr *)alloca(phsize);
-
- result = (*read)(handle, x.h64.e_phoff, phdr, phsize, &actual);
- if (result)
- return result;
- if (actual < phsize)
- return EX_CORRUPT;
-
- for (i = 0; i < x.h64.e_phnum; i++)
- {
- ph = (Elf64_Phdr *)((vm_offset_t)phdr + i * x.h64.e_phentsize);
- if (ph->p_type == PT_LOAD)
- {
- exec_sectype_t type = EXEC_SECTYPE_ALLOC |
- EXEC_SECTYPE_LOAD;
- if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ;
- if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE;
- if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE;
- result = (*read_exec)(handle,
- ph->p_offset, ph->p_filesz,
- ph->p_vaddr, ph->p_memsz, type);
- }
- }
- }
- else
- {
- Elf32_Phdr *phdr, *ph;
- vm_size_t phsize;
-
- if (x.h.e_machine != MY_MACHINE)
- return EX_WRONG_ARCH;
-
- /* XXX others */
- out_info->entry = (vm_offset_t) x.h.e_entry;
- out_info->init_dp = 0; /* ? */
-
- phsize = x.h.e_phnum * x.h.e_phentsize;
- phdr = (Elf32_Phdr *)alloca(phsize);
-
- result = (*read)(handle, x.h.e_phoff, phdr, phsize, &actual);
- if (result)
- return result;
- if (actual < phsize)
- return EX_CORRUPT;
-
- for (i = 0; i < x.h.e_phnum; i++)
- {
- ph = (Elf32_Phdr *)((vm_offset_t)phdr + i * x.h.e_phentsize);
- if (ph->p_type == PT_LOAD)
- {
- exec_sectype_t type = EXEC_SECTYPE_ALLOC |
- EXEC_SECTYPE_LOAD;
- if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ;
- if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE;
- if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE;
- result = (*read_exec)(handle,
- ph->p_offset, ph->p_filesz,
- ph->p_vaddr, ph->p_memsz, type);
- }
- }
- }
-
- return 0;
-}
diff --git a/serverboot/exec.c b/serverboot/exec.c
deleted file mode 100644
index a487fb5d..00000000
--- a/serverboot/exec.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * i386-specific routines for loading a.out files.
- */
-
-#include <mach.h>
-#include <mach/machine/vm_param.h>
-#include "mach-exec.h"
-
-#include <file_io.h>
-
-#ifdef i386
-
-#include <mach/machine/eflags.h>
-
-/*
- * Machine-dependent portions of execve() for the i386.
- */
-
-#define STACK_SIZE (64*1024)
-
-char *set_regs(
- mach_port_t user_task,
- mach_port_t user_thread,
- struct exec_info *info,
- int arg_size)
-{
- vm_offset_t stack_start;
- vm_offset_t stack_end;
- struct i386_thread_state regs;
- unsigned int reg_size;
-
- /*
- * Add space for 5 ints to arguments, for
- * PS program. XXX
- */
- arg_size += 5 * sizeof(int);
-
- /*
- * Allocate stack.
- */
- stack_end = VM_MAX_ADDRESS;
- stack_start = VM_MAX_ADDRESS - STACK_SIZE;
- (void)vm_allocate(user_task,
- &stack_start,
- (vm_size_t)(stack_end - stack_start),
- FALSE);
-
- reg_size = i386_THREAD_STATE_COUNT;
- (void)thread_get_state(user_thread,
- i386_THREAD_STATE,
- (thread_state_t)&regs,
- &reg_size);
-
- regs.eip = info->entry;
- regs.uesp = (int)((stack_end - arg_size) & ~(sizeof(int)-1));
-
- /* regs.efl |= EFL_TF; trace flag*/
-
- (void)thread_set_state(user_thread,
- i386_THREAD_STATE,
- (thread_state_t)&regs,
- reg_size);
-
- return (char *)regs.uesp;
-}
-
-#elif defined __alpha__
-
-
-/*
- * Object:
- * set_regs EXPORTED function
- *
- * Initialize enough state for a thread to run, including
- * stack memory and stack pointer, and program counter.
- *
- */
-#define STACK_SIZE (vm_size_t)(128*1024)
-
-char *set_regs(
- mach_port_t user_task,
- mach_port_t user_thread,
- struct exec_info *info,
- int arg_size)
-{
- vm_offset_t stack_start;
- vm_offset_t stack_end;
- struct alpha_thread_state regs;
-
- natural_t reg_size;
-
- /*
- * Allocate stack.
- */
- stack_end = VM_MAX_ADDRESS;
- stack_start = stack_end - STACK_SIZE;
- (void)vm_allocate(user_task,
- &stack_start,
- (vm_size_t)(STACK_SIZE),
- FALSE);
-
- reg_size = ALPHA_THREAD_STATE_COUNT;
- (void)thread_get_state(user_thread,
- ALPHA_THREAD_STATE,
- (thread_state_t)&regs,
- &reg_size);
-
- regs.pc = info->entry;
- regs.r29 = info->init_dp;
- regs.r30 = (integer_t)((stack_end - arg_size) & ~(sizeof(integer_t)-1));
-
- (void)thread_set_state(user_thread,
- ALPHA_THREAD_STATE,
- (thread_state_t)&regs,
- reg_size);
-
- return (char *)regs.r30;
-}
-
-#else
-# error "Not ported to this architecture!"
-#endif
diff --git a/serverboot/ext2_file_io.c b/serverboot/ext2_file_io.c
deleted file mode 100644
index cb915c4a..00000000
--- a/serverboot/ext2_file_io.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Stand-alone file reading package.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include "file_io.h"
-#include "ffs_compat.h"
-
-void ext2_close_file(); /* forward */
-
-/*
- * Free file buffers, but don't close file.
- */
-static void
-free_file_buffers(fp)
- register struct file *fp;
-{
- register int level;
-
- /*
- * Free the indirect blocks
- */
- for (level = 0; level < NIADDR; level++) {
- if (fp->f_blk[level] != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_blk[level],
- fp->f_blksize[level]);
- fp->f_blk[level] = 0;
- }
- fp->f_blkno[level] = -1;
- }
-
- /*
- * Free the data block
- */
- if (fp->f_buf != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
- fp->f_buf = 0;
- }
- fp->f_buf_blkno = -1;
-}
-
-/*
- * Read a new inode into a file structure.
- */
-static int
-read_inode(inumber, fp)
- ino_t inumber;
- register struct file *fp;
-{
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- register
- struct ext2_super_block *fs;
- daddr_t disk_block;
- kern_return_t rc;
-
- fs = fp->f_fs;
- disk_block = ino2blk(fs, fp->f_gd, inumber);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, disk_block),
- (int) EXT2_BLOCK_SIZE(fs),
- (char **)&buf,
- &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- {
- register struct ext2_inode *dp;
-
- dp = (struct ext2_inode *)buf;
- dp += itoo(fs, inumber);
- fp->i_ic = *dp;
- fp->f_size = dp->i_size;
- }
-
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
-
- /*
- * Clear out the old buffers
- */
- free_file_buffers(fp);
-
- return (0);
-}
-
-/*
- * Given an offset in a file, find the disk block number that
- * contains that block.
- */
-static int
-block_map(fp, file_block, disk_block_p)
- struct file *fp;
- daddr_t file_block;
- daddr_t *disk_block_p; /* out */
-{
- int level;
- int idx;
- daddr_t ind_block_num;
- kern_return_t rc;
-
- vm_offset_t olddata[NIADDR+1];
- vm_size_t oldsize[NIADDR+1];
-
- /*
- * Index structure of an inode:
- *
- * i_db[0..NDADDR-1] hold block numbers for blocks
- * 0..NDADDR-1
- *
- * i_ib[0] index block 0 is the single indirect
- * block
- * holds block numbers for blocks
- * NDADDR .. NDADDR + NINDIR(fs)-1
- *
- * i_ib[1] index block 1 is the double indirect
- * block
- * holds block numbers for INDEX blocks
- * for blocks
- * NDADDR + NINDIR(fs) ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
- *
- * i_ib[2] index block 2 is the triple indirect
- * block
- * holds block numbers for double-indirect
- * blocks for blocks
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2
- * + NINDIR(fs)**3 - 1
- */
-
- mutex_lock(&fp->f_lock);
-
- if (file_block < NDADDR) {
- /* Direct block. */
- *disk_block_p = fp->i_ic.i_block[file_block];
- mutex_unlock(&fp->f_lock);
- return (0);
- }
-
- file_block -= NDADDR;
-
- /*
- * nindir[0] = NINDIR
- * nindir[1] = NINDIR**2
- * nindir[2] = NINDIR**3
- * etc
- */
- for (level = 0; level < NIADDR; level++) {
- if (file_block < fp->f_nindir[level])
- break;
- file_block -= fp->f_nindir[level];
- }
- if (level == NIADDR) {
- /* Block number too high */
- mutex_unlock(&fp->f_lock);
- return (FS_NOT_IN_FILE);
- }
-
- ind_block_num = fp->i_ic.i_block[level + NDADDR];
-
- /*
- * Initialize array of blocks to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- oldsize[idx] = 0;
-
- for (; level >= 0; level--) {
-
- vm_offset_t data;
- mach_msg_type_number_t size;
-
- if (ind_block_num == 0)
- break;
-
- if (fp->f_blkno[level] == ind_block_num) {
- /*
- * Cache hit. Just pick up the data.
- */
-
- data = fp->f_blk[level];
- }
- else {
- /*
- * Drop our lock while doing the read.
- * (The f_dev and f_fs fields don`t change.)
- */
- mutex_unlock(&fp->f_lock);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, ind_block_num),
- EXT2_BLOCK_SIZE(fp->f_fs),
- (char **)&data,
- &size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- /*
- * See if we can cache the data. Need a write lock to
- * do this. While we hold the write lock, we can`t do
- * *anything* which might block for memory. Otherwise
- * a non-privileged thread might deadlock with the
- * privileged threads. We can`t block while taking the
- * write lock. Otherwise a non-privileged thread
- * blocked in the vm_deallocate (while holding a read
- * lock) will block a privileged thread. For the same
- * reason, we can`t take a read lock and then use
- * lock_read_to_write.
- */
-
- mutex_lock(&fp->f_lock);
-
- olddata[level] = fp->f_blk[level];
- oldsize[level] = fp->f_blksize[level];
-
- fp->f_blkno[level] = ind_block_num;
- fp->f_blk[level] = data;
- fp->f_blksize[level] = size;
-
- /*
- * Return to holding a read lock, and
- * dispose of old data.
- */
-
- }
-
- if (level > 0) {
- idx = file_block / fp->f_nindir[level-1];
- file_block %= fp->f_nindir[level-1];
- }
- else
- idx = file_block;
-
- ind_block_num = ((daddr_t *)data)[idx];
- }
-
- mutex_unlock(&fp->f_lock);
-
- /*
- * After unlocking the file, free any blocks that
- * we need to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- if (oldsize[idx] != 0)
- (void) vm_deallocate(mach_task_self(),
- olddata[idx],
- oldsize[idx]);
-
- *disk_block_p = ind_block_num;
- return (0);
-}
-
-/*
- * Read a portion of a file into an internal buffer. Return
- * the location in the buffer and the amount in the buffer.
- */
-static int
-buf_read_file(fp, offset, buf_p, size_p)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t *buf_p; /* out */
- vm_size_t *size_p; /* out */
-{
- register
- struct ext2_super_block *fs;
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
- int rc;
- vm_offset_t block_size;
-
- if (offset >= fp->i_ic.i_size)
- return (FS_NOT_IN_FILE);
-
- fs = fp->f_fs;
-
- off = blkoff(fs, offset);
- file_block = lblkno(fs, offset);
- block_size = blksize(fs, fp, file_block);
-
- if (file_block != fp->f_buf_blkno) {
- rc = block_map(fp, file_block, &disk_block);
- if (rc != 0)
- return (rc);
-
- if (fp->f_buf)
- (void)vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
-
- if (disk_block == 0) {
- (void)vm_allocate(mach_task_self(),
- &fp->f_buf,
- block_size,
- TRUE);
- fp->f_buf_size = block_size;
- }
- else {
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) block_size,
- (char **) &fp->f_buf,
- (mach_msg_type_number_t *)&fp->f_buf_size);
- }
- if (rc)
- return (rc);
-
- fp->f_buf_blkno = file_block;
- }
-
- /*
- * Return address of byte in buffer corresponding to
- * offset, and size of remainder of buffer after that
- * byte.
- */
- *buf_p = fp->f_buf + off;
- *size_p = block_size - off;
-
- /*
- * But truncate buffer at end of file.
- */
- if (*size_p > fp->i_ic.i_size - offset)
- *size_p = fp->i_ic.i_size - offset;
-
- return (0);
-}
-
-/*
- * Search a directory for a name and return its
- * i_number.
- */
-static int
-search_directory(name, fp, inumber_p)
- char * name;
- register struct file *fp;
- ino_t *inumber_p; /* out */
-{
- vm_offset_t buf;
- vm_size_t buf_size;
- vm_offset_t offset;
- struct ext2_dir_entry_2 *dp;
- int length;
- kern_return_t rc;
- char tmp_name[256];
-
- length = strlen(name);
-
- offset = 0;
- while (offset < fp->i_ic.i_size) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- dp = (struct ext2_dir_entry_2 *)buf;
- if (dp->inode != 0) {
- strncpy (tmp_name, dp->name, dp->name_len);
- tmp_name[dp->name_len] = '\0';
- if (dp->name_len == length &&
- !strcmp(name, tmp_name))
- {
- /* found entry */
- *inumber_p = dp->inode;
- return (0);
- }
- }
- offset += dp->rec_len;
- }
- return (FS_NO_ENTRY);
-}
-
-static int
-read_fs(dev, fsp, gdp, gd_size_p)
- mach_port_t dev;
- struct ext2_super_block **fsp;
- struct ext2_group_desc **gdp;
- vm_size_t *gd_size_p;
-{
- register
- struct ext2_super_block *fs;
- vm_offset_t buf;
- vm_offset_t buf2;
- mach_msg_type_number_t buf_size;
- mach_msg_type_number_t buf2_size;
- int error;
- int gd_count;
- int gd_blocks;
- int gd_size;
- int gd_location;
- int gd_sector;
-
- /*
- * Read the super block
- */
- error = device_read(dev, 0, (recnum_t) SBLOCK, SBSIZE,
- (char **) &buf, &buf_size);
- if (error)
- return (error);
-
- /*
- * Check the superblock
- */
- fs = (struct ext2_super_block *)buf;
- if (fs->s_magic != EXT2_SUPER_MAGIC) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return (FS_INVALID_FS);
- }
-
- *fsp = fs;
-
- /*
- * Compute the groups informations
- */
- gd_count = (fs->s_blocks_count - fs->s_first_data_block +
- fs->s_blocks_per_group - 1) / fs->s_blocks_per_group;
- gd_blocks = (gd_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
- EXT2_DESC_PER_BLOCK(fs);
- gd_size = gd_blocks * EXT2_BLOCK_SIZE(fs);
- gd_location = fs->s_first_data_block + 1;
- gd_sector = (gd_location * EXT2_BLOCK_SIZE(fs)) / DEV_BSIZE;
-
- /*
- * Read the groups descriptors
- */
- error = device_read(dev, 0, (recnum_t) gd_sector, gd_size,
- (char **) &buf2, &buf2_size);
- if (error) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return error;
- }
-
- *gdp = (struct ext2_group_desc *) buf2;
- *gd_size_p = gd_size;
-
- return 0;
-}
-
-static int
-mount_fs(fp)
- register struct file *fp;
-{
- register struct ext2_super_block *fs;
- int error;
-
- error = read_fs(fp->f_dev, &fp->f_fs, &fp->f_gd, &fp->f_gd_size);
- if (error)
- return (error);
-
- fs = fp->f_fs;
-
- /*
- * Calculate indirect block levels.
- */
- {
- register int mult;
- register int level;
-
- mult = 1;
- for (level = 0; level < NIADDR; level++) {
- mult *= NINDIR(fs);
- fp->f_nindir[level] = mult;
- }
- }
-
- return (0);
-}
-
-static void
-unmount_fs(fp)
- register struct file *fp;
-{
- if (file_is_structured(fp)) {
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_fs,
- SBSIZE);
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_gd,
- fp->f_gd_size);
- fp->f_fs = 0;
- }
-}
-
-/*
- * Open a file.
- */
-int
-ext2_open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
-#define RETURN(code) { rc = (code); goto exit; }
-
- register char *cp, *component;
- register int c; /* char */
- register int rc;
- ino_t inumber, parent_inumber;
- int nlinks = 0;
-
- char namebuf[MAXPATHLEN+1];
-
- if (path == 0 || *path == '\0') {
- return FS_NO_ENTRY;
- }
-
- /*
- * Copy name into buffer to allow modifying it.
- */
- strcpy(namebuf, path);
-
- /*
- * Look for '/dev/xxx' at start of path, for
- * root device.
- */
- if (!strprefix(namebuf, "/dev/")) {
- printf("no device name\n");
- return FS_NO_ENTRY;
- }
-
- cp = namebuf + 5; /* device */
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- bzero (fp, sizeof (struct file));
-
- rc = device_open(master_device_port,
- D_READ|D_WRITE,
- component,
- &fp->f_dev);
- if (rc)
- return rc;
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return rc;
-
- inumber = (ino_t) ROOTINO;
- if ((rc = read_inode(inumber, fp)) != 0) {
- printf("can't read root inode\n");
- goto exit;
- }
-
- while (*cp) {
-
- /*
- * Check that current node is a directory.
- */
- if ((fp->i_ic.i_mode & IFMT) != IFDIR)
- RETURN (FS_NOT_DIRECTORY);
-
- /*
- * Remove extra separators
- */
- while (*cp == '/')
- cp++;
-
- /*
- * Get next component of path name.
- */
- component = cp;
- {
- register int len = 0;
-
- while ((c = *cp) != '\0' && c != '/') {
- if (len++ > MAXNAMLEN)
- RETURN (FS_NAME_TOO_LONG);
- if (c & 0200)
- RETURN (FS_INVALID_PARAMETER);
- cp++;
- }
- *cp = 0;
- }
-
- /*
- * Look up component in current directory.
- * Save directory inumber in case we find a
- * symbolic link.
- */
- parent_inumber = inumber;
- rc = search_directory(component, fp, &inumber);
- if (rc) {
- printf("%s: not found\n", path);
- goto exit;
- }
- *cp = c;
-
- /*
- * Open next component.
- */
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
-
- /*
- * Check for symbolic link.
- */
- if ((fp->i_ic.i_mode & IFMT) == IFLNK) {
-
- int link_len = fp->i_ic.i_size;
- int len;
-
- len = strlen(cp) + 1;
-
- if (link_len + len >= MAXPATHLEN - 1)
- RETURN (FS_NAME_TOO_LONG);
-
- if (++nlinks > MAXSYMLINKS)
- RETURN (FS_SYMLINK_LOOP);
-
- memmove(&namebuf[link_len], cp, len);
-
-#ifdef IC_FASTLINK
- if (fp->i_ic.i_blocks == 0) {
- bcopy(fp->i_ic.i_block, namebuf, (unsigned) link_len);
- }
- else
-#endif /* IC_FASTLINK */
- {
- /*
- * Read file for symbolic link
- */
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- daddr_t disk_block;
- register struct ext2_super_block *fs = fp->f_fs;
-
- (void) block_map(fp, (daddr_t)0, &disk_block);
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) blksize(fs, fp, 0),
- (char **) &buf,
- &buf_size);
- if (rc)
- goto exit;
-
- bcopy((char *)buf, namebuf, (unsigned)link_len);
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- }
-
- /*
- * If relative pathname, restart at parent directory.
- * If absolute pathname, restart at root.
- * If pathname begins '/dev/<device>/',
- * restart at root of that device.
- */
- cp = namebuf;
- if (*cp != '/') {
- inumber = parent_inumber;
- }
- else if (!strprefix(cp, "/dev/")) {
- inumber = (ino_t)ROOTINO;
- }
- else {
- cp += 5;
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- /*
- * Unmount current file system and free buffers.
- */
- ext2_close_file(fp);
-
- /*
- * Open new root device.
- */
- rc = device_open(master_device_port,
- D_READ,
- component,
- &fp->f_dev);
- if (rc)
- return (rc);
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return (rc);
-
- inumber = (ino_t)ROOTINO;
- }
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
- }
- }
-
- /*
- * Found terminal component.
- */
- out_ok:
- mutex_init(&fp->f_lock);
- return 0;
-
- /*
- * At error exit, close file to free storage.
- */
- exit:
- ext2_close_file(fp);
- return rc;
-}
-
-/*
- * Close file - free all storage used.
- */
-void
-ext2_close_file(fp)
- register struct file *fp;
-{
- register int i;
-
- /*
- * Free the disk super-block.
- */
- unmount_fs(fp);
-
- /*
- * Free the inode and data buffers.
- */
- free_file_buffers(fp);
-}
-
-int
-ext2_file_is_directory(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFDIR;
-}
-
-int
-ext2_file_is_regular(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFREG;
-}
-
-/*
- * Copy a portion of a file into kernel memory.
- * Cross block boundaries when necessary.
- */
-int
-ext2_read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- int rc;
- register vm_size_t csize;
- vm_offset_t buf;
- vm_size_t buf_size;
-
- while (size != 0) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc)
- return (rc);
-
- csize = size;
- if (csize > buf_size)
- csize = buf_size;
- if (csize == 0)
- break;
-
- bcopy((char *)buf, (char *)start, csize);
-
- offset += csize;
- start += csize;
- size -= csize;
- }
- if (resid)
- *resid = size;
-
- return (0);
-}
-
-/* simple utility: only works for 2^n */
-static int
-log2(n)
- register unsigned int n;
-{
- register int i = 0;
-
- while ((n & 1) == 0) {
- i++;
- n >>= 1;
- }
- return i;
-}
-
-/*
- * Make an empty file_direct for a device.
- */
-int
-ext2_open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- struct ext2_super_block *fs;
- struct ext2_group_desc *gd;
- vm_size_t gd_size;
- int rc;
-
- if (!is_structured) {
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_bsize = vm_page_size;
- fdp->fd_bshift = log2(vm_page_size);
- fdp->fd_fsbtodb = 0; /* later */
- fdp->fd_size = 0; /* later */
- return 0;
- }
-
- rc = read_fs(dev, &fs, &gd, &gd_size);
- if (rc)
- return rc;
-
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_size = 0;
- fdp->fd_bsize = EXT2_BLOCK_SIZE(fs);
- fdp->fd_bshift = log2(fdp->fd_bsize);
- fdp->fd_fsbtodb = log2(fdp->fd_bsize / DEV_BSIZE);
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fs,
- SBSIZE);
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) gd,
- gd_size);
-
- return 0;
-}
-
-/*
- * Add blocks from a file to a file_direct.
- */
-int
-ext2_add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- register struct ext2_super_block *fs;
- long num_blocks, i;
- vm_offset_t buffer;
- vm_size_t size;
- int rc;
-
- /* the file must be on the same device */
-
- if (fdp->fd_dev != fp->f_dev)
- return FS_INVALID_FS;
-
- if (!file_is_structured(fp)) {
- int result[DEV_GET_SIZE_COUNT];
- natural_t count;
-
- count = DEV_GET_SIZE_COUNT;
- rc = device_get_status( fdp->fd_dev, DEV_GET_SIZE,
- result, &count);
- if (rc)
- return rc;
- fdp->fd_size = result[DEV_GET_SIZE_DEVICE_SIZE] >> fdp->fd_bshift;
- fdp->fd_fsbtodb = log2(fdp->fd_bsize/result[DEV_GET_SIZE_RECORD_SIZE]);
- return 0;
- }
-
- /* it must hold a file system */
-
- fs = fp->f_fs;
-/*
- if (fdp->fd_bsize != fs->fs_bsize ||
- fdp->fd_fsbtodb != fs->fs_fsbtodb)
-*/
- if (fdp->fd_bsize != EXT2_BLOCK_SIZE(fs))
- return FS_INVALID_FS;
-
- /* calculate number of blocks in the file, ignoring fragments */
-
- num_blocks = lblkno(fs, fp->i_ic.i_size);
-
- /* allocate memory for a bigger array */
-
- size = (num_blocks + fdp->fd_size) * sizeof(daddr_t);
- rc = vm_allocate(mach_task_self(), &buffer, size, TRUE);
- if (rc != KERN_SUCCESS)
- return rc;
-
- /* lookup new block addresses */
-
- for (i = 0; i < num_blocks; i++) {
- daddr_t disk_block;
-
- rc = block_map(fp, (daddr_t) i, &disk_block);
- if (rc != 0) {
- (void) vm_deallocate(mach_task_self(), buffer, size);
- return rc;
- }
-
- ((daddr_t *) buffer)[fdp->fd_size + i] = disk_block;
- }
-
- /* copy old addresses and install the new array */
-
- if (fdp->fd_blocks != 0) {
- bcopy((char *) fdp->fd_blocks, (char *) buffer,
- fdp->fd_size * sizeof(daddr_t));
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- }
- fdp->fd_blocks = (daddr_t *) buffer;
- fdp->fd_size += num_blocks;
-
- /* deallocate cached blocks */
-
- free_file_buffers(fp);
-
- return 0;
-}
-
-int
-ext2_remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- if (fdp->fd_blocks)
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- fdp->fd_blocks = 0; /* sanity */
- /* xxx should lose a ref to fdp->fd_dev here (and elsewhere) xxx */
-}
diff --git a/serverboot/ffs_compat.c b/serverboot/ffs_compat.c
deleted file mode 100644
index 6e322b63..00000000
--- a/serverboot/ffs_compat.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * BSD FFS like functions used to ease porting bootstrap to Linux ext2 fs
- * Copyright (C) 1994 Remy Card
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include <file_io.h>
-
-#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_inode))
-
-int ino2blk (struct ext2_super_block *fs, struct ext2_group_desc *gd, int ino)
-{
- int group;
- int blk;
-
- group = (ino - 1) / EXT2_INODES_PER_GROUP(fs);
- blk = gd[group].bg_inode_table +
- (((ino - 1) % EXT2_INODES_PER_GROUP(fs)) /
- EXT2_INODES_PER_BLOCK(fs));
- return blk;
-}
-
-int fsbtodb (struct ext2_super_block *fs, int b)
-{
- return (b * EXT2_BLOCK_SIZE(fs)) / DEV_BSIZE;
-}
-
-int itoo (struct ext2_super_block *fs, int ino)
-{
- return (ino - 1) % EXT2_INODES_PER_BLOCK(fs);
-}
-
-int blkoff (struct ext2_super_block * fs, vm_offset_t offset)
-{
- return offset % EXT2_BLOCK_SIZE(fs);
-}
-
-int lblkno (struct ext2_super_block * fs, vm_offset_t offset)
-{
- return offset / EXT2_BLOCK_SIZE(fs);
-}
-
-int blksize (struct ext2_super_block *fs, struct file *fp, daddr_t file_block)
-{
- return EXT2_BLOCK_SIZE(fs); /* XXX - fix for fragments */
-}
diff --git a/serverboot/ffs_compat.h b/serverboot/ffs_compat.h
deleted file mode 100644
index d78840f5..00000000
--- a/serverboot/ffs_compat.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * BSD FFS like declarations used to ease porting bootstrap to Linux ext2 fs
- * Copyright (C) 1994 Remy Card
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define SBSIZE EXT2_MIN_BLOCK_SIZE /* Size of superblock */
-#define SBLOCK ((daddr_t) 2) /* Location of superblock */
-
-#define NDADDR EXT2_NDIR_BLOCKS
-#define NIADDR (EXT2_N_BLOCKS - EXT2_NDIR_BLOCKS)
-
-#define MAXNAMLEN 255
-
-#define ROOTINO EXT2_ROOT_INO
-
-#define NINDIR(fs) EXT2_ADDR_PER_BLOCK(fs)
-
-#define IC_FASTLINK
-
-#define IFMT 00170000
-#define IFSOCK 0140000
-#define IFLNK 0120000
-#define IFREG 0100000
-#define IFBLK 0060000
-#define IFDIR 0040000
-#define IFCHR 0020000
-#define IFIFO 0010000
-#define ISUID 0004000
-#define ISGID 0002000
-#define ISVTX 0001000
-
-#define f_fs u.ext2.ext2_fs
-#define f_gd u.ext2.ext2_gd
-#define f_gd_size u.ext2.ext2_gd_size
-#define i_ic u.ext2.ext2_ic
-#define f_nindir u.ext2.ext2_nindir
-#define f_blk u.ext2.ext2_blk
-#define f_blksize u.ext2.ext2_blksize
-#define f_blkno u.ext2.ext2_blkno
-
diff --git a/serverboot/ffs_file_io.c b/serverboot/ffs_file_io.c
deleted file mode 100644
index 1105eacc..00000000
--- a/serverboot/ffs_file_io.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Stand-alone file reading package.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include "file_io.h"
-#include "fs.h"
-#include "dir.h"
-#include "disk_inode_ffs.h"
-
-void close_file(); /* forward */
-
-/*
- * Free file buffers, but don't close file.
- */
-static void
-free_file_buffers(fp)
- register struct file *fp;
-{
- register int level;
-
- /*
- * Free the indirect blocks
- */
- for (level = 0; level < NIADDR; level++) {
- if (fp->f_blk[level] != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_blk[level],
- fp->f_blksize[level]);
- fp->f_blk[level] = 0;
- }
- fp->f_blkno[level] = -1;
- }
-
- /*
- * Free the data block
- */
- if (fp->f_buf != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
- fp->f_buf = 0;
- }
- fp->f_buf_blkno = -1;
-}
-
-/*
- * Read a new inode into a file structure.
- */
-static int
-read_inode(inumber, fp)
- ino_t inumber;
- register struct file *fp;
-{
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- register struct fs *fs;
- daddr_t disk_block;
- kern_return_t rc;
-
- fs = fp->f_fs;
- disk_block = itod(fs, inumber);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, disk_block),
- (int) fs->fs_bsize,
- (char **)&buf,
- &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- {
- register struct dinode *dp;
-
- dp = (struct dinode *)buf;
- dp += itoo(fs, inumber);
- fp->i_ic = dp->di_ic;
- fp->f_size = fp->i_size;
- }
-
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
-
- /*
- * Clear out the old buffers
- */
- free_file_buffers(fp);
-
- return (0);
-}
-
-/*
- * Given an offset in a file, find the disk block number that
- * contains that block.
- */
-static int
-block_map(fp, file_block, disk_block_p)
- struct file *fp;
- daddr_t file_block;
- daddr_t *disk_block_p; /* out */
-{
- int level;
- int idx;
- daddr_t ind_block_num;
- kern_return_t rc;
-
- vm_offset_t olddata[NIADDR+1];
- vm_size_t oldsize[NIADDR+1];
-
- /*
- * Index structure of an inode:
- *
- * i_db[0..NDADDR-1] hold block numbers for blocks
- * 0..NDADDR-1
- *
- * i_ib[0] index block 0 is the single indirect
- * block
- * holds block numbers for blocks
- * NDADDR .. NDADDR + NINDIR(fs)-1
- *
- * i_ib[1] index block 1 is the double indirect
- * block
- * holds block numbers for INDEX blocks
- * for blocks
- * NDADDR + NINDIR(fs) ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
- *
- * i_ib[2] index block 2 is the triple indirect
- * block
- * holds block numbers for double-indirect
- * blocks for blocks
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2
- * + NINDIR(fs)**3 - 1
- */
-
- mutex_lock(&fp->f_lock);
-
- if (file_block < NDADDR) {
- /* Direct block. */
- *disk_block_p = fp->i_db[file_block];
- mutex_unlock(&fp->f_lock);
- return (0);
- }
-
- file_block -= NDADDR;
-
- /*
- * nindir[0] = NINDIR
- * nindir[1] = NINDIR**2
- * nindir[2] = NINDIR**3
- * etc
- */
- for (level = 0; level < NIADDR; level++) {
- if (file_block < fp->f_nindir[level])
- break;
- file_block -= fp->f_nindir[level];
- }
- if (level == NIADDR) {
- /* Block number too high */
- mutex_unlock(&fp->f_lock);
- return (FS_NOT_IN_FILE);
- }
-
- ind_block_num = fp->i_ib[level];
-
- /*
- * Initialize array of blocks to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- oldsize[idx] = 0;
-
- for (; level >= 0; level--) {
-
- vm_offset_t data;
- mach_msg_type_number_t size;
-
- if (ind_block_num == 0)
- break;
-
- if (fp->f_blkno[level] == ind_block_num) {
- /*
- * Cache hit. Just pick up the data.
- */
-
- data = fp->f_blk[level];
- }
- else {
- /*
- * Drop our lock while doing the read.
- * (The f_dev and f_fs fields don`t change.)
- */
- mutex_unlock(&fp->f_lock);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, ind_block_num),
- fp->f_fs->fs_bsize,
- (char **)&data,
- &size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- /*
- * See if we can cache the data. Need a write lock to
- * do this. While we hold the write lock, we can`t do
- * *anything* which might block for memory. Otherwise
- * a non-privileged thread might deadlock with the
- * privileged threads. We can`t block while taking the
- * write lock. Otherwise a non-privileged thread
- * blocked in the vm_deallocate (while holding a read
- * lock) will block a privileged thread. For the same
- * reason, we can`t take a read lock and then use
- * lock_read_to_write.
- */
-
- mutex_lock(&fp->f_lock);
-
- olddata[level] = fp->f_blk[level];
- oldsize[level] = fp->f_blksize[level];
-
- fp->f_blkno[level] = ind_block_num;
- fp->f_blk[level] = data;
- fp->f_blksize[level] = size;
-
- /*
- * Return to holding a read lock, and
- * dispose of old data.
- */
-
- }
-
- if (level > 0) {
- idx = file_block / fp->f_nindir[level-1];
- file_block %= fp->f_nindir[level-1];
- }
- else
- idx = file_block;
-
- ind_block_num = ((daddr_t *)data)[idx];
- }
-
- mutex_unlock(&fp->f_lock);
-
- /*
- * After unlocking the file, free any blocks that
- * we need to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- if (oldsize[idx] != 0)
- (void) vm_deallocate(mach_task_self(),
- olddata[idx],
- oldsize[idx]);
-
- *disk_block_p = ind_block_num;
- return (0);
-}
-
-/*
- * Read a portion of a file into an internal buffer. Return
- * the location in the buffer and the amount in the buffer.
- */
-static int
-buf_read_file(fp, offset, buf_p, size_p)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t *buf_p; /* out */
- vm_size_t *size_p; /* out */
-{
- register struct fs *fs;
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
- int rc;
- vm_offset_t block_size;
-
- if (offset >= fp->i_size)
- return (FS_NOT_IN_FILE);
-
- fs = fp->f_fs;
-
- off = blkoff(fs, offset);
- file_block = lblkno(fs, offset);
- block_size = blksize(fs, fp, file_block);
-
- if (file_block != fp->f_buf_blkno) {
- rc = block_map(fp, file_block, &disk_block);
- if (rc != 0)
- return (rc);
-
- if (fp->f_buf)
- (void)vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
-
- if (disk_block == 0) {
- (void)vm_allocate(mach_task_self(),
- &fp->f_buf,
- block_size,
- TRUE);
- fp->f_buf_size = block_size;
- }
- else {
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) block_size,
- (char **) &fp->f_buf,
- (mach_msg_type_number_t *)&fp->f_buf_size);
- }
- if (rc)
- return (rc);
-
- fp->f_buf_blkno = file_block;
- }
-
- /*
- * Return address of byte in buffer corresponding to
- * offset, and size of remainder of buffer after that
- * byte.
- */
- *buf_p = fp->f_buf + off;
- *size_p = block_size - off;
-
- /*
- * But truncate buffer at end of file.
- */
- if (*size_p > fp->i_size - offset)
- *size_p = fp->i_size - offset;
-
- return (0);
-}
-
-/* In 4.4 d_reclen is split into d_type and d_namlen */
-struct dirent_44 {
- unsigned long d_fileno;
- unsigned short d_reclen;
- unsigned char d_type;
- unsigned char d_namlen;
- char d_name[255 + 1];
-};
-
-/*
- * Search a directory for a name and return its
- * i_number.
- */
-static int
-search_directory(name, fp, inumber_p)
- char * name;
- register struct file *fp;
- ino_t *inumber_p; /* out */
-{
- vm_offset_t buf;
- vm_size_t buf_size;
- vm_offset_t offset;
- register struct dirent_44 *dp;
- int length;
- kern_return_t rc;
-
- length = strlen(name);
-
- offset = 0;
- while (offset < fp->i_size) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- dp = (struct dirent_44 *)buf;
- if (dp->d_ino != 0) {
- unsigned short namlen = dp->d_namlen;
- /*
- * If namlen is zero, then either this is a 4.3 file
- * system or the namlen is really zero. In the latter
- * case also the 4.3 d_namlen field is zero
- * interpreted either way.
- */
- if (namlen == 0)
- namlen = ((struct direct *)dp)->d_namlen;
-
- if (namlen == length &&
- !strcmp(name, dp->d_name))
- {
- /* found entry */
- *inumber_p = dp->d_ino;
- return (0);
- }
- }
- offset += dp->d_reclen;
- }
- return (FS_NO_ENTRY);
-}
-
-static int
-read_fs(dev, fsp)
- mach_port_t dev;
- struct fs **fsp;
-{
- register struct fs *fs;
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- int error;
-
- error = device_read(dev, 0, (recnum_t) SBLOCK, SBSIZE,
- (char **) &buf, &buf_size);
- if (error)
- return (error);
-
- fs = (struct fs *)buf;
- if (fs->fs_magic != FS_MAGIC ||
- fs->fs_bsize > MAXBSIZE ||
- fs->fs_bsize < sizeof(struct fs)) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return (FS_INVALID_FS);
- }
- /* don't read cylinder groups - we aren't modifying anything */
-
- *fsp = fs;
- return 0;
-}
-
-static int
-mount_fs(fp)
- register struct file *fp;
-{
- register struct fs *fs;
- int error;
-
- error = read_fs(fp->f_dev, &fp->f_fs);
- if (error)
- return (error);
- fs = fp->f_fs;
-
- /*
- * Calculate indirect block levels.
- */
- {
- register int mult;
- register int level;
-
- mult = 1;
- for (level = 0; level < NIADDR; level++) {
- mult *= NINDIR(fs);
- fp->f_nindir[level] = mult;
- }
- }
-
- return (0);
-}
-
-static void
-unmount_fs(fp)
- register struct file *fp;
-{
- if (file_is_structured(fp)) {
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_fs,
- SBSIZE);
- fp->f_fs = 0;
- }
-}
-
-/*
- * Open a file.
- */
-int
-ffs_open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
-#define RETURN(code) { rc = (code); goto exit; }
-
- register char *cp, *component;
- register int c; /* char */
- register int rc;
- ino_t inumber, parent_inumber;
- int nlinks = 0;
-
- char namebuf[MAXPATHLEN+1];
-
- if (path == 0 || *path == '\0') {
- return FS_NO_ENTRY;
- }
-
- /*
- * Copy name into buffer to allow modifying it.
- */
- strcpy(namebuf, path);
-
- /*
- * Look for '/dev/xxx' at start of path, for
- * root device.
- */
- if (!strprefix(namebuf, "/dev/")) {
- printf("no device name\n");
- return FS_NO_ENTRY;
- }
-
- cp = namebuf + 5; /* device */
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- bzero (fp, sizeof (struct file));
-
- rc = device_open(master_device_port,
- D_READ|D_WRITE,
- component,
- &fp->f_dev);
- if (rc)
- return rc;
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return rc;
-
- inumber = (ino_t) ROOTINO;
- if ((rc = read_inode(inumber, fp)) != 0) {
- printf("can't read root inode\n");
- goto exit;
- }
-
- while (*cp) {
-
- /*
- * Check that current node is a directory.
- */
- if ((fp->i_mode & IFMT) != IFDIR)
- RETURN (FS_NOT_DIRECTORY);
-
- /*
- * Remove extra separators
- */
- while (*cp == '/')
- cp++;
-
- /*
- * Get next component of path name.
- */
- component = cp;
- {
- register int len = 0;
-
- while ((c = *cp) != '\0' && c != '/') {
- if (len++ > MAXNAMLEN)
- RETURN (FS_NAME_TOO_LONG);
- if (c & 0200)
- RETURN (FS_INVALID_PARAMETER);
- cp++;
- }
- *cp = 0;
- }
-
- /*
- * Look up component in current directory.
- * Save directory inumber in case we find a
- * symbolic link.
- */
- parent_inumber = inumber;
- rc = search_directory(component, fp, &inumber);
- if (rc) {
- printf("%s: not found\n", path);
- goto exit;
- }
- *cp = c;
-
- /*
- * Open next component.
- */
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
-
- /*
- * Check for symbolic link.
- */
- if ((fp->i_mode & IFMT) == IFLNK) {
-
- int link_len = fp->i_size;
- int len;
-
- len = strlen(cp) + 1;
-
- if (link_len + len >= MAXPATHLEN - 1)
- RETURN (FS_NAME_TOO_LONG);
-
- if (++nlinks > MAXSYMLINKS)
- RETURN (FS_SYMLINK_LOOP);
-
- memmove (&namebuf[link_len], cp, len);
-
-#ifdef IC_FASTLINK
- if ((fp->i_flags & IC_FASTLINK) != 0) {
- bcopy(fp->i_symlink, namebuf, (unsigned) link_len);
- }
- else
-#endif /* IC_FASTLINK */
-#if !defined(DISABLE_BSD44_FASTLINKS)
- /*
- * There is no bit for fastlinks in 4.4 but instead
- * all symlinks that fit into the inode are fastlinks.
- * If the second block (ic_db[1]) is zero the symlink
- * can't be a fastlink if its length is at least five.
- * For symlinks of length one to four there is no easy
- * way of knowing whether we are looking at a 4.4
- * fastlink or a 4.3 slowlink. This code always
- * guesses the 4.4 way when in doubt. THIS BREAKS 4.3
- * SLOWLINKS OF LENGTH FOUR OR LESS.
- */
- if ((link_len <= MAX_FASTLINK_SIZE && fp->i_ic.ic_db[1] != 0)
- || (link_len <= 4))
- {
- bcopy(fp->i_symlink, namebuf, (unsigned) link_len);
- }
- else
-#endif /* !DISABLE_BSD44_FASTLINKS */
-
- {
- /*
- * Read file for symbolic link
- */
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- daddr_t disk_block;
- register struct fs *fs = fp->f_fs;
-
- (void) block_map(fp, (daddr_t)0, &disk_block);
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) blksize(fs, fp, 0),
- (char **) &buf,
- &buf_size);
- if (rc)
- goto exit;
-
- bcopy((char *)buf, namebuf, (unsigned)link_len);
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- }
-
- /*
- * If relative pathname, restart at parent directory.
- * If absolute pathname, restart at root.
- * If pathname begins '/dev/<device>/',
- * restart at root of that device.
- */
- cp = namebuf;
- if (*cp != '/') {
- inumber = parent_inumber;
- }
- else if (!strprefix(cp, "/dev/")) {
- inumber = (ino_t)ROOTINO;
- }
- else {
- cp += 5;
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- /*
- * Unmount current file system and free buffers.
- */
- close_file(fp);
-
- /*
- * Open new root device.
- */
- rc = device_open(master_device_port,
- D_READ,
- component,
- &fp->f_dev);
- if (rc)
- return (rc);
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return (rc);
-
- inumber = (ino_t)ROOTINO;
- }
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
- }
- }
-
- /*
- * Found terminal component.
- */
- out_ok:
- mutex_init(&fp->f_lock);
- return 0;
-
- /*
- * At error exit, close file to free storage.
- */
- exit:
- close_file(fp);
- return rc;
-}
-
-/*
- * Close file - free all storage used.
- */
-void
-ffs_close_file(fp)
- register struct file *fp;
-{
- register int i;
-
- /*
- * Free the disk super-block.
- */
- unmount_fs(fp);
-
- /*
- * Free the inode and data buffers.
- */
- free_file_buffers(fp);
-}
-
-int
-ffs_file_is_directory(struct file *fp)
-{
- return (fp->i_mode & IFMT) == IFDIR;
-}
-
-int
-ffs_file_is_regular(struct file *fp)
-{
- return (fp->i_mode & IFMT) == IFREG;
-}
-
-/*
- * Copy a portion of a file into kernel memory.
- * Cross block boundaries when necessary.
- */
-int
-ffs_read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- int rc;
- register vm_size_t csize;
- vm_offset_t buf;
- vm_size_t buf_size;
-
- while (size != 0) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc)
- return (rc);
-
- csize = size;
- if (csize > buf_size)
- csize = buf_size;
- if (csize == 0)
- break;
-
- bcopy((char *)buf, (char *)start, csize);
-
- offset += csize;
- start += csize;
- size -= csize;
- }
- if (resid)
- *resid = size;
-
- return (0);
-}
-
-/* simple utility: only works for 2^n */
-static int
-log2(n)
- register unsigned int n;
-{
- register int i = 0;
-
- while ((n & 1) == 0) {
- i++;
- n >>= 1;
- }
- return i;
-}
-
-/*
- * Make an empty file_direct for a device.
- */
-int
-ffs_open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- struct fs *fs;
- int rc;
-
- if (!is_structured) {
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_bsize = vm_page_size;
- fdp->fd_bshift = log2(vm_page_size);
- fdp->fd_fsbtodb = 0; /* later */
- fdp->fd_size = 0; /* later */
- return 0;
- }
-
- rc = read_fs(dev, &fs);
- if (rc)
- return rc;
-
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_size = 0;
- fdp->fd_bsize = fs->fs_bsize;
- fdp->fd_bshift = fs->fs_bshift;
- fdp->fd_fsbtodb = fs->fs_fsbtodb;
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fs,
- SBSIZE);
-
- return 0;
-}
-
-/*
- * Add blocks from a file to a file_direct.
- */
-int
-ffs_add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- register struct fs *fs;
- long num_blocks, i;
- vm_offset_t buffer;
- vm_size_t size;
- int rc;
-
- /* the file must be on the same device */
-
- if (fdp->fd_dev != fp->f_dev)
- return FS_INVALID_FS;
-
- if (!file_is_structured(fp)) {
- int result[DEV_GET_SIZE_COUNT];
- natural_t count;
-
- count = DEV_GET_SIZE_COUNT;
- rc = device_get_status( fdp->fd_dev, DEV_GET_SIZE,
- result, &count);
- if (rc)
- return rc;
- fdp->fd_size = result[DEV_GET_SIZE_DEVICE_SIZE] >> fdp->fd_bshift;
- fdp->fd_fsbtodb = log2(fdp->fd_bsize/result[DEV_GET_SIZE_RECORD_SIZE]);
- return 0;
- }
-
- /* it must hold a file system */
-
- fs = fp->f_fs;
- if (fdp->fd_bsize != fs->fs_bsize ||
- fdp->fd_fsbtodb != fs->fs_fsbtodb)
- return FS_INVALID_FS;
-
- /* calculate number of blocks in the file, ignoring fragments */
-
- num_blocks = lblkno(fs, fp->i_size);
-
- /* allocate memory for a bigger array */
-
- size = (num_blocks + fdp->fd_size) * sizeof(daddr_t);
- rc = vm_allocate(mach_task_self(), &buffer, size, TRUE);
- if (rc != KERN_SUCCESS)
- return rc;
-
- /* lookup new block addresses */
-
- for (i = 0; i < num_blocks; i++) {
- daddr_t disk_block;
-
- rc = block_map(fp, (daddr_t) i, &disk_block);
- if (rc != 0) {
- (void) vm_deallocate(mach_task_self(), buffer, size);
- return rc;
- }
-
- ((daddr_t *) buffer)[fdp->fd_size + i] = disk_block;
- }
-
- /* copy old addresses and install the new array */
-
- if (fdp->fd_blocks != 0) {
- bcopy((char *) fdp->fd_blocks, (char *) buffer,
- fdp->fd_size * sizeof(daddr_t));
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- }
- fdp->fd_blocks = (daddr_t *) buffer;
- fdp->fd_size += num_blocks;
-
- /* deallocate cached blocks */
-
- free_file_buffers(fp);
-
- return 0;
-}
-
-int
-ffs_remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- if (fdp->fd_blocks)
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- fdp->fd_blocks = 0; /* sanity */
- /* xxx should lose a ref to fdp->fd_dev here (and elsewhere) xxx */
-}
diff --git a/serverboot/file_io.c b/serverboot/file_io.c
deleted file mode 100644
index 99966f95..00000000
--- a/serverboot/file_io.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 1994 The University of Utah and
- * the Computer Systems Laboratory at the University of Utah (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the
- * Computer Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- *
- * Author: Bryan Ford, University of Utah CSL
- * MINIX FS patches: Csizmazia Balazs, University ELTE, Hungary
- */
-/* This is just an icky kludgy "VFS layer" (harhar) for ffs and ext2 and minix. */
-
-#include "file_io.h"
-
-int
-open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
- int rc;
-
- if ((rc = ext2_open_file(master_device_port, path, fp))
- != FS_INVALID_FS)
- {
- if (rc == 0)
- fp->f_fstype = EXT2_FS;
- return rc;
- }
- if ( (rc = minix_open_file(master_device_port, path, fp))
- != FS_INVALID_FS )
- {
- if (rc == 0)
- fp->f_fstype = MINIX_FS;
- return rc;
- }
- fp->f_fstype = BSD_FFS;
- return ffs_open_file(master_device_port, path, fp);
-}
-
-void
-close_file(fp)
- register struct file *fp;
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- ext2_close_file(fp);
- return;
- case MINIX_FS:
- minix_close_file(fp);
- return;
- default:
- ffs_close_file(fp);
- return;
- }
-}
-
-int
-read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- return ext2_read_file(fp, offset, start, size, resid);
- case MINIX_FS:
- return minix_read_file(fp, offset, start, size, resid);
- default:
- return ffs_read_file(fp, offset, start, size, resid);
- }
-
-}
-
-int
-file_is_directory(struct file *f)
-{
- switch (f->f_fstype) {
- case EXT2_FS:
- return ext2_file_is_directory(f);
- case MINIX_FS:
- return minix_file_is_directory(f);
- default:
- return ffs_file_is_directory(f);
- }
-}
-
-int
-file_is_regular(struct file *f)
-{
- switch (f->f_fstype) {
- case EXT2_FS:
- return ext2_file_is_regular(f);
- case MINIX_FS:
- return minix_file_is_regular(f);
- default:
- return ffs_file_is_regular(f);
- }
-
-}
-
-int
-open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- int rc;
-
-
- if ((rc = ext2_open_file_direct(dev, fdp, is_structured))
- != FS_INVALID_FS)
- {
- if (rc == 0)
- fdp->f_fstype = EXT2_FS;
- return rc;
- }
- if ( (rc = minix_open_file_direct(dev, fdp, is_structured) )
- != FS_INVALID_FS )
- {
- if (rc == 0)
- fdp->f_fstype = MINIX_FS;
- return rc;
- }
- fdp->f_fstype = BSD_FFS;
- return ffs_open_file_direct(dev, fdp, is_structured);
-}
-
-int
-add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- return ext2_add_file_direct(fdp, fp);
- case MINIX_FS:
- return minix_add_file_direct(fdp, fp);
- default:
- return ffs_add_file_direct(fdp, fp);
- }
-}
-
-
-int
-remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- switch (fdp->f_fstype) {
- case EXT2_FS:
- return ext2_remove_file_direct(fdp);
- case MINIX_FS:
- return minix_remove_file_direct(fdp);
- default:
- return ffs_remove_file_direct(fdp);
- }
-}
-
-/*
- * some other stuff, that was previously defined as macro
- */
-
-int
-file_is_structured(fp)
- register struct file *fp;
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- return (fp)->u.ext2.ext2_fs != 0;
- case MINIX_FS:
- return (fp)->u.minix.minix_fs != 0;
- default:
- return (fp)->u.ffs.ffs_fs != 0;
- }
-}
-
-/*
- * Special read and write routines for default pager.
- * Assume that all offsets and sizes are multiples
- * of DEV_BSIZE.
- */
-
-#define fdir_blkoff(fdp, offset) /* offset % fd_bsize */ \
- ((offset) & ((fdp)->fd_bsize - 1))
-#define fdir_lblkno(fdp, offset) /* offset / fd_bsize */ \
- ((offset) >> (fdp)->fd_bshift)
-
-#define fdir_fsbtodb(fdp, block) /* offset * fd_bsize / DEV_BSIZE */ \
- ((block) << (fdp)->fd_fsbtodb)
-
-/*
- * Read all or part of a data block, and
- * return a pointer to the appropriate part.
- * Caller must deallocate the block when done.
- */
-int
-page_read_file_direct(fdp, offset, size, addr, size_read)
- register struct file_direct *fdp;
- vm_offset_t offset;
- vm_size_t size;
- vm_offset_t *addr; /* out */
- mach_msg_type_number_t *size_read; /* out */
-{
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
-
- if (offset % DEV_BSIZE != 0 ||
- size % DEV_BSIZE != 0)
- panic("page_read_file_direct");
-
- if (offset >= (fdp->fd_size << fdp->fd_bshift))
- return (FS_NOT_IN_FILE);
-
- off = fdir_blkoff(fdp, offset);
- file_block = fdir_lblkno(fdp, offset);
-
- if (file_is_device(fdp)) {
- disk_block = file_block;
- } else {
- disk_block = fdp->fd_blocks[file_block];
- if (disk_block == 0)
- return (FS_NOT_IN_FILE);
-
- if (size > fdp->fd_bsize) {
- /* Read only as much as is contiguous on disk. */
- daddr_t b = file_block + 1;
- while (b < file_block + fdp->fd_size &&
- fdp->fd_blocks[b] == disk_block + fdir_fsbtodb(fdp, 1))
- ++b;
- size = (b - file_block) * fdp->fd_bsize;
- }
- }
-
- return (device_read(fdp->fd_dev,
- 0,
- (recnum_t) (fdir_fsbtodb(fdp, disk_block) + btodb(off)),
- (int) size,
- (char **) addr,
- size_read));
-}
-
-/*
- * Write all or part of a data block, and
- * return the amount written.
- */
-int
-page_write_file_direct(fdp, offset, addr, size, size_written)
- register struct file_direct *fdp;
- vm_offset_t offset;
- vm_offset_t addr;
- vm_size_t size;
- vm_offset_t *size_written; /* out */
-{
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
- int rc, num_written;
- vm_offset_t block_size;
-
- if (offset % DEV_BSIZE != 0 ||
- size % DEV_BSIZE != 0)
- panic("page_write_file");
-
- if (offset >= (fdp->fd_size << fdp->fd_bshift))
- return (FS_NOT_IN_FILE);
-
- off = fdir_blkoff(fdp, offset);
- file_block = fdir_lblkno(fdp, offset);
-
- if (file_is_device(fdp)) {
- disk_block = file_block;
- } else {
- disk_block = fdp->fd_blocks[file_block];
- if (disk_block == 0)
- return (FS_NOT_IN_FILE);
-
- if (size > fdp->fd_bsize) {
- /* Write only as much as is contiguous on disk. */
- daddr_t b = file_block + 1;
- while (b < file_block + fdp->fd_size &&
- fdp->fd_blocks[b] == disk_block + fdir_fsbtodb(fdp, 1))
- ++b;
- size = (b - file_block) * fdp->fd_bsize;
- }
- }
-
- /*
- * Write the data. Wait for completion to keep
- * reads from getting ahead of writes and reading
- * stale data.
- */
- rc = device_write(
- fdp->fd_dev,
- 0,
- (recnum_t) (fdir_fsbtodb(fdp, disk_block) + btodb(off)),
- (char *) addr,
- size,
- &num_written);
- *size_written = num_written;
- return rc;
-}
diff --git a/serverboot/file_io.h b/serverboot/file_io.h
deleted file mode 100644
index 323e4e9a..00000000
--- a/serverboot/file_io.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#ifndef _FILE_IO_H_
-#define _FILE_IO_H_
-
-/*
- * Read-only file IO.
- */
-
-#include <mach.h>
-#include <cthreads.h>
-
-#include <stdint.h>
-#include <device/device_types.h>
-
-/* Types used by the ext2 header files. */
-typedef u_int32_t __u32;
-typedef int32_t __s32;
-typedef u_int16_t __u16;
-typedef int16_t __s16;
-typedef u_int8_t __u8;
-typedef int8_t __s8;
-
-#include <defs.h>
-#include "minix_fs.h"
-#include "../ext2fs/ext2_fs.h" /* snarf stolen linux header from ext2fs */
-#include "disk_inode.h"
-
-#define BSD_FFS 0
-#define EXT2_FS 1
-#define MINIX_FS 2
-
-#define EXT2_NIADDR (EXT2_N_BLOCKS - EXT2_NDIR_BLOCKS)
-
-/*
- * In-core open file.
- */
-struct file {
- struct mutex f_lock; /* lock */
- mach_port_t f_dev; /* port to device */
- vm_offset_t f_buf; /* buffer for data block */
- vm_size_t f_buf_size; /* size of data block */
- daddr_t f_buf_blkno; /* block number of data block */
- vm_size_t f_size; /* size in bytes of the file */
-
- int f_fstype; /* contains fs-id */
-
- union {
- struct {
- struct fs * ffs_fs; /* pointer to super-block */
- struct icommon ffs_ic; /* copy of on-disk inode */
-
- /* number of blocks mapped by
- indirect block at level i */
- int ffs_nindir[FFS_NIADDR+1];
-
- /* buffer for indirect block at level i */
- vm_offset_t ffs_blk[FFS_NIADDR];
-
- /* size of buffer */
- vm_size_t ffs_blksize[FFS_NIADDR];
-
- /* disk address of block in buffer */
- daddr_t ffs_blkno[FFS_NIADDR];
- } ffs;
- struct {
- /* pointer to super-block */
- struct ext2_super_block*ext2_fs;
-
- /* pointer to group descriptors */
- struct ext2_group_desc* ext2_gd;
-
- /* size of group descriptors */
- vm_size_t ext2_gd_size;
-
- /* copy of on-disk inode */
- struct ext2_inode ext2_ic;
-
- /* number of blocks mapped by
- indirect block at level i */
- int ext2_nindir[EXT2_NIADDR+1];
-
- /* buffer for indirect block at level i */
- vm_offset_t ext2_blk[EXT2_NIADDR];
-
- /* size of buffer */
- vm_size_t ext2_blksize[EXT2_NIADDR];
-
- /* disk address of block in buffer */
- daddr_t ext2_blkno[EXT2_NIADDR];
- } ext2;
- struct {
- /* pointer to super-block */
- struct minix_super_block* minix_fs;
-
- /* copy of on-disk inode */
- struct minix_inode minix_ic;
-
- /* number of blocks mapped by
- indirect block at level i */
- int minix_nindir[MINIX_NIADDR+1];
-
- /* buffer for indirect block at level i */
- vm_offset_t minix_blk[MINIX_NIADDR];
-
- /* size of buffer */
- vm_size_t minix_blksize[MINIX_NIADDR];
-
- /* disk address of block in buffer */
- minix_daddr_t minix_blkno[MINIX_NIADDR];
- } minix;
- } u;
-};
-
-/*
- * In-core open file, with in-core block map.
- */
-struct file_direct {
- int f_fstype; /* XXX was: true if ext2, false if ffs */
-
- mach_port_t fd_dev; /* port to device */
- daddr_t * fd_blocks; /* array of disk block addresses */
- long fd_size; /* number of blocks in the array */
- long fd_bsize; /* disk block size */
- long fd_bshift; /* log2(fd_bsize) */
- long fd_fsbtodb; /* log2(fd_bsize / disk sector size) */
-};
-
-#define file_is_device(_fd_) ((_fd_)->fd_blocks == 0)
-
-/*
- * Exported routines.
- */
-
-extern int open_file();
-extern void close_file();
-extern int read_file();
-
-extern int open_file_direct();
-extern int add_file_direct();
-extern int remove_file_direct();
-extern int file_wire_direct();
-extern int page_read_file_direct();
-extern int page_write_file_direct();
-
-/*
- * Error codes for file system errors.
- */
-
-#include <errno.h>
-
-/* Just use the damn Hurd error numbers. This is old CMU/Utah code from
- the days of personality-independent Mach where it made sense for this to
- be a standalone universe. In the Hurd, we compile serverboot against
- the regular C library anyway. */
-
-#define FS_NOT_DIRECTORY ENOTDIR
-#define FS_NO_ENTRY ENOENT
-#define FS_NAME_TOO_LONG ENAMETOOLONG
-#define FS_SYMLINK_LOOP ELOOP
-#define FS_INVALID_FS EFTYPE /* ? */
-#define FS_NOT_IN_FILE EINVAL
-#define FS_INVALID_PARAMETER EINVAL
-
-#if 0
-#define FS_NOT_DIRECTORY 5000 /* not a directory */
-#define FS_NO_ENTRY 5001 /* name not found */
-#define FS_NAME_TOO_LONG 5002 /* name too long */
-#define FS_SYMLINK_LOOP 5003 /* symbolic link loop */
-#define FS_INVALID_FS 5004 /* bad file system */
-#define FS_NOT_IN_FILE 5005 /* offset not in file */
-#define FS_INVALID_PARAMETER 5006 /* bad parameter to routine */
-#endif
-
-
-#endif /* _FILE_IO_H_ */
diff --git a/serverboot/fs.h b/serverboot/fs.h
deleted file mode 100644
index 5809ed93..00000000
--- a/serverboot/fs.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)fs.h 7.7 (Berkeley) 5/9/89
- */
-
-/*
- * Each disk drive contains some number of file systems.
- * A file system consists of a number of cylinder groups.
- * Each cylinder group has inodes and data.
- *
- * A file system is described by its super-block, which in turn
- * describes the cylinder groups. The super-block is critical
- * data and is replicated in each cylinder group to protect against
- * catastrophic loss. This is done at `newfs' time and the critical
- * super-block data does not change, so the copies need not be
- * referenced further unless disaster strikes.
- *
- * For file system fs, the offsets of the various blocks of interest
- * are given in the super block as:
- * [fs->fs_sblkno] Super-block
- * [fs->fs_cblkno] Cylinder group block
- * [fs->fs_iblkno] Inode blocks
- * [fs->fs_dblkno] Data blocks
- * The beginning of cylinder group cg in fs, is given by
- * the ``cgbase(fs, cg)'' macro.
- *
- * The first boot and super blocks are given in absolute disk addresses.
- * The byte-offset forms are preferred, as they don't imply a sector size.
- */
-#define BBSIZE 8192
-#define SBSIZE 8192
-#define BBOFF ((off_t)(0))
-#define SBOFF ((off_t)(BBOFF + BBSIZE))
-#define BBLOCK ((daddr_t)(0))
-#define SBLOCK ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
-
-/*
- * Addresses stored in inodes are capable of addressing fragments
- * of `blocks'. File system blocks of at most size MAXBSIZE can
- * be optionally broken into 2, 4, or 8 pieces, each of which is
- * addressible; these pieces may be DEV_BSIZE, or some multiple of
- * a DEV_BSIZE unit.
- *
- * Large files consist of exclusively large data blocks. To avoid
- * undue wasted disk space, the last data block of a small file may be
- * allocated as only as many fragments of a large block as are
- * necessary. The file system format retains only a single pointer
- * to such a fragment, which is a piece of a single large block that
- * has been divided. The size of such a fragment is determinable from
- * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
- *
- * The file system records space availability at the fragment level;
- * to determine block availability, aligned fragments are examined.
- *
- * The root inode is the root of the file system.
- * Inode 0 can't be used for normal purposes and
- * historically bad blocks were linked to inode 1,
- * thus the root inode is 2. (inode 1 is no longer used for
- * this purpose, however numerous dump tapes make this
- * assumption, so we are stuck with it)
- */
-#define ROOTINO ((ino_t)2) /* i number of all roots */
-
-/*
- * MINBSIZE is the smallest allowable block size.
- * In order to insure that it is possible to create files of size
- * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
- * MINBSIZE must be big enough to hold a cylinder group block,
- * thus changes to (struct cg) must keep its size within MINBSIZE.
- * Note that super blocks are always of size SBSIZE,
- * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
- */
-#define MINBSIZE 4096
-
-/*
- * The path name on which the file system is mounted is maintained
- * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
- * the super block for this name.
- * The limit on the amount of summary information per file system
- * is defined by MAXCSBUFS. It is currently parameterized for a
- * maximum of two million cylinders.
- */
-#define MAXMNTLEN 512
-#define MAXCSBUFS 32
-
-/*
- * Per cylinder group information; summarized in blocks allocated
- * from first cylinder group data blocks. These blocks have to be
- * read in from fs_csaddr (size fs_cssize) in addition to the
- * super block.
- *
- * N.B. sizeof(struct csum) must be a power of two in order for
- * the ``fs_cs'' macro to work (see below).
- */
-struct csum {
- int cs_ndir; /* number of directories */
- int cs_nbfree; /* number of free blocks */
- int cs_nifree; /* number of free inodes */
- int cs_nffree; /* number of free frags */
-};
-
-/*
- * Super block for a file system.
- */
-#define FS_MAGIC 0x011954
-struct fs
-{
- int xxx1; /* struct fs *fs_link;*/
- int xxx2; /* struct fs *fs_rlink;*/
- daddr_t fs_sblkno; /* addr of super-block in filesys */
- daddr_t fs_cblkno; /* offset of cyl-block in filesys */
- daddr_t fs_iblkno; /* offset of inode-blocks in filesys */
- daddr_t fs_dblkno; /* offset of first data after cg */
- int fs_cgoffset; /* cylinder group offset in cylinder */
- int fs_cgmask; /* used to calc mod fs_ntrak */
- time_t fs_time; /* last time written */
- int fs_size; /* number of blocks in fs */
- int fs_dsize; /* number of data blocks in fs */
- int fs_ncg; /* number of cylinder groups */
- int fs_bsize; /* size of basic blocks in fs */
- int fs_fsize; /* size of frag blocks in fs */
- int fs_frag; /* number of frags in a block in fs */
-/* these are configuration parameters */
- int fs_minfree; /* minimum percentage of free blocks */
- int fs_rotdelay; /* num of ms for optimal next block */
- int fs_rps; /* disk revolutions per second */
-/* these fields can be computed from the others */
- int fs_bmask; /* ``blkoff'' calc of blk offsets */
- int fs_fmask; /* ``fragoff'' calc of frag offsets */
- int fs_bshift; /* ``lblkno'' calc of logical blkno */
- int fs_fshift; /* ``numfrags'' calc number of frags */
-/* these are configuration parameters */
- int fs_maxcontig; /* max number of contiguous blks */
- int fs_maxbpg; /* max number of blks per cyl group */
-/* these fields can be computed from the others */
- int fs_fragshift; /* block to frag shift */
- int fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
- int fs_sbsize; /* actual size of super block */
- int fs_csmask; /* csum block offset */
- int fs_csshift; /* csum block number */
- int fs_nindir; /* value of NINDIR */
- int fs_inopb; /* value of INOPB */
- int fs_nspf; /* value of NSPF */
-/* yet another configuration parameter */
- int fs_optim; /* optimization preference, see below */
-/* these fields are derived from the hardware */
- int fs_npsect; /* # sectors/track including spares */
- int fs_interleave; /* hardware sector interleave */
- int fs_trackskew; /* sector 0 skew, per track */
- int fs_headswitch; /* head switch time, usec */
- int fs_trkseek; /* track-to-track seek, usec */
-/* sizes determined by number of cylinder groups and their sizes */
- daddr_t fs_csaddr; /* blk addr of cyl grp summary area */
- int fs_cssize; /* size of cyl grp summary area */
- int fs_cgsize; /* cylinder group size */
-/* these fields are derived from the hardware */
- int fs_ntrak; /* tracks per cylinder */
- int fs_nsect; /* sectors per track */
- int fs_spc; /* sectors per cylinder */
-/* this comes from the disk driver partitioning */
- int fs_ncyl; /* cylinders in file system */
-/* these fields can be computed from the others */
- int fs_cpg; /* cylinders per group */
- int fs_ipg; /* inodes per group */
- int fs_fpg; /* blocks per group * fs_frag */
-/* this data must be re-computed after crashes */
- struct csum fs_cstotal; /* cylinder summary information */
-/* these fields are cleared at mount time */
- char fs_fmod; /* super block modified flag */
- char fs_clean; /* file system is clean flag */
- char fs_ronly; /* mounted read-only flag */
- char fs_flags; /* currently unused flag */
- char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
-/* these fields retain the current block allocation info */
- int fs_cgrotor; /* last cg searched */
-#if 1
- int was_fs_csp[MAXCSBUFS];
-#else
- struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
-#endif
- int fs_cpc; /* cyl per cycle in postbl */
- short fs_opostbl[16][8]; /* old rotation block list head */
- long fs_sparecon[50]; /* reserved for future constants */
- long fs_contigsumsize; /* size of cluster summary array */
- long fs_maxsymlinklen; /* max length of an internal symlink */
- long fs_inodefmt; /* format of on-disk inodes */
- quad fs_maxfilesize; /* maximum representable file size */
- quad fs_qbmask; /* ~fs_bmask - for use with quad size */
- quad fs_qfmask; /* ~fs_fmask - for use with quad size */
- long fs_state; /* validate fs_clean field */
- int fs_postblformat; /* format of positional layout tables */
- int fs_nrpos; /* number of rotaional positions */
- int fs_postbloff; /* (short) rotation block list head */
- int fs_rotbloff; /* (u_char) blocks for each rotation */
- int fs_magic; /* magic number */
- u_char fs_space[1]; /* list of blocks for each rotation */
-/* actually longer */
-};
-/*
- * Preference for optimization.
- */
-#define FS_OPTTIME 0 /* minimize allocation time */
-#define FS_OPTSPACE 1 /* minimize disk fragmentation */
-
-/*
- * Rotational layout table format types
- */
-#define FS_42POSTBLFMT -1 /* 4.2BSD rotational table format */
-#define FS_DYNAMICPOSTBLFMT 1 /* dynamic rotational table format */
-/*
- * Macros for access to superblock array structures
- */
-#define fs_postbl(fs, cylno) \
- (((fs)->fs_postblformat == FS_42POSTBLFMT) \
- ? ((fs)->fs_opostbl[cylno]) \
- : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
-#define fs_rotbl(fs) \
- (((fs)->fs_postblformat == FS_42POSTBLFMT) \
- ? ((fs)->fs_space) \
- : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
-
-/*
- * Convert cylinder group to base address of its global summary info.
- *
- * N.B. This macro assumes that sizeof(struct csum) is a power of two.
- */
-#define fs_cs(fs, indx) \
- fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
-
-/*
- * Cylinder group block for a file system.
- */
-#define CG_MAGIC 0x090255
-struct cg {
- int xxx1; /* struct cg *cg_link;*/
- int cg_magic; /* magic number */
- time_t cg_time; /* time last written */
- int cg_cgx; /* we are the cgx'th cylinder group */
- short cg_ncyl; /* number of cyl's this cg */
- short cg_niblk; /* number of inode blocks this cg */
- int cg_ndblk; /* number of data blocks this cg */
- struct csum cg_cs; /* cylinder summary information */
- int cg_rotor; /* position of last used block */
- int cg_frotor; /* position of last used frag */
- int cg_irotor; /* position of last used inode */
- int cg_frsum[MAXFRAG]; /* counts of available frags */
- int cg_btotoff; /* (long) block totals per cylinder */
- int cg_boff; /* (short) free block positions */
- int cg_iusedoff; /* (char) used inode map */
- int cg_freeoff; /* (u_char) free block map */
- int cg_nextfreeoff; /* (u_char) next available space */
- int cg_sparecon[16]; /* reserved for future use */
- u_char cg_space[1]; /* space for cylinder group maps */
-/* actually longer */
-};
-/*
- * Macros for access to cylinder group array structures
- */
-#define cg_blktot(cgp) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_btot) \
- : ((int *)((char *)(cgp) + (cgp)->cg_btotoff)))
-#define cg_blks(fs, cgp, cylno) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_b[cylno]) \
- : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
-#define cg_inosused(cgp) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_iused) \
- : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
-#define cg_blksfree(cgp) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_free) \
- : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
-#define cg_chkmagic(cgp) \
- ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
-
-/*
- * The following structure is defined
- * for compatibility with old file systems.
- */
-struct ocg {
- int xxx1; /* struct ocg *cg_link;*/
- int xxx2; /* struct ocg *cg_rlink;*/
- time_t cg_time; /* time last written */
- int cg_cgx; /* we are the cgx'th cylinder group */
- short cg_ncyl; /* number of cyl's this cg */
- short cg_niblk; /* number of inode blocks this cg */
- int cg_ndblk; /* number of data blocks this cg */
- struct csum cg_cs; /* cylinder summary information */
- int cg_rotor; /* position of last used block */
- int cg_frotor; /* position of last used frag */
- int cg_irotor; /* position of last used inode */
- int cg_frsum[8]; /* counts of available frags */
- int cg_btot[32]; /* block totals per cylinder */
- short cg_b[32][8]; /* positions of free blocks */
- char cg_iused[256]; /* used inode map */
- int cg_magic; /* magic number */
- u_char cg_free[1]; /* free block map */
-/* actually longer */
-};
-
-/*
- * Turn file system block numbers into disk block addresses.
- * This maps file system blocks to device size blocks.
- */
-#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb)
-#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb)
-
-/*
- * Cylinder group macros to locate things in cylinder groups.
- * They calc file system addresses of cylinder group data structures.
- */
-#define cgbase(fs, c) ((daddr_t)((fs)->fs_fpg * (c)))
-#define cgstart(fs, c) \
- (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
-#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
-#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
-#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
-#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
-
-/*
- * Macros for handling inode numbers:
- * inode number to file system block offset.
- * inode number to cylinder group number.
- * inode number to file system block address.
- */
-#define itoo(fs, x) ((x) % INOPB(fs))
-#define itog(fs, x) ((x) / (fs)->fs_ipg)
-#define itod(fs, x) \
- ((daddr_t)(cgimin(fs, itog(fs, x)) + \
- (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
-
-/*
- * Give cylinder group number for a file system block.
- * Give cylinder group block number for a file system block.
- */
-#define dtog(fs, d) ((d) / (fs)->fs_fpg)
-#define dtogd(fs, d) ((d) % (fs)->fs_fpg)
-
-/*
- * Extract the bits for a block from a map.
- * Compute the cylinder and rotational position of a cyl block addr.
- */
-#define blkmap(fs, map, loc) \
- (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
-#define cbtocylno(fs, bno) \
- ((bno) * NSPF(fs) / (fs)->fs_spc)
-#define cbtorpos(fs, bno) \
- (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
- (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
- (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
-
-/*
- * The following macros optimize certain frequently calculated
- * quantities by using shifts and masks in place of divisions
- * modulos and multiplications.
- */
-#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \
- ((loc) & ~(fs)->fs_bmask)
-#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
- ((loc) & ~(fs)->fs_fmask)
-#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \
- ((loc) >> (fs)->fs_bshift)
-#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
- ((loc) >> (fs)->fs_fshift)
-#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
- (((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
-#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
- (((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
-#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
- ((frags) >> (fs)->fs_fragshift)
-#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
- ((blks) << (fs)->fs_fragshift)
-#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \
- ((fsb) & ((fs)->fs_frag - 1))
-#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \
- ((fsb) &~ ((fs)->fs_frag - 1))
-
-/*
- * Determine the number of available frags given a
- * percentage to hold in reserve
- */
-#define freespace(fs, percentreserved) \
- (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
- (fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))
-
-/*
- * Determining the size of a file block in the file system.
- */
-#define blksize(fs, ip, lbn) \
- (((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \
- ? (fs)->fs_bsize \
- : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
-#define dblksize(fs, dip, lbn) \
- (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \
- ? (fs)->fs_bsize \
- : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
-
-/*
- * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
- */
-#define NSPB(fs) ((fs)->fs_nspf << (fs)->fs_fragshift)
-#define NSPF(fs) ((fs)->fs_nspf)
-
-/*
- * INOPB is the number of inodes in a secondary storage block.
- */
-#define INOPB(fs) ((fs)->fs_inopb)
-#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
-
-/*
- * NINDIR is the number of indirects in a file system block.
- */
-#define NINDIR(fs) ((fs)->fs_nindir)
-
diff --git a/serverboot/gets.c b/serverboot/gets.c
deleted file mode 100644
index 61d14460..00000000
--- a/serverboot/gets.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University.
- * Copyright (c) 1994 The University of Utah and
- * the Computer Systems Laboratory (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
- * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
- * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
- * THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#include <mach.h>
-#include <device/device.h>
-#include <varargs.h>
-
-extern mach_port_t __libmach_console_port;
-
-safe_gets(str, maxlen)
- char *str;
- int maxlen;
-{
- register char *lp;
- register int c;
-
- char inbuf[IO_INBAND_MAX];
- mach_msg_type_number_t count;
- register char *ip;
- char *strmax = str + maxlen - 1; /* allow space for trailing 0 */
-
- lp = str;
- for (;;) {
- count = IO_INBAND_MAX;
- (void) device_read_inband(__libmach_console_port,
- (dev_mode_t)0, (recnum_t)0,
- sizeof(inbuf), inbuf, &count);
- for (ip = inbuf; ip < &inbuf[count]; ip++) {
- c = *ip;
- switch (c) {
- case '\n':
- case '\r':
- printf("\n");
- *lp++ = 0;
- return;
-
- case '\b':
- case '#':
- case '\177':
- if (lp > str) {
- printf("\b \b");
- lp--;
- }
- continue;
- case '@':
- case 'u'&037:
- lp = str;
- printf("\n\r");
- continue;
- default:
- if (c >= ' ' && c < '\177') {
- if (lp < strmax) {
- *lp++ = c;
- printf("%c", c);
- }
- else {
- printf("%c", '\007'); /* beep */
- }
- }
- }
- }
- }
-}
-
diff --git a/serverboot/gunzip.c b/serverboot/gunzip.c
deleted file mode 100644
index f74da111..00000000
--- a/serverboot/gunzip.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Modified by okuji@kuicr.kyoto-u.ac.jp for use in serverboot. */
-/* Decompressing store backend
-
- Copyright (C) 1997 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include <stdio.h>
-#include <string.h>
-#include <setjmp.h>
-#include <cthreads.h>
-#include <errno.h>
-
-#include <file_io.h>
-
-/* gzip.h makes several annoying defines & decls, which we have to work
- around. */
-#define file_t gzip_file_t
-#include "gzip.h"
-#undef file_t
-#undef head
-
-#define IN_BUFFERING (256*1024)
-#define OUT_BUFFERING (512*1024)
-
-static struct mutex unzip_lock = MUTEX_INITIALIZER;
-
-/* Uncompress the contents of FROM, which should contain a valid gzip file,
- into memory, returning the result buffer in BUF & BUF_LEN. */
-int
-serverboot_gunzip (struct file *from, void **buf, size_t *buf_len)
-{
- /* Entry points to unzip engine. */
- int get_method (int);
- extern long int bytes_out;
- /* Callbacks from unzip for I/O and error interface. */
- extern int (*unzip_read) (char *buf, size_t maxread);
- extern void (*unzip_write) (const char *buf, size_t nwrite);
- extern void (*unzip_read_error) (void);
- extern void (*unzip_error) (const char *msg);
-
- /* How we return errors from our hook functions. */
- jmp_buf zerr_jmp_buf;
- int zerr;
-
- size_t offset = 0; /* Offset of read point in FROM. */
-
- /* Read at most MAXREAD (or 0 if eof) bytes into BUF from our current
- position in FROM. */
- int zread (char *buf, size_t maxread)
- {
- vm_size_t resid;
- size_t did_read;
-
- if (from->f_size - offset < maxread)
- did_read = from->f_size - offset;
- else
- did_read = maxread;
-
- zerr = read_file (from, offset, buf, did_read, &resid);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- did_read -= resid;
- offset += did_read;
-
- return did_read;
- }
-
- size_t out_buf_offs = 0; /* Position in the output buffer. */
-
- /* Write uncompress data to our output buffer. */
- void zwrite (const char *wbuf, size_t nwrite)
- {
- size_t old_buf_len = *buf_len;
-
- if (out_buf_offs + nwrite > old_buf_len)
- /* Have to grow the output buffer. */
- {
- void *old_buf = *buf;
- void *new_buf = old_buf + old_buf_len; /* First try. */
- size_t new_buf_len = round_page (old_buf_len + old_buf_len + nwrite);
-
- /* Try to grow the buffer. */
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len - old_buf_len,
- 0);
- if (zerr)
- /* Can't do that, try to make a bigger buffer elsewhere. */
- {
- new_buf = old_buf;
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len, 1);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- if (out_buf_offs > 0)
- /* Copy the old buffer into the start of the new & free it. */
- bcopy (old_buf, new_buf, out_buf_offs);
-
- vm_deallocate (mach_task_self (),
- (vm_address_t)old_buf, old_buf_len);
-
- *buf = new_buf;
- }
-
- *buf_len = new_buf_len;
- }
-
- bcopy (wbuf, *buf + out_buf_offs, nwrite);
- out_buf_offs += nwrite;
- }
-
- void zreaderr (void)
- {
- zerr = EIO;
- longjmp (zerr_jmp_buf, 1);
- }
- void zerror (const char *msg)
- {
- zerr = EINVAL;
- longjmp (zerr_jmp_buf, 2);
- }
-
- /* Try to guess a reasonable output buffer size. */
- *buf_len = round_page (from->f_size * 2);
- zerr = vm_allocate (mach_task_self (), (vm_address_t *)buf, *buf_len, 1);
- if (zerr)
- return zerr;
-
- mutex_lock (&unzip_lock);
-
- unzip_read = zread;
- unzip_write = zwrite;
- unzip_read_error = zreaderr;
- unzip_error = zerror;
-
- if (! setjmp (zerr_jmp_buf))
- {
- if (get_method (0) != 0)
- /* Not a happy gzip file. */
- zerr = EINVAL;
- else
- /* Matched gzip magic number. Ready to unzip.
- Set up the output stream and let 'er rip. */
- {
- /* Call the gunzip engine. */
- bytes_out = 0;
- unzip (17, 23); /* Arguments ignored. */
- zerr = 0;
- }
- }
-
- mutex_unlock (&unzip_lock);
-
- if (zerr)
- {
- if (*buf_len > 0)
- vm_deallocate (mach_task_self (), (vm_address_t)*buf, *buf_len);
- }
- else if (out_buf_offs < *buf_len)
- /* Trim the output buffer to be the right length. */
- {
- size_t end = round_page (out_buf_offs);
- if (end < *buf_len)
- vm_deallocate (mach_task_self (),
- (vm_address_t)(*buf + end), *buf_len - end);
- *buf_len = out_buf_offs;
- }
-
- return zerr;
-}
diff --git a/serverboot/kalloc.c b/serverboot/kalloc.c
deleted file mode 100644
index 28c0b55e..00000000
--- a/serverboot/kalloc.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: kern/kalloc.c
- * Author: Avadis Tevanian, Jr.
- * Date: 1985
- *
- * General kernel memory allocator. This allocator is designed
- * to be used by the kernel to manage dynamic memory fast.
- */
-
-#include <mach.h>
-#include <cthreads.h> /* for spin locks */
-#include <malloc.h> /* for malloc_hook/free_hook */
-
-static void init_hook (void);
-static void *malloc_hook (size_t size, const void *caller);
-static void free_hook (void *ptr, const void *caller);
-
-void (*__malloc_initialize_hook) (void) = init_hook;
-
-
-#define DEBUG
-
-/*
- * All allocations of size less than kalloc_max are rounded to the
- * next highest power of 2.
- */
-vm_size_t kalloc_max; /* max before we use vm_allocate */
-#define MINSIZE 4 /* minimum allocation size */
-
-struct free_list {
- spin_lock_t lock;
- vm_offset_t head; /* head of free list */
-#ifdef DEBUG
- int count;
-#endif /*DEBUG*/
-};
-
-#define KLIST_MAX 13
- /* sizes: 4, 8, 16, 32, 64,
- 128, 256, 512, 1024,
- 2048, 4096, 8192, 16384 */
-struct free_list kfree_list[KLIST_MAX];
-
-spin_lock_t kget_space_lock;
-vm_offset_t kalloc_next_space = 0;
-vm_offset_t kalloc_end_of_space = 0;
-
-vm_size_t kalloc_wasted_space = 0;
-
-boolean_t kalloc_initialized = FALSE;
-
-/*
- * Initialize the memory allocator. This should be called only
- * once on a system wide basis (i.e. first processor to get here
- * does the initialization).
- *
- * This initializes all of the zones.
- */
-
-void kalloc_init(void)
-{
- vm_offset_t min, max;
- vm_size_t size;
- register int i;
-
- /*
- * Support free lists for items up to vm_page_size or
- * 16Kbytes, whichever is less.
- */
-
- if (vm_page_size > 16*1024)
- kalloc_max = 16*1024;
- else
- kalloc_max = vm_page_size;
-
- for (i = 0; i < KLIST_MAX; i++) {
- spin_lock_init(&kfree_list[i].lock);
- kfree_list[i].head = 0;
- }
- spin_lock_init(&kget_space_lock);
-
- /*
- * Do not allocate memory at address 0.
- */
- kalloc_next_space = vm_page_size;
- kalloc_end_of_space = vm_page_size;
-}
-
-/*
- * Contiguous space allocator for items of less than a page size.
- */
-vm_offset_t kget_space(vm_offset_t size)
-{
- vm_size_t space_to_add;
- vm_offset_t new_space = 0;
- vm_offset_t addr;
-
- spin_lock(&kget_space_lock);
- while (kalloc_next_space + size > kalloc_end_of_space) {
- /*
- * Add at least one page to allocation area.
- */
- space_to_add = round_page(size);
-
- if (new_space == 0) {
- /*
- * Unlock and allocate memory.
- * Try to make it contiguous with the last
- * allocation area.
- */
- spin_unlock(&kget_space_lock);
-
- new_space = kalloc_end_of_space;
- if (vm_map(mach_task_self(),
- &new_space, space_to_add, (vm_offset_t) 0, TRUE,
- MEMORY_OBJECT_NULL, (vm_offset_t) 0, FALSE,
- VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT)
- != KERN_SUCCESS)
- return 0;
- wire_memory(new_space, space_to_add,
- VM_PROT_READ|VM_PROT_WRITE);
- spin_lock(&kget_space_lock);
- continue;
- }
-
- /*
- * Memory was allocated in a previous iteration.
- * Check whether the new region is contiguous with the
- * old one.
- */
- if (new_space != kalloc_end_of_space) {
- /*
- * Throw away the remainder of the old space,
- * and start a new one.
- */
- kalloc_wasted_space +=
- kalloc_end_of_space - kalloc_next_space;
- kalloc_next_space = new_space;
- }
- kalloc_end_of_space = new_space + space_to_add;
-
- new_space = 0;
- }
-
- addr = kalloc_next_space;
- kalloc_next_space += size;
- spin_unlock(&kget_space_lock);
-
- if (new_space != 0)
- (void) vm_deallocate(mach_task_self(), new_space, space_to_add);
-
- return addr;
-}
-
-void *kalloc(vm_size_t size)
-{
- register vm_size_t allocsize;
- vm_offset_t addr;
- register struct free_list *fl;
-
- if (!kalloc_initialized) {
- kalloc_init();
- kalloc_initialized = TRUE;
- }
-
- /* compute the size of the block that we will actually allocate */
-
- allocsize = size;
- if (size < kalloc_max) {
- allocsize = MINSIZE;
- fl = kfree_list;
- while (allocsize < size) {
- allocsize <<= 1;
- fl++;
- }
- }
-
- /*
- * If our size is still small enough, check the queue for that size
- * and allocate.
- */
-
- if (allocsize < kalloc_max) {
- spin_lock(&fl->lock);
- if ((addr = fl->head) != 0) {
- fl->head = *(vm_offset_t *)addr;
-#ifdef DEBUG
- fl->count--;
-#endif
- spin_unlock(&fl->lock);
- }
- else {
- spin_unlock(&fl->lock);
- addr = kget_space(allocsize);
- }
- }
- else {
- if (vm_allocate(mach_task_self(), &addr, allocsize, TRUE)
- != KERN_SUCCESS)
- addr = 0;
- }
- return (void *) addr;
-}
-
-void
-kfree( void *data,
- vm_size_t size)
-{
- register vm_size_t freesize;
- register struct free_list *fl;
-
- freesize = size;
- if (size < kalloc_max) {
- freesize = MINSIZE;
- fl = kfree_list;
- while (freesize < size) {
- freesize <<= 1;
- fl++;
- }
- }
-
- if (freesize < kalloc_max) {
- spin_lock(&fl->lock);
- *(vm_offset_t *)data = fl->head;
- fl->head = (vm_offset_t) data;
-#ifdef DEBUG
- fl->count++;
-#endif
- spin_unlock(&fl->lock);
- }
- else {
- (void) vm_deallocate(mach_task_self(), (vm_offset_t)data, freesize);
- }
-}
-
-static void
-init_hook (void)
-{
- __malloc_hook = malloc_hook;
- __free_hook = free_hook;
-}
-
-static void *
-malloc_hook (size_t size, const void *caller)
-{
- return (void *) kalloc ((vm_size_t) size);
-}
-
-static void
-free_hook (void *ptr, const void *caller)
-{
- /* Just ignore harmless attempts at cleanliness. */
- /* panic("free not implemented"); */
-}
-
-void malloc_fork_prepare()
-{
-}
-
-void malloc_fork_parent()
-{
-}
-
-void malloc_fork_child()
-{
-}
diff --git a/serverboot/load.c b/serverboot/load.c
deleted file mode 100644
index aa481943..00000000
--- a/serverboot/load.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#include <stddef.h>
-#include <assert.h>
-#include <mach/mach_interface.h>
-#include "mach-exec.h"
-#include "../boot/boot_script.h"
-
-#include <file_io.h>
-
-
-boolean_t load_protect_text = TRUE;
-
-
-struct stuff
-{
- struct file *fp;
- task_t user_task;
-
- /* uncompressed image */
- vm_offset_t image_addr;
- vm_size_t image_size;
-
- vm_offset_t aout_symtab_ofs;
- vm_size_t aout_symtab_size;
- vm_offset_t aout_strtab_ofs;
- vm_size_t aout_strtab_size;
-};
-
-char *set_regs(
- mach_port_t user_task,
- mach_port_t user_thread,
- struct exec_info *info,
- int arg_size);
-
-static void read_symtab_from_file(
- struct file *fp,
- mach_port_t host_port,
- task_t task,
- char * symtab_name,
- struct stuff *st);
-
-/* Callback functions for reading the executable file. */
-static int prog_read(void *handle, vm_offset_t file_ofs, void *buf, vm_size_t size,
- vm_size_t *out_actual)
-{
- struct stuff *st = handle;
- vm_size_t resid;
- int result;
-
- result = read_file(st->fp, file_ofs, buf, size, &resid);
- if (result)
- return result;
- *out_actual = size - resid;
- return 0;
-}
-
-static int prog_read_exec(void *handle, vm_offset_t file_ofs, vm_size_t file_size,
- vm_offset_t mem_addr, vm_size_t mem_size,
- exec_sectype_t sec_type)
-{
- struct stuff *st = handle;
- vm_offset_t page_start = trunc_page(mem_addr);
- vm_offset_t page_end = round_page(mem_addr + mem_size);
- vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK;
- vm_offset_t area_start;
- int result;
-
- if (sec_type & EXEC_SECTYPE_AOUT_SYMTAB)
- {
- st->aout_symtab_ofs = file_ofs;
- st->aout_symtab_size = file_size;
- }
- if (sec_type & EXEC_SECTYPE_AOUT_STRTAB)
- {
- st->aout_strtab_ofs = file_ofs;
- st->aout_strtab_size = file_size;
- }
-
- if (!(sec_type & EXEC_SECTYPE_ALLOC))
- return 0;
-
- assert(mem_size > 0);
- assert(mem_size > file_size);
-
- /*
- printf("section %08x-%08x-%08x prot %08x (%08x-%08x)\n",
- mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, page_start, page_end);
- */
-
- result = vm_allocate(mach_task_self(), &area_start, page_end - page_start, TRUE);
- if (result) return (result);
-
- if (file_size > 0)
- {
- vm_size_t resid;
-
- result = read_file(st->fp, file_ofs, area_start + (mem_addr - page_start),
- file_size, &resid);
- if (result) return result;
- if (resid) return EX_CORRUPT;
- }
-
- if (mem_size > file_size)
- {
- bzero((void*)area_start + (mem_addr + file_size - page_start),
- mem_size - file_size);
- }
-
- result = vm_allocate(st->user_task, &page_start, page_end - page_start, FALSE);
- if (result) return (result);
- assert(page_start == trunc_page(mem_addr));
-
- result = vm_write(st->user_task, page_start, area_start, page_end - page_start);
- if (result) return (result);
-
- result = vm_deallocate(mach_task_self(), area_start, page_end - page_start);
- if (result) return (result);
-
- /*
- * Protect the segment.
- */
- if (load_protect_text && (mem_prot != VM_PROT_ALL)) {
- result = vm_protect(st->user_task, page_start, page_end - page_start,
- FALSE, mem_prot);
- if (result) return (result);
- }
-
- return 0;
-}
-
-/* Callback functions for reading the uncompressed image. */
-static int image_read(void *handle, vm_offset_t file_ofs, void *buf,
- vm_size_t size, vm_size_t *out_actual)
-{
- struct stuff *st = handle;
- bcopy(st->image_addr + file_ofs, buf, size);
- *out_actual = size;
- return 0;
-}
-
-static int image_read_exec(void *handle, vm_offset_t file_ofs,
- vm_size_t file_size, vm_offset_t mem_addr,
- vm_size_t mem_size, exec_sectype_t sec_type)
-{
- struct stuff *st = handle;
- vm_offset_t page_start = trunc_page(mem_addr);
- vm_offset_t page_end = round_page(mem_addr + mem_size);
- vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK;
- vm_offset_t area_start;
- int result;
-
- if (sec_type & EXEC_SECTYPE_AOUT_SYMTAB)
- {
- st->aout_symtab_ofs = file_ofs;
- st->aout_symtab_size = file_size;
- }
- if (sec_type & EXEC_SECTYPE_AOUT_STRTAB)
- {
- st->aout_strtab_ofs = file_ofs;
- st->aout_strtab_size = file_size;
- }
-
- if (!(sec_type & EXEC_SECTYPE_ALLOC))
- return 0;
-
- assert(mem_size > 0);
- assert(mem_size > file_size);
-
- /*
- printf("section %08x-%08x-%08x prot %08x (%08x-%08x)\n",
- mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, page_start, page_end);
- */
-
- result = vm_allocate(mach_task_self(), &area_start, page_end - page_start, TRUE);
- if (result) return (result);
-
- if (file_size > 0)
- {
- bcopy(st->image_addr + file_ofs, area_start + (mem_addr - page_start),
- file_size);
- }
-
- if (mem_size > file_size)
- {
- bzero((void*)area_start + (mem_addr + file_size - page_start),
- mem_size - file_size);
- }
-
- result = vm_allocate(st->user_task, &page_start, page_end - page_start, FALSE);
- if (result) return (result);
- assert(page_start == trunc_page(mem_addr));
-
- result = vm_write(st->user_task, page_start, area_start, page_end - page_start);
- if (result) return (result);
-
- result = vm_deallocate(mach_task_self(), area_start, page_end - page_start);
- if (result) return (result);
-
- /*
- * Protect the segment.
- */
- if (load_protect_text && (mem_prot != VM_PROT_ALL)) {
- result = vm_protect(st->user_task, page_start, page_end - page_start,
- FALSE, mem_prot);
- if (result) return (result);
- }
-
- return 0;
-}
-
-mach_port_t boot_script_read_file (const char *file)
-{ return MACH_PORT_NULL; } /* XXX */
-
-int
-boot_script_exec_cmd (void *hook,
- task_t user_task,
- char *file_name,
- int arg_count, char **argv,
- char *argstrings, int argslen)
-{
- extern mach_port_t bootstrap_master_device_port, bootstrap_master_host_port;
- extern char *root_name;
- extern char **environ;
- int envc, env_len;
-
- int arg_len = argslen;
- char *arg_pos;
-
- kern_return_t result;
- thread_t user_thread;
- struct file file;
- char namebuf[MAXPATHLEN+1];
-
- struct stuff st;
- struct exec_info info;
-
- extern char * strbuild();
-
- if (strcmp (file_name, "/dev/"))
- (void) strbuild(namebuf, "/dev/", root_name, "/", file_name,
- (char *)0);
- else
- strcpy (namebuf, file_name);
-
- /*
- * Open the file
- */
- bzero((char *)&file, sizeof(file));
-
- result = open_file(bootstrap_master_device_port, namebuf, &file);
- if (result != 0) {
- panic ("%s: %s", namebuf, strerror (result));
- }
-
- env_len = 0;
- for (envc = 0; environ[envc]; ++envc)
- env_len += strlen (environ[envc]) + 1;
-
- /*
- * Add space for:
- * arg_count
- * pointers to arguments
- * trailing 0 pointer
- * environment variables
- * trailing 0 pointer
- * and align to integer boundary
- */
- arg_len += sizeof(integer_t) + (envc + 2 + arg_count) * sizeof(char *);
- arg_len += env_len;
- arg_len = (arg_len + (sizeof(integer_t) - 1)) & ~(sizeof(integer_t)-1);
-
- /*
- * We refrain from checking IEXEC bits to make
- * things a little easier when things went bad.
- * Say you have ftp(1) but chmod(1) is gone.
- */
- if (!file_is_regular(&file))
- panic("boot_load_program: %s is not a regular file", namebuf);
-
- /*
- * Load the executable file.
- */
- st.fp = &file;
- st.user_task = user_task;
- st.aout_symtab_size = 0;
- st.aout_strtab_size = 0;
- result = exec_load(prog_read, prog_read_exec, &st, &info);
-#ifdef GZIP
- if (result)
- {
- /*
- * It might be gzip file.
- */
- int err;
- extern int serverboot_gunzip(struct file *,
- vm_offset_t *, size_t *);
-
- err = serverboot_gunzip(st.fp,
- &(st.image_addr),
- &(st.image_size));
- if (!err)
- {
- result = exec_load(image_read,
- image_read_exec,
- &st,
- &info);
- vm_deallocate(mach_task_self(),
- st.image_addr,
- st.image_size);
- }
- }
-#endif /* GZIP */
-#ifdef BZIP2
- if (result)
- {
- /*
- * It might be bzip2 file.
- */
- int err;
- extern int serverboot_bunzip2(struct file *,
- vm_offset_t *, size_t *);
-
- err = serverboot_bunzip2(st.fp,
- &(st.image_addr),
- &(st.image_size));
- if (!err)
- {
- result = exec_load(image_read,
- image_read_exec,
- &st,
- &info);
- vm_deallocate(mach_task_self(),
- st.image_addr,
- st.image_size);
- }
- }
-#endif /* BZIP2 */
- if (result)
- panic ("cannot load %s: %s", namebuf, strerror (result));
-#if 0
- printf("(serverboot): loaded %s; entrypoint %08x\n", namebuf, info.entry);
-#endif
-
- /*
- * Set up the stack and user registers.
- */
- result = thread_create (user_task, &user_thread);
- if (result)
- panic ("can't create user thread for %s: %s", namebuf,
- strerror (result));
- arg_pos = set_regs(user_task, user_thread, &info, arg_len);
-
- /*
- * Read symbols from the executable file.
- */
-#if 0
- printf("(serverboot): loading symbols from %s\n", namebuf);
- read_symtab_from_file(&file, bootstrap_master_host_port, user_task, namebuf, &st);
-#endif
-
- /*
- * Copy out the arguments.
- */
- {
- vm_offset_t u_arg_start;
- /* user start of argument list block */
- vm_offset_t k_arg_start;
- /* kernel start of argument list block */
- vm_offset_t u_arg_page_start;
- /* user start of args, page-aligned */
- vm_size_t arg_page_size;
- /* page_aligned size of args */
- vm_offset_t k_arg_page_start;
- /* kernel start of args, page-aligned */
-
- register
- char ** k_ap; /* kernel arglist address */
- char * u_cp; /* user argument string address */
- register
- char * k_cp; /* kernel argument string address */
- register
- int i;
-
- /*
- * Get address of argument list in user space
- */
- u_arg_start = (vm_offset_t)arg_pos;
-
- /*
- * Round to page boundaries, and allocate kernel copy
- */
- u_arg_page_start = trunc_page(u_arg_start);
- arg_page_size = (vm_size_t)(round_page(u_arg_start + arg_len)
- - u_arg_page_start);
-
- result = vm_allocate(mach_task_self(),
- &k_arg_page_start,
- (vm_size_t)arg_page_size,
- TRUE);
- if (result)
- panic("boot_load_program: arg size");
-
- /*
- * Set up addresses corresponding to user pointers
- * in the kernel block
- */
- k_arg_start = k_arg_page_start + (u_arg_start - u_arg_page_start);
-
- k_ap = (char **)k_arg_start;
-
- /*
- * Start the strings after the arg-count and pointers
- */
- u_cp = (char *)u_arg_start + arg_count * sizeof(char *)
- + envc * sizeof(char *)
- + 2 * sizeof(char *)
- + sizeof(integer_t);
- k_cp = (char *)k_arg_start + arg_count * sizeof(char *)
- + envc * sizeof(char *)
- + 2 * sizeof(char *)
- + sizeof(integer_t);
-
- /*
- * first the argument count
- */
- *k_ap++ = (char *)(intptr_t)arg_count;
-
- /*
- * Then the strings and string pointers for each argument
- */
- for (i = 0; i < arg_count; i++)
- *k_ap++ = argv[i] - argstrings + u_cp;
- *k_ap++ = (char *)0;
- bcopy (argstrings, k_cp, argslen);
- k_cp += argslen;
- u_cp += argslen;
-
- for (i = 0; i < envc; i++)
- *k_ap++ = environ[i] - environ[0] + u_cp;
- *k_ap = (char *)0;
- bcopy (environ[0], k_cp, env_len);
-
- /*
- * Now write all of this to user space.
- */
- (void) vm_write(user_task,
- u_arg_page_start,
- k_arg_page_start,
- arg_page_size);
-
- (void) vm_deallocate(mach_task_self(),
- k_arg_page_start,
- arg_page_size);
- }
-
- /*
- * Close the file.
- */
- close_file(&file);
-
- /* Resume the thread. */
- thread_resume (user_thread);
- mach_port_deallocate (mach_task_self (), user_thread);
-
- return (0);
-}
-
-/*
- * Load symbols from file into kernel debugger.
- */
-static void read_symtab_from_file(
- struct file *fp,
- mach_port_t host_port,
- task_t task,
- char * symtab_name,
- struct stuff *st)
-{
- vm_size_t resid;
- kern_return_t result;
- vm_size_t table_size;
- vm_offset_t symtab;
-
-#if 0
-
- if (!st->aout_symtab_size || !st->aout_strtab_size)
- return;
-
- /*
- * Allocate space for the symbol table.
- */
- table_size = sizeof(vm_size_t)
- + st->aout_symtab_size
- + st->aout_strtab_size;
- result= vm_allocate(mach_task_self(),
- &symtab,
- table_size,
- TRUE);
- if (result) {
- printf("[ error %d allocating space for %s symbol table ]\n",
- result, symtab_name);
- return;
- }
-
- /*
- * Set the symbol table length word,
- * then read in the symbol table and string table.
- */
- *(vm_size_t*)symtab = st->aout_symtab_size;
- result = read_file(fp, st->aout_symtab_ofs,
- symtab + sizeof(vm_size_t),
- st->aout_symtab_size + st->aout_strtab_size,
- &resid);
- if (result || resid) {
- printf("[ no valid symbol table present for %s ]\n",
- symtab_name);
- }
- else {
- /*
- * Load the symbols into the kernel.
- */
- result = host_load_symbol_table(
- host_port,
- task,
- symtab_name,
- symtab,
- table_size);
- }
- (void) vm_deallocate(mach_task_self(), symtab, table_size);
-#endif
-}
diff --git a/serverboot/mach-exec.h b/serverboot/mach-exec.h
deleted file mode 100644
index 94b234b0..00000000
--- a/serverboot/mach-exec.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#ifndef _MACH_EXEC_H_
-#define _MACH_EXEC_H_
-
-#include <mach/machine/vm_types.h>
-#include <mach/vm_prot.h>
-
-/* XXX */
-typedef enum
-{
- EXEC_ELF = 1,
- EXEC_AOUT = 2,
-} exec_format_t;
-
-typedef struct exec_info
-{
- /* Format of executable loaded - see above. */
- exec_format_t format;
-
- /* Program entrypoint. */
- vm_offset_t entry;
-
- /* Initial data pointer - only some architectures use this. */
- vm_offset_t init_dp;
-
- /* (ELF) Address of interpreter string for loading shared libraries, null if none. */
- vm_offset_t interp;
-
-} exec_info_t;
-
-typedef int exec_sectype_t;
-#define EXEC_SECTYPE_READ VM_PROT_READ
-#define EXEC_SECTYPE_WRITE VM_PROT_WRITE
-#define EXEC_SECTYPE_EXECUTE VM_PROT_EXECUTE
-#define EXEC_SECTYPE_PROT_MASK VM_PROT_ALL
-#define EXEC_SECTYPE_ALLOC ((exec_sectype_t)0x000100)
-#define EXEC_SECTYPE_LOAD ((exec_sectype_t)0x000200)
-#define EXEC_SECTYPE_DEBUG ((exec_sectype_t)0x010000)
-#define EXEC_SECTYPE_AOUT_SYMTAB ((exec_sectype_t)0x020000)
-#define EXEC_SECTYPE_AOUT_STRTAB ((exec_sectype_t)0x040000)
-
-typedef int exec_read_func_t(void *handle, vm_offset_t file_ofs,
- void *buf, vm_size_t size,
- vm_size_t *out_actual);
-
-typedef int exec_read_exec_func_t(void *handle,
- vm_offset_t file_ofs, vm_size_t file_size,
- vm_offset_t mem_addr, vm_size_t mem_size,
- exec_sectype_t section_type);
-
-/*
- * Routines exported from libmach_exec.a
- */
-
-/* Generic function to interpret an executable "file"
- and "load" it into "memory".
- Doesn't really know about files, loading, or memory;
- all file I/O and destination memory accesses
- go through provided functions.
- Thus, this is a very generic loading mechanism.
-
- The read() function is used to read metadata from the file
- into the local address space.
-
- The read_exec() function is used to load the actual sections.
- It is used for all kinds of sections - code, data, bss, debugging data.
- The 'section_type' parameter specifies what type of section is being loaded.
-
- For code, data, and bss, the EXEC_SECTYPE_ALLOC flag will be set.
- For code and data (i.e. stuff that's actually loaded from the file),
- EXEC_SECTYPE_LOAD will also be set.
- The EXEC_SECTYPE_PROT_MASK contains the intended access permissions
- for the section.
- 'file_size' may be less than 'mem_size';
- the remaining data must be zero-filled.
- 'mem_size' is always greater than zero, but 'file_size' may be zero
- (e.g. in the case of a bss section).
- No two read_exec() calls for one executable
- will load data into the same virtual memory page,
- although they may load from arbitrary (possibly overlapping) file positions.
-
- For sections that aren't normally loaded into the process image
- (e.g. debug sections), EXEC_SECTYPE_ALLOC isn't set,
- but some other appropriate flag is set to indicate the type of section.
-
- The 'handle' is an opaque pointer which is simply passed on
- to the read() and read_exec() functions.
-
- On return, the specified info structure is filled in
- with information about the loaded executable.
-*/
-int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec,
- void *handle, exec_info_t *out_info);
-
-/*
- * Error codes
- */
-
-#define EX_NOT_EXECUTABLE 6000 /* not a recognized executable format */
-#define EX_WRONG_ARCH 6001 /* valid executable, but wrong arch. */
-#define EX_CORRUPT 6002 /* recognized executable, but mangled */
-#define EX_BAD_LAYOUT 6003 /* something wrong with the memory or file image layout */
-
-
-#endif /* _MACH_EXEC_H_ */
diff --git a/serverboot/minix_ffs_compat.c b/serverboot/minix_ffs_compat.c
deleted file mode 100644
index 7d493520..00000000
--- a/serverboot/minix_ffs_compat.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * BSD FFS like functions used to ease porting bootstrap to MINIX fs
- * Copyright (C) 1994 Csizmazia Balazs, University ELTE, Hungary
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include <file_io.h>
-
-#define MINIX_BLOCK_SIZE 1024
-
-int minix_ino2blk (struct minix_super_block *fs, int ino)
-{
- int blk;
-
- blk=0 /* it's Mach */+2 /* boot+superblock */ + fs->s_imap_blocks +
- fs->s_zmap_blocks + (ino-1)/MINIX_INODES_PER_BLOCK;
- return blk;
-}
-
-int minix_fsbtodb (struct minix_super_block *fs, int b)
-{
- return (b * MINIX_BLOCK_SIZE) / DEV_BSIZE;
-}
-
-int minix_itoo (struct minix_super_block *fs, int ino)
-{
- return (ino - 1) % MINIX_INODES_PER_BLOCK;
-}
-
-int minix_blkoff (struct minix_super_block * fs, vm_offset_t offset)
-{
- return offset % MINIX_BLOCK_SIZE;
-}
-
-int minix_lblkno (struct minix_super_block * fs, vm_offset_t offset)
-{
- return offset / MINIX_BLOCK_SIZE;
-}
-
-int minix_blksize (struct minix_super_block *fs, struct file *fp, minix_daddr_t file_block)
-{
- return MINIX_BLOCK_SIZE;
-}
diff --git a/serverboot/minix_ffs_compat.h b/serverboot/minix_ffs_compat.h
deleted file mode 100644
index cc038032..00000000
--- a/serverboot/minix_ffs_compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * BSD FFS like declarations used to ease porting bootstrap to MINIX fs
- * Copyright (C) 1994 Csizmazia Balazs, University ELTE, Hungary
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define MINIX_SBSIZE MINIX_BLOCK_SIZE /* Size of superblock */
-#define MINIX_SBLOCK ((minix_daddr_t) 2) /* Location of superblock */
-
-#define MINIX_NDADDR 7
-#define MINIX_NIADDR 2
-
-#define MINIX_MAXNAMLEN 14
-
-#define MINIX_ROOTINO 1 /* MINIX ROOT INODE */
-
-#define MINIX_NINDIR(fs) 512 /* DISK_ADDRESSES_PER_BLOCKS */
-
-#define IFMT 00170000
-#define IFREG 0100000
-#define IFDIR 0040000
-#define ISVTX 0001000
-
-#define f_fs u.minix.minix_fs
-#define i_ic u.minix.minix_ic
-#define f_nindir u.minix.minix_nindir
-#define f_blk u.minix.minix_blk
-#define f_blksize u.minix.minix_blksize
-#define f_blkno u.minix.minix_blkno
-
diff --git a/serverboot/minix_file_io.c b/serverboot/minix_file_io.c
deleted file mode 100644
index 17beb18c..00000000
--- a/serverboot/minix_file_io.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Stand-alone file reading package.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include "file_io.h"
-#include "minix_ffs_compat.h"
-#include "minix_fs.h"
-
-void minix_close_file(); /* forward */
-
-#define MINIX_NAME_LEN 14
-#define MINIX_BLOCK_SIZE 1024
-
-/*
- * Free file buffers, but don't close file.
- */
-static void
-free_file_buffers(fp)
- register struct file *fp;
-{
- register int level;
-
- /*
- * Free the indirect blocks
- */
- for (level = 0; level < MINIX_NIADDR; level++) {
- if (fp->f_blk[level] != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_blk[level],
- fp->f_blksize[level]);
- fp->f_blk[level] = 0;
- }
- fp->f_blkno[level] = -1;
- }
-
- /*
- * Free the data block
- */
- if (fp->f_buf != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
- fp->f_buf = 0;
- }
- fp->f_buf_blkno = -1;
-}
-
-/*
- * Read a new inode into a file structure.
- */
-static int
-read_inode(inumber, fp)
- ino_t inumber;
- register struct file *fp;
-{
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- register
- struct minix_super_block *fs;
- minix_daddr_t disk_block;
- kern_return_t rc;
-
- fs = fp->f_fs;
- disk_block = minix_ino2blk(fs, inumber);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) minix_fsbtodb(fp->f_fs, disk_block),
- (int) MINIX_BLOCK_SIZE,
- (char **)&buf,
- &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- {
- register struct minix_inode *dp;
-
- dp = (struct minix_inode *)buf;
- dp += minix_itoo(fs, inumber);
- fp->i_ic = *dp;
- fp->f_size = dp->i_size;
- }
-
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
-
- /*
- * Clear out the old buffers
- */
- free_file_buffers(fp);
-
- return (0);
-}
-
-/*
- * Given an offset in a file, find the disk block number that
- * contains that block.
- */
-static int
-block_map(fp, file_block, disk_block_p)
- struct file *fp;
- minix_daddr_t file_block;
- minix_daddr_t *disk_block_p; /* out */
-{
- int level;
- int idx;
- minix_daddr_t ind_block_num;
- kern_return_t rc;
-
- vm_offset_t olddata[MINIX_NIADDR+1];
- vm_size_t oldsize[MINIX_NIADDR+1];
-
- /*
- * Index structure of an inode:
- *
- * i_db[0..NDADDR-1] hold block numbers for blocks
- * 0..NDADDR-1
- *
- * i_ib[0] index block 0 is the single indirect
- * block
- * holds block numbers for blocks
- * NDADDR .. NDADDR + NINDIR(fs)-1
- *
- * i_ib[1] index block 1 is the double indirect
- * block
- * holds block numbers for INDEX blocks
- * for blocks
- * NDADDR + NINDIR(fs) ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
- *
- * i_ib[2] index block 2 is the triple indirect
- * block
- * holds block numbers for double-indirect
- * blocks for blocks
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2
- * + NINDIR(fs)**3 - 1
- */
-
- mutex_lock(&fp->f_lock);
-
- if (file_block < MINIX_NDADDR) {
- /* Direct block. */
- *disk_block_p = fp->i_ic.i_zone[file_block];
- mutex_unlock(&fp->f_lock);
- return (0);
- }
-
- file_block -= MINIX_NDADDR;
-
- /*
- * nindir[0] = NINDIR
- * nindir[1] = NINDIR**2
- * nindir[2] = NINDIR**3
- * etc
- */
- for (level = 0; level < MINIX_NIADDR; level++) {
- if (file_block < fp->f_nindir[level])
- break;
- file_block -= fp->f_nindir[level];
- }
- if (level == MINIX_NIADDR) {
- /* Block number too high */
- mutex_unlock(&fp->f_lock);
- return (FS_NOT_IN_FILE);
- }
-
- ind_block_num = fp->i_ic.i_zone[level + MINIX_NDADDR];
-
- /*
- * Initialize array of blocks to free.
- */
- for (idx = 0; idx < MINIX_NIADDR; idx++)
- oldsize[idx] = 0;
-
- for (; level >= 0; level--) {
-
- vm_offset_t data;
- mach_msg_type_number_t size;
-
- if (ind_block_num == 0)
- break;
-
- if (fp->f_blkno[level] == ind_block_num) {
- /*
- * Cache hit. Just pick up the data.
- */
-
- data = fp->f_blk[level];
- }
- else {
- /*
- * Drop our lock while doing the read.
- * (The f_dev and f_fs fields don`t change.)
- */
- mutex_unlock(&fp->f_lock);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) minix_fsbtodb(fp->f_fs, ind_block_num),
- MINIX_BLOCK_SIZE,
- (char **)&data,
- &size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- /*
- * See if we can cache the data. Need a write lock to
- * do this. While we hold the write lock, we can`t do
- * *anything* which might block for memory. Otherwise
- * a non-privileged thread might deadlock with the
- * privileged threads. We can`t block while taking the
- * write lock. Otherwise a non-privileged thread
- * blocked in the vm_deallocate (while holding a read
- * lock) will block a privileged thread. For the same
- * reason, we can`t take a read lock and then use
- * lock_read_to_write.
- */
-
- mutex_lock(&fp->f_lock);
-
- olddata[level] = fp->f_blk[level];
- oldsize[level] = fp->f_blksize[level];
-
- fp->f_blkno[level] = ind_block_num;
- fp->f_blk[level] = data;
- fp->f_blksize[level] = size;
-
- /*
- * Return to holding a read lock, and
- * dispose of old data.
- */
-
- }
-
- if (level > 0) {
- idx = file_block / fp->f_nindir[level-1];
- file_block %= fp->f_nindir[level-1];
- }
- else
- idx = file_block;
-
- ind_block_num = ((minix_daddr_t *)data)[idx];
- }
-
- mutex_unlock(&fp->f_lock);
-
- /*
- * After unlocking the file, free any blocks that
- * we need to free.
- */
- for (idx = 0; idx < MINIX_NIADDR; idx++)
- if (oldsize[idx] != 0)
- (void) vm_deallocate(mach_task_self(),
- olddata[idx],
- oldsize[idx]);
-
- *disk_block_p = ind_block_num;
- return (0);
-}
-
-/*
- * Read a portion of a file into an internal buffer. Return
- * the location in the buffer and the amount in the buffer.
- */
-static int
-buf_read_file(fp, offset, buf_p, size_p)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t *buf_p; /* out */
- vm_size_t *size_p; /* out */
-{
- register
- struct minix_super_block *fs;
- vm_offset_t off;
- register minix_daddr_t file_block;
- minix_daddr_t disk_block;
- int rc;
- vm_offset_t block_size;
-
- if (offset >= fp->i_ic.i_size)
- return (FS_NOT_IN_FILE);
-
- fs = fp->f_fs;
-
- off = minix_blkoff(fs, offset);
- file_block = minix_lblkno(fs, offset);
- block_size = minix_blksize(fs, fp, file_block);
-
- if (((daddr_t) file_block) != fp->f_buf_blkno) {
- rc = block_map(fp, file_block, &disk_block);
- if (rc != 0)
- return (rc);
-
- if (fp->f_buf)
- (void)vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
-
- if (disk_block == 0) {
- (void)vm_allocate(mach_task_self(),
- &fp->f_buf,
- block_size,
- TRUE);
- fp->f_buf_size = block_size;
- }
- else {
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) minix_fsbtodb(fs, disk_block),
- (int) block_size,
- (char **) &fp->f_buf,
- (mach_msg_type_number_t *)&fp->f_buf_size);
- }
- if (rc)
- return (rc);
-
- fp->f_buf_blkno = (daddr_t) file_block;
- }
-
- /*
- * Return address of byte in buffer corresponding to
- * offset, and size of remainder of buffer after that
- * byte.
- */
- *buf_p = fp->f_buf + off;
- *size_p = block_size - off;
-
- /*
- * But truncate buffer at end of file.
- */
- if (*size_p > fp->i_ic.i_size - offset)
- *size_p = fp->i_ic.i_size - offset;
-
- return (0);
-}
-
-/*
- * Search a directory for a name and return its
- * i_number.
- */
-static int
-search_directory(name, fp, inumber_p)
- char * name;
- register struct file *fp;
- ino_t *inumber_p; /* out */
-{
- vm_offset_t buf;
- vm_size_t buf_size;
- vm_offset_t offset;
- register struct minix_directory_entry *dp;
- int length;
- kern_return_t rc;
- char tmp_name[15];
-
- length = strlen(name);
-
- offset = 0;
- while (offset < fp->i_ic.i_size) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- dp = (struct minix_directory_entry *)buf;
- if (dp->inode != 0) {
- strncpy (tmp_name, dp->name, MINIX_NAME_LEN /* XXX it's 14 */);
- tmp_name[MINIX_NAME_LEN] = '\0';
- if (strlen(tmp_name) == length &&
- !strcmp(name, tmp_name))
- {
- /* found entry */
- *inumber_p = dp->inode;
- return (0);
- }
- }
- offset += 16 /* MINIX dir. entry length - MINIX FS Ver. 1. */;
- }
- return (FS_NO_ENTRY);
-}
-
-static int
-read_fs(dev, fsp)
- mach_port_t dev;
- struct minix_super_block **fsp;
-{
- register
- struct minix_super_block *fs;
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- int error;
-
- /*
- * Read the super block
- */
- error = device_read(dev, 0, (recnum_t) MINIX_SBLOCK, MINIX_SBSIZE,
- (char **) &buf, &buf_size);
- if (error)
- return (error);
-
- /*
- * Check the superblock
- */
- fs = (struct minix_super_block *)buf;
- if (fs->s_magic != MINIX_SUPER_MAGIC) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return (FS_INVALID_FS);
- }
-
-
- *fsp = fs;
-
- return 0;
-}
-
-static int
-mount_fs(fp)
- register struct file *fp;
-{
- register struct minix_super_block *fs;
- int error;
-
- error = read_fs(fp->f_dev, &fp->f_fs);
- if (error)
- return (error);
-
- fs = fp->f_fs;
-
- /*
- * Calculate indirect block levels.
- */
- {
- register int mult;
- register int level;
-
- mult = 1;
- for (level = 0; level < MINIX_NIADDR; level++) {
- mult *= MINIX_NINDIR(fs);
- fp->f_nindir[level] = mult;
- }
- }
-
- return (0);
-}
-
-static void
-unmount_fs(fp)
- register struct file *fp;
-{
- if (file_is_structured(fp)) {
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_fs,
- MINIX_SBSIZE);
- fp->f_fs = 0;
- }
-}
-
-/*
- * Open a file.
- */
-int
-minix_open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
-#define RETURN(code) { rc = (code); goto exit; }
-
- register char *cp, *component;
- register int c; /* char */
- register int rc;
- ino_t inumber, parent_inumber;
- int nlinks = 0;
-
- char namebuf[MAXPATHLEN+1];
-
- if (path == 0 || *path == '\0') {
- return FS_NO_ENTRY;
- }
-
- /*
- * Copy name into buffer to allow modifying it.
- */
- strcpy(namebuf, path);
-
- /*
- * Look for '/dev/xxx' at start of path, for
- * root device.
- */
- if (!strprefix(namebuf, "/dev/")) {
- printf("no device name\n");
- return FS_NO_ENTRY;
- }
-
- cp = namebuf + 5; /* device */
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- bzero (fp, sizeof (struct file));
-
- rc = device_open(master_device_port,
- D_READ|D_WRITE,
- component,
- &fp->f_dev);
- if (rc)
- return rc;
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return rc;
-
- inumber = (ino_t) MINIX_ROOTINO;
- if ((rc = read_inode(inumber, fp)) != 0) {
- printf("can't read root inode\n");
- goto exit;
- }
-
- while (*cp) {
-
- /*
- * Check that current node is a directory.
- */
- if ((fp->i_ic.i_mode & IFMT) != IFDIR)
- RETURN (FS_NOT_DIRECTORY);
-
- /*
- * Remove extra separators
- */
- while (*cp == '/')
- cp++;
-
- /*
- * Get next component of path name.
- */
- component = cp;
- {
- register int len = 0;
-
- while ((c = *cp) != '\0' && c != '/') {
- if (len++ > MINIX_MAXNAMLEN)
- RETURN (FS_NAME_TOO_LONG);
- if (c & 0200)
- RETURN (FS_INVALID_PARAMETER);
- cp++;
- }
- *cp = 0;
- }
-
- /*
- * Look up component in current directory.
- * Save directory inumber in case we find a
- * symbolic link.
- */
- parent_inumber = inumber;
- rc = search_directory(component, fp, &inumber);
- if (rc) {
- printf("%s: not found\n", path);
- goto exit;
- }
- *cp = c;
-
- /*
- * Open next component.
- */
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
-
- /*
- * Check for symbolic link.
- */
- }
-
- /*
- * Found terminal component.
- */
- out_ok:
- mutex_init(&fp->f_lock);
- return 0;
-
- /*
- * At error exit, close file to free storage.
- */
- exit:
- minix_close_file(fp);
- return rc;
-}
-
-/*
- * Close file - free all storage used.
- */
-void
-minix_close_file(fp)
- register struct file *fp;
-{
- register int i;
-
- /*
- * Free the disk super-block.
- */
- unmount_fs(fp);
-
- /*
- * Free the inode and data buffers.
- */
- free_file_buffers(fp);
-}
-
-int
-minix_file_is_directory(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFDIR;
-}
-
-int
-minix_file_is_regular(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFREG;
-}
-
-/*
- * Copy a portion of a file into kernel memory.
- * Cross block boundaries when necessary.
- */
-int
-minix_read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- int rc;
- register vm_size_t csize;
- vm_offset_t buf;
- vm_size_t buf_size;
-
- while (size != 0) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc)
- return (rc);
-
- csize = size;
- if (csize > buf_size)
- csize = buf_size;
- if (csize == 0)
- break;
-
- bcopy((char *)buf, (char *)start, csize);
-
- offset += csize;
- start += csize;
- size -= csize;
- }
- if (resid)
- *resid = size;
-
- return (0);
-}
-
-/* simple utility: only works for 2^n */
-static int
-log2(n)
- register unsigned int n;
-{
- register int i = 0;
-
- while ((n & 1) == 0) {
- i++;
- n >>= 1;
- }
- return i;
-}
-
-/*
- * Make an empty file_direct for a device.
- */
-int
-minix_open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- struct minix_super_block *fs;
- int rc;
-
- if (!is_structured) {
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_bsize = vm_page_size;
- fdp->fd_bshift = log2(vm_page_size);
- fdp->fd_fsbtodb = 0; /* later */
- fdp->fd_size = 0; /* later */
- return 0;
- }
-
- rc = read_fs(dev, &fs);
- if (rc)
- return rc;
-
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_size = 0;
- fdp->fd_bsize = MINIX_BLOCK_SIZE;
- fdp->fd_bshift = log2(fdp->fd_bsize);
- fdp->fd_fsbtodb = log2(fdp->fd_bsize / DEV_BSIZE);
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fs,
- MINIX_SBSIZE);
-
- return 0;
-}
-
-/*
- * Add blocks from a file to a file_direct.
- */
-int
-minix_add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- register struct minix_super_block *fs;
- long num_blocks, i;
- vm_offset_t buffer;
- vm_size_t size;
- int rc;
-
- /* the file must be on the same device */
-
- if (fdp->fd_dev != fp->f_dev)
- return FS_INVALID_FS;
-
- if (!file_is_structured(fp)) {
- int result[DEV_GET_SIZE_COUNT];
- natural_t count;
-
- count = DEV_GET_SIZE_COUNT;
- rc = device_get_status( fdp->fd_dev, DEV_GET_SIZE,
- result, &count);
- if (rc)
- return rc;
- fdp->fd_size = result[DEV_GET_SIZE_DEVICE_SIZE] >> fdp->fd_bshift;
- fdp->fd_fsbtodb = log2(fdp->fd_bsize/result[DEV_GET_SIZE_RECORD_SIZE]);
- return 0;
- }
-
- /* it must hold a file system */
-
- fs = fp->f_fs;
-/*
- if (fdp->fd_bsize != fs->fs_bsize ||
- fdp->fd_fsbtodb != fs->fs_fsbtodb)
-*/
- if (fdp->fd_bsize != MINIX_BLOCK_SIZE)
- return FS_INVALID_FS;
-
- /* calculate number of blocks in the file, ignoring fragments */
-
- num_blocks = minix_lblkno(fs, fp->i_ic.i_size);
-
- /* allocate memory for a bigger array */
-
- size = (num_blocks + fdp->fd_size) * sizeof(minix_daddr_t);
- rc = vm_allocate(mach_task_self(), &buffer, size, TRUE);
- if (rc != KERN_SUCCESS)
- return rc;
-
- /* lookup new block addresses */
-
- for (i = 0; i < num_blocks; i++) {
- minix_daddr_t disk_block;
-
- rc = block_map(fp, (minix_daddr_t) i, &disk_block);
- if (rc != 0) {
- (void) vm_deallocate(mach_task_self(), buffer, size);
- return rc;
- }
-
- ((minix_daddr_t *) buffer)[fdp->fd_size + i] = disk_block;
- }
-
- /* copy old addresses and install the new array */
-
- if (fdp->fd_blocks != 0) {
- bcopy((char *) fdp->fd_blocks, (char *) buffer,
- fdp->fd_size * sizeof(minix_daddr_t));
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(minix_daddr_t)));
- }
- fdp->fd_blocks = (daddr_t *) buffer;
- fdp->fd_size += num_blocks;
-
- /* deallocate cached blocks */
-
- free_file_buffers(fp);
-
- return 0;
-}
-
-int
-minix_remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- if (fdp->fd_blocks)
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(minix_daddr_t)));
- fdp->fd_blocks = 0; /* sanity */
- /* xxx should lose a ref to fdp->fd_dev here (and elsewhere) xxx */
-}
diff --git a/serverboot/minix_fs.h b/serverboot/minix_fs.h
deleted file mode 100644
index 678f3a0d..00000000
--- a/serverboot/minix_fs.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * minix_fs.h
- * stolen (and slightly extended by csb) from the Linux distribution
- * Copyright (C) 1994 Linus Torvalds
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _LINUX_MINIX_FS_H
-#define _LINUX_MINIX_FS_H
-
-/*
- * The minix filesystem constants/structures
- */
-
-/*
- * Thanks to Kees J Bot for sending me the definitions of the new
- * minix filesystem (aka V2) with bigger inodes and 32-bit block
- * pointers. It's not actually implemented yet, but I'll look into
- * it.
- */
-
-#define MINIX_ROOT_INO 1
-
-/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
-#define MINIX_LINK_MAX 250
-
-#define MINIX_I_MAP_SLOTS 8
-#define MINIX_Z_MAP_SLOTS 8
-#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
-#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
-#define NEW_MINIX_SUPER_MAGIC 0x2468 /* minix V2 - not implemented */
-#define MINIX_VALID_FS 0x0001 /* Clean fs. */
-#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
-
-#define MINIX_INODES_PER_BLOCK ((MINIX_BLOCK_SIZE)/(sizeof (struct minix_inode)))
-
-struct minix_inode {
- unsigned short i_mode;
- unsigned short i_uid;
- unsigned long i_size;
- unsigned long i_time;
- unsigned char i_gid;
- unsigned char i_nlinks;
- unsigned short i_zone[9];
-};
-
-/*
- * The new minix inode has all the time entries, as well as
- * long block numbers and a third indirect block (7+1+1+1
- * instead of 7+1+1). Also, some previously 8-bit values are
- * now 16-bit. The inode is now 64 bytes instead of 32.
- */
-struct new_minix_inode {
- unsigned short i_mode;
- unsigned short i_nlinks;
- unsigned short i_uid;
- unsigned short i_gid;
- unsigned long i_size;
- unsigned long i_atime;
- unsigned long i_mtime;
- unsigned long i_ctime;
- unsigned long i_zone[10];
-};
-
-/*
- * minix super-block data on disk
- */
-struct minix_super_block {
- unsigned short s_ninodes;
- unsigned short s_nzones;
- unsigned short s_imap_blocks;
- unsigned short s_zmap_blocks;
- unsigned short s_firstdatazone;
- unsigned short s_log_zone_size;
- unsigned long s_max_size;
- unsigned short s_magic;
- unsigned short s_state;
-};
-
-struct minix_dir_entry {
- unsigned short inode;
- char name[0];
-};
-
-struct minix_directory_entry {
- unsigned short inode;
- char name[14];
-};
-
-#define MINIX_NIADDR 2
-
-typedef unsigned short minix_daddr_t;
-
-#endif
diff --git a/serverboot/minix_super.h b/serverboot/minix_super.h
deleted file mode 100644
index 144cf064..00000000
--- a/serverboot/minix_super.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * minix_super.h
- * stolen from the Linux distribution
- * Copyright (C) 1994 Linus Torvalds
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _LINUX_MINIX_FS_H
-#define _LINUX_MINIX_FS_H
-
-struct minix_super_block {
- unsigned short s_ninodes;
- unsigned short s_nzones;
- unsigned short s_imap_blocks;
- unsigned short s_zmap_blocks;
- unsigned short s_firstdatazone;
- unsigned short s_log_zone_size;
- unsigned long s_max_size;
- unsigned short s_magic;
- unsigned short s_state;
-};
-
-
-struct minix_inode {
- unsigned short i_mode;
- unsigned short i_uid;
- unsigned long i_size;
- unsigned long i_time;
- unsigned char i_gid;
- unsigned char i_nlinks;
- unsigned short i_zone[9];
-};
-
-#define MINIX_NIADDR 2
-
-#endif
diff --git a/serverboot/panic.c b/serverboot/panic.c
deleted file mode 100644
index 25924099..00000000
--- a/serverboot/panic.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#include <mach/port.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <errno.h>
-
-static mach_port_t master_host_port;
-
-panic_init(port)
- mach_port_t port;
-{
- master_host_port = port;
-}
-
-/*VARARGS1*/
-panic (const char *s, ...)
-{
- va_list listp;
-
- clearerr (stdout);
- printf("%s: panic: ", program_invocation_name);
- va_start(listp, s);
- vprintf(s, listp);
- va_end(listp);
- printf("\n");
-
-#ifdef PC532
- { int l; for (l=0;l < 1000000;l++) ; }
-#endif /* PC532 */
-#define RB_DEBUGGER 0x1000 /* enter debugger NOW */
- (void) host_reboot(master_host_port, RB_DEBUGGER);
- for (;;);
-}
diff --git a/serverboot/queue.h b/serverboot/queue.h
deleted file mode 100644
index 00619174..00000000
--- a/serverboot/queue.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon rights
- * to redistribute these changes.
- */
-/*
- * File: queue.h
- * Author: Avadis Tevanian, Jr.
- * Date: 1985
- *
- * Type definitions for generic queues.
- *
- */
-
-#ifndef _QUEUE_H_
-#define _QUEUE_H_
-
-/*
- * Queue of abstract objects. Queue is maintained
- * within that object.
- *
- * Supports fast removal from within the queue.
- *
- * How to declare a queue of elements of type "foo_t":
- * In the "*foo_t" type, you must have a field of
- * type "queue_chain_t" to hold together this queue.
- * There may be more than one chain through a
- * "foo_t", for use by different queues.
- *
- * Declare the queue as a "queue_t" type.
- *
- * Elements of the queue (of type "foo_t", that is)
- * are referred to by reference, and cast to type
- * "queue_entry_t" within this module.
- */
-
-/*
- * A generic doubly-linked list (queue).
- */
-
-struct queue_entry {
- struct queue_entry *next; /* next element */
- struct queue_entry *prev; /* previous element */
-};
-
-typedef struct queue_entry *queue_t;
-typedef struct queue_entry queue_head_t;
-typedef struct queue_entry queue_chain_t;
-typedef struct queue_entry *queue_entry_t;
-
-/*
- * Macro: queue_init
- * Function:
- * Initialize the given queue.
- * Header:
- * void queue_init(q)
- * queue_t q; / * MODIFIED * /
- */
-#define queue_init(q) ((q)->next = (q)->prev = q)
-
-/*
- * Macro: queue_first
- * Function:
- * Returns the first entry in the queue,
- * Header:
- * queue_entry_t queue_first(q)
- * queue_t q; / * IN * /
- */
-#define queue_first(q) ((q)->next)
-
-/*
- * Macro: queue_next
- * Function:
- * Returns the entry after an item in the queue.
- * Header:
- * queue_entry_t queue_next(qc)
- * queue_t qc;
- */
-#define queue_next(qc) ((qc)->next)
-
-/*
- * Macro: queue_last
- * Function:
- * Returns the last entry in the queue.
- * Header:
- * queue_entry_t queue_last(q)
- * queue_t q; / * IN * /
- */
-#define queue_last(q) ((q)->prev)
-
-/*
- * Macro: queue_prev
- * Function:
- * Returns the entry before an item in the queue.
- * Header:
- * queue_entry_t queue_prev(qc)
- * queue_t qc;
- */
-#define queue_prev(qc) ((qc)->prev)
-
-/*
- * Macro: queue_end
- * Function:
- * Tests whether a new entry is really the end of
- * the queue.
- * Header:
- * boolean_t queue_end(q, qe)
- * queue_t q;
- * queue_entry_t qe;
- */
-#define queue_end(q, qe) ((q) == (qe))
-
-/*
- * Macro: queue_empty
- * Function:
- * Tests whether a queue is empty.
- * Header:
- * boolean_t queue_empty(q)
- * queue_t q;
- */
-#define queue_empty(q) queue_end((q), queue_first(q))
-
-
-/*----------------------------------------------------------------*/
-/*
- * Macros that operate on generic structures. The queue
- * chain may be at any location within the structure, and there
- * may be more than one chain.
- */
-
-/*
- * Macro: queue_enter
- * Function:
- * Insert a new element at the tail of the queue.
- * Header:
- * void queue_enter(q, elt, type, field)
- * queue_t q;
- * <type> elt;
- * <type> is what's in our queue
- * <field> is the chain field in (*<type>)
- */
-#define queue_enter(head, elt, type, field) \
-{ \
- register queue_entry_t prev; \
- \
- prev = (head)->prev; \
- if ((head) == prev) { \
- (head)->next = (queue_entry_t) (elt); \
- } \
- else { \
- ((type)prev)->field.next = (queue_entry_t)(elt);\
- } \
- (elt)->field.prev = prev; \
- (elt)->field.next = head; \
- (head)->prev = (queue_entry_t) elt; \
-}
-
-/*
- * Macro: queue_enter_first
- * Function:
- * Insert a new element at the head of the queue.
- * Header:
- * void queue_enter_first(q, elt, type, field)
- * queue_t q;
- * <type> elt;
- * <type> is what's in our queue
- * <field> is the chain field in (*<type>)
- */
-#define queue_enter_first(head, elt, type, field) \
-{ \
- register queue_entry_t next; \
- \
- next = (head)->next; \
- if ((head) == next) { \
- (head)->prev = (queue_entry_t) (elt); \
- } \
- else { \
- ((type)next)->field.prev = (queue_entry_t)(elt);\
- } \
- (elt)->field.next = next; \
- (elt)->field.prev = head; \
- (head)->next = (queue_entry_t) elt; \
-}
-
-/*
- * Macro: queue_field [internal use only]
- * Function:
- * Find the queue_chain_t (or queue_t) for the
- * given element (thing) in the given queue (head)
- */
-#define queue_field(head, thing, type, field) \
- (((head) == (thing)) ? (head) : &((type)(thing))->field)
-
-/*
- * Macro: queue_remove
- * Function:
- * Remove an arbitrary item from the queue.
- * Header:
- * void queue_remove(q, qe, type, field)
- * arguments as in queue_enter
- */
-#define queue_remove(head, elt, type, field) \
-{ \
- register queue_entry_t next, prev; \
- \
- next = (elt)->field.next; \
- prev = (elt)->field.prev; \
- \
- if ((head) == next) \
- (head)->prev = prev; \
- else \
- ((type)next)->field.prev = prev; \
- \
- if ((head) == prev) \
- (head)->next = next; \
- else \
- ((type)prev)->field.next = next; \
-}
-
-/*
- * Macro: queue_remove_first
- * Function:
- * Remove and return the entry at the head of
- * the queue.
- * Header:
- * queue_remove_first(head, entry, type, field)
- * entry is returned by reference
- */
-#define queue_remove_first(head, entry, type, field) \
-{ \
- register queue_entry_t next; \
- \
- (entry) = (type) ((head)->next); \
- next = (entry)->field.next; \
- \
- if ((head) == next) \
- (head)->prev = (head); \
- else \
- ((type)(next))->field.prev = (head); \
- (head)->next = next; \
-}
-
-/*
- * Macro: queue_remove_last
- * Function:
- * Remove and return the entry at the tail of
- * the queue.
- * Header:
- * queue_remove_last(head, entry, type, field)
- * entry is returned by reference
- */
-#define queue_remove_last(head, entry, type, field) \
-{ \
- register queue_entry_t prev; \
- \
- (entry) = (type) ((head)->prev); \
- prev = (entry)->field.prev; \
- \
- if ((head) == prev) \
- (head)->next = (head); \
- else \
- ((type)(prev))->field.next = (head); \
- (head)->prev = prev; \
-}
-
-/*
- * Macro: queue_assign
- */
-#define queue_assign(to, from, type, field) \
-{ \
- ((type)((from)->prev))->field.next = (to); \
- ((type)((from)->next))->field.prev = (to); \
- *to = *from; \
-}
-
-/*
- * Macro: queue_iterate
- * Function:
- * iterate over each item in the queue.
- * Generates a 'for' loop, setting elt to
- * each item in turn (by reference).
- * Header:
- * queue_iterate(q, elt, type, field)
- * queue_t q;
- * <type> elt;
- * <type> is what's in our queue
- * <field> is the chain field in (*<type>)
- */
-#define queue_iterate(head, elt, type, field) \
- for ((elt) = (type) queue_first(head); \
- !queue_end((head), (queue_entry_t)(elt)); \
- (elt) = (type) queue_next(&(elt)->field))
-
-
-
-#endif /* _QUEUE_H_ */
diff --git a/serverboot/strfcns.c b/serverboot/strfcns.c
deleted file mode 100644
index cbead7e4..00000000
--- a/serverboot/strfcns.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Character subroutines
- */
-
-#include <stdarg.h>
-
-#define EXPORT_BOOLEAN
-#include <mach/boolean.h>
-
-/*
- * Concatenate a group of strings together into a buffer.
- * Return a pointer to the trailing '\0' character in
- * the result string.
- * The list of strings ends with a '(char *)0'.
- */
-/*VARARGS1*/
-char *
-strbuild(char *dest, ...)
-{
- va_list argptr;
- register char * src;
- register int c;
-
- va_start(argptr, dest);
- while ((src = va_arg(argptr, char *)) != (char *)0) {
-
- while ((c = *src++) != '\0')
- *dest++ = c;
- }
- *dest = '\0';
- va_end(argptr);
- return (dest);
-}
-
-/*
- * Return TRUE if string 2 is a prefix of string 1.
- */
-boolean_t
-strprefix(s1, s2)
- register char *s1, *s2;
-{
- register int c;
-
- while ((c = *s2++) != '\0') {
- if (c != *s1++)
- return (FALSE);
- }
- return (TRUE);
-}
diff --git a/serverboot/wiring.c b/serverboot/wiring.c
deleted file mode 100644
index 585a3075..00000000
--- a/serverboot/wiring.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Package to wire current task's memory.
- */
-#include <mach.h>
-#include <mach_init.h>
-#include <mach/machine/vm_param.h>
-
-mach_port_t this_task; /* our task */
-mach_port_t priv_host_port = MACH_PORT_NULL;
- /* the privileged host port */
-
-void
-wire_setup(host_priv)
- mach_port_t host_priv;
-{
- priv_host_port = host_priv;
- this_task = mach_task_self();
-}
-
-void
-wire_memory(start, size, prot)
- vm_address_t start;
- vm_size_t size;
- vm_prot_t prot;
-{
- kern_return_t kr;
-
- if (priv_host_port == MACH_PORT_NULL)
- return;
-
- kr = vm_wire(priv_host_port,
- this_task,
- start, size, prot);
- if (kr != KERN_SUCCESS)
- panic("mem_wire: %d", kr);
-}
-
-void
-wire_thread()
-{
- kern_return_t kr;
-
- if (priv_host_port == MACH_PORT_NULL)
- return;
-
- kr = thread_wire(priv_host_port,
- mach_thread_self(),
- TRUE);
- if (kr != KERN_SUCCESS)
- panic("wire_thread: %d", kr);
-}
-
-void
-wire_all_memory()
-{
- register kern_return_t kr;
- vm_offset_t address;
- vm_size_t size;
- vm_prot_t protection;
- vm_prot_t max_protection;
- vm_inherit_t inheritance;
- boolean_t is_shared;
- memory_object_name_t object;
- vm_offset_t offset;
-
- if (priv_host_port == MACH_PORT_NULL)
- return;
-
- /* iterate thru all regions, wiring */
- address = 0;
- while (
- (kr = vm_region(this_task, &address,
- &size,
- &protection,
- &max_protection,
- &inheritance,
- &is_shared,
- &object,
- &offset))
- == KERN_SUCCESS)
- {
- if (MACH_PORT_VALID(object))
- (void) mach_port_deallocate(this_task, object);
- if (protection != VM_PROT_NONE)
- {
- /* The VM system cannot cope with a COW fault on another
- unrelated virtual copy happening later when we have
- wired down the original page. So we must touch all our
- pages before wiring to make sure that only we will ever
- use them. */
- void *page;
- if (!(protection & VM_PROT_WRITE))
- {
- kr = vm_protect(this_task, address, size,
- 0, max_protection);
- }
- for (page = (void *) address;
- page < (void *) (address + size);
- page += vm_page_size)
- *(volatile int *) page = *(int *) page;
-
- wire_memory(address, size, protection);
-
- if (!(protection & VM_PROT_WRITE))
- {
- kr = vm_protect(this_task, address, size,
- 0, protection);
- }
- }
- address += size;
- }
-}
-
-/*
- * Alias for vm_allocate to return wired memory.
- */
-kern_return_t
-vm_allocate(task, address, size, anywhere)
- task_t task;
- vm_address_t *address;
- vm_size_t size;
- boolean_t anywhere;
-{
- kern_return_t kr;
-
- if (anywhere)
- *address = VM_MIN_ADDRESS;
- kr = vm_map(task,
- address, size, (vm_offset_t) 0, anywhere,
- MEMORY_OBJECT_NULL, (vm_offset_t)0, FALSE,
- VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
- if (kr != KERN_SUCCESS)
- return kr;
-
- if (task == this_task)
- (void) vm_wire(priv_host_port, task, *address, size,
- VM_PROT_DEFAULT);
- return KERN_SUCCESS;
-}
-
-/* Other versions of this function in libc... */
-kern_return_t
-__vm_allocate (task, address, size, anywhere)
- task_t task;
- vm_address_t *address;
- vm_size_t size;
- boolean_t anywhere;
-{
- return vm_allocate (task, address, size, anywhere);
-}
diff --git a/serverboot/wiring.h b/serverboot/wiring.h
deleted file mode 100644
index b5f8e53f..00000000
--- a/serverboot/wiring.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon the
- * rights to redistribute these changes.
- */
-/*
- * Package to wire current task's memory.
- */
-#include <mach.h>
-#include <mach_init.h>
-
-extern void wire_setup(/* mach_port_t host_priv */);
-extern void wire_memory(/* vm_address_t, vm_size_t, vm_prot_t */);
-extern void wire_thread();
-extern void wire_all_memory();
diff --git a/ufs-fsck/utilities.c b/ufs-fsck/utilities.c
index 5e081fe8..14705f84 100644
--- a/ufs-fsck/utilities.c
+++ b/ufs-fsck/utilities.c
@@ -270,7 +270,7 @@ retch (char *reason)
static void
punt (char *msg)
{
- problem (0, msg);
+ problem (0, "%s", msg);
flush_problems ();
exit (8);
}
diff --git a/ufs/Makefile b/ufs/Makefile
index 02cf38ba..cf5c40d7 100644
--- a/ufs/Makefile
+++ b/ufs/Makefile
@@ -21,7 +21,7 @@ makemode := server
target = ufs
SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \
- sizes.c subr.c tables.c bmap.c pokeloc.c
+ sizes.c subr.c tables.c bmap.c pokeloc.c xinl.c
LCLHDRS = ufs.h fs.h dinode.h dir.h
OBJS = $(SRCS:.c=.o)
diff --git a/ufs/alloc.c b/ufs/alloc.c
index 48ee60cc..d8f92255 100644
--- a/ufs/alloc.c
+++ b/ufs/alloc.c
@@ -215,7 +215,7 @@ release_cg (struct cg *cgp)
* 3) allocate a block in the same cylinder group.
* 4) quadradically rehash into other cylinder groups, until an
* available block is located.
- * If no block preference is given the following heirarchy is used
+ * If no block preference is given the following hierarchy is used
* to allocate a block:
* 1) allocate a block in the cylinder group that contains the
* inode for the file.
@@ -472,7 +472,7 @@ nospace:
* logical blocks to be made contiguous is given. The allocator attempts
* to find a range of sequential blocks starting as close as possible to
* an fs_rotdelay offset from the end of the allocation for the logical
- * block immediately preceeding the current range. If successful, the
+ * block immediately preceding the current range. If successful, the
* physical block numbers in the buffer pointers and in the inode are
* changed to reflect the new allocation. If unsuccessful, the allocation
* is left unchanged. The success in doing the reallocation is returned.
@@ -638,7 +638,7 @@ fail:
* 2) allocate an inode in the same cylinder group.
* 3) quadradically rehash into other cylinder groups, until an
* available inode is located.
- * If no inode preference is given the following heirarchy is used
+ * If no inode preference is given the following hierarchy is used
* to allocate an inode:
* 1) allocate an inode in cylinder group 0.
* 2) quadradically rehash into other cylinder groups, until an
diff --git a/ufs/dir.c b/ufs/dir.c
index 7a8cfa55..3c5f152a 100644
--- a/ufs/dir.c
+++ b/ufs/dir.c
@@ -664,7 +664,7 @@ diskfs_direnter_hard(struct node *dp,
/* Following a lookup call for REMOVE, this removes the link from the
directory. DP is the directory being changed and DS is the cached
information returned from lookup. This call is only valid if the
- directory has been locked continously since the call to lookup, and
+ directory has been locked continuously since the call to lookup, and
only if that call succeeded. */
error_t
diskfs_dirremove_hard(struct node *dp,
diff --git a/ufs/inode.c b/ufs/inode.c
index 1a8a7098..77a45edb 100644
--- a/ufs/inode.c
+++ b/ufs/inode.c
@@ -181,7 +181,7 @@ diskfs_lost_hardrefs (struct node *np)
spin_unlock (&_libports_portrefcntlock);
/* Right now the node is locked with no hard refs;
- this is an anomolous situation. Before messing with
+ this is an anomalous situation. Before messing with
the reference count on the file pager, we have to
give ourselves a reference back so that we are really
allowed to hold the lock. Then we can do the
diff --git a/ufs/ufs.h b/ufs/ufs.h
index 5d823ebc..f59784d5 100644
--- a/ufs/ufs.h
+++ b/ufs/ufs.h
@@ -25,9 +25,16 @@
#include <hurd/diskfs.h>
#include <sys/mman.h>
#include <assert.h>
+#include <features.h>
#include "fs.h"
#include "dinode.h"
+#ifdef UFS_DEFINE_EI
+#define UFS_EI
+#else
+#define UFS_EI __extern_inline
+#endif
+
/* Define this if memory objects should not be cached by the kernel.
Normally, don't define it, but defining it causes a much greater rate
of paging requests, which may be helpful in catching bugs. */
@@ -150,8 +157,18 @@ unsigned log2_dev_blocks_per_dev_bsize;
/* Functions for looking inside disk_image */
+extern struct dinode * dino (ino_t inum);
+extern daddr_t * indir_block (daddr_t bno);
+extern struct cg * cg_locate (int ncg);
+extern void sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait);
+extern void sync_dinode (int inum, int wait);
+extern short swab_short (short arg);
+extern long swab_long (long arg);
+extern long long swab_long_long (long long arg);
+
+#if defined(__USE_EXTERN_INLINES) || defined(UFS_DEFINE_EI)
/* Convert an inode number to the dinode on disk. */
-extern inline struct dinode *
+UFS_EI struct dinode *
dino (ino_t inum)
{
return (struct dinode *)
@@ -161,28 +178,28 @@ dino (ino_t inum)
}
/* Convert a indirect block number to a daddr_t table. */
-extern inline daddr_t *
+UFS_EI daddr_t *
indir_block (daddr_t bno)
{
return (daddr_t *) (disk_image + fsaddr (sblock, bno));
}
/* Convert a cg number to the cylinder group. */
-extern inline struct cg *
+UFS_EI struct cg *
cg_locate (int ncg)
{
return (struct cg *) (disk_image + fsaddr (sblock, cgtod (sblock, ncg)));
}
/* Sync part of the disk */
-extern inline void
+UFS_EI void
sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait)
{
pager_sync_some (diskfs_disk_pager, fsaddr (sblock, blkno), nbytes, wait);
}
/* Sync an disk inode */
-extern inline void
+UFS_EI void
sync_dinode (int inum, int wait)
{
sync_disk_blocks (ino_to_fsba (sblock, inum), sblock->fs_fsize, wait);
@@ -190,26 +207,27 @@ sync_dinode (int inum, int wait)
/* Functions for byte swapping */
-extern inline short
+UFS_EI short
swab_short (short arg)
{
return (((arg & 0xff) << 8)
| ((arg & 0xff00) >> 8));
}
-extern inline long
+UFS_EI long
swab_long (long arg)
{
return (((long) swab_short (arg & 0xffff) << 16)
| swab_short ((arg & 0xffff0000) >> 16));
}
-extern inline long long
+UFS_EI long long
swab_long_long (long long arg)
{
return (((long long) swab_long (arg & 0xffffffff) << 32)
| swab_long ((arg & 0xffffffff00000000LL) >> 32));
}
+#endif /* Use extern inlines. */
/* Return ENTRY, after byteswapping it if necessary */
#define read_disk_entry(entry) \
diff --git a/ufs/xinl.c b/ufs/xinl.c
new file mode 100644
index 00000000..7994a1f7
--- /dev/null
+++ b/ufs/xinl.c
@@ -0,0 +1,2 @@
+#define UFS_DEFINE_EI
+#include "ufs.h"