diff options
119 files changed, 6758 insertions, 18666 deletions
diff --git a/README.CVS b/README.CVS new file mode 100644 index 00000000..92a2392d --- /dev/null +++ b/README.CVS @@ -0,0 +1,29 @@ +-*- Text -*- +GNU Hurd CVS version. + + +This is the Hurd. Welcome. + +For installation instructions, you might try your luck with the files +README, INSTALL, and INSTALL-cross. However, they have not been +updated for a long time. + +For now, this file documents the version requirements for the CVS +version of the Hurd. Other combinations might work, but the stated +minimum requirements are best tested by the developers. + +GNU MiG at least 1.3 +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. @@ -1,11 +0,0 @@ -#!/bin/bash -# Setup critical hurd translators - -set -v - -# Set up the PFLOCAL server so we can do pipes -/bin/settrans -c /servers/socket/1 /hurd/pflocal - -# Setup crucial devices -cd /dev -/bin/sh ./MAKEDEV std diff --git a/bsdfsck/ChangeLog b/bsdfsck/ChangeLog deleted file mode 100644 index 0a948518..00000000 --- a/bsdfsck/ChangeLog +++ /dev/null @@ -1,98 +0,0 @@ -Thu Jul 6 15:30:43 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile (tables.o): Delete target. - (vpath tables.c): Tell where to find tables.c. - - * Makefile: Removed dependencies that are now automatically - generated. - -Thu Nov 3 17:18:35 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (dir): Changed to bsdfsck. - (target): Changed to bsdfsck. - -Thu Oct 6 13:19:25 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * dir.c (dircheck): Fix from Charles Hannum: dircheck() shouldn't - be looking at d_type or d_namlen in blank entries *at all*. Not - only is it wrong, but it causes a serious problem on little-endian - machines, since after -c2 conversion, d_type will often be > 15. - -Wed Oct 5 12:53:45 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * pass1.c (checkinode) [mode == 0]: Check that di_trans - is also clear here. - - * fsck.h (IFTODT): Provide macro here. - * inode.c: Not here. - -Tue Oct 4 22:42:54 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (ckinode) [dino.di_trans set]: Only call IDESC->id_func - if IDESC->id_type is ADDR (meaning call function for each block). - If it's DATA, then that means call dirscan on each data block, - something entirely different. - - * inode.c (IFTODT): Provide macro. - -Fri Sep 30 21:28:57 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (LCLHDRS): Define. - -Fri Sep 16 10:57:04 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * fsck.h (direct): Define macro. - -Thu Sep 1 14:51:23 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (ckinode): Don't pay attention to fs_maxsymlinklen - if it's -1. - * pass1.c (checkinode): Likewise. - - * fsck.h (DI_MODE): Use | not & for bitwise disjunction. - -Fri Aug 26 12:35:21 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * main.c (main): Don't call checkblock. - - * pass5.c (ffs_fragacct): Copy in function from ../ufs/subr.c. - - * inode.c (ckinode): Call IDESC->id_func for passive translator - if it's set. - -Thu Aug 25 11:07:05 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * setup.c: Don't include <disklabel.h>. - (setup): Comment out variable LP and label fetching code. - (calcsb, getdisklabel): Comment out functions. Replace - calcsb with one returning constant zero. - - * main.c: Don't include <sys/mount.h> or <fstab.h>. - (main): Don't run checkfstab; just print an error in that case. - (docheck): Comment out this function. - (checkfilesys): Comment out special code for HOTROOT. - -Wed Aug 24 11:11:23 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * fsck.h (NBBY): Define macro. - -Tue Aug 23 15:54:49 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * dir.c (fileerror): Use DI_MODE instead of di_mode member. - (adjust): Likewise. - (linkup): Likewise. - * inode.c (ckinode): Likewise. - (clri): Likewise. - (pinode): Likewise. - * pass1.c (checkinode): Likewise. - * pass2.c (pass2check): Likewise. - * utilities.c (ftypeok): Likewise. - - * inode.c (allocino): Set di_model and di_modeh instead of di_mode. - * pass1.c (checkinode): Likewise. - * pass2.c (pass2): Likewise. - - * fsck.h (DIRSIZ): Replace ufs version with old BSD version. - (struct dirtemplate, struct odirtemplate): Proved old BSD types. - (DEV_BSIZE, MAXPATHLEN): Provide definitions. - (DI_MODE): New macro. 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 new file mode 100755 index 00000000..1fab7980 --- /dev/null +++ b/configure @@ -0,0 +1,5868 @@ +#! /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 for GNU Hurd 0.3. +# +# Report bugs to <bug-hurd@gnu.org>. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $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 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 +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +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= +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +HAVE_SUN_RPC +LIBNCURSESW +NCURSESW_INCLUDE +boot_store_types +PARTED_LIBS +EGREP +GREP +CPP +libc_cv_gnu89_inline +VERSIONING +LIBCRYPT +MIG +RANLIB +AR +OBJCOPY +LD +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AWK +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +enable_static_progs +enable_profile +asm_syntax +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_profile +enable_static_progs +with_parted +enable_boot_store_types +enable_ncursesw +with_ncursesw_include_dir +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +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 GNU Hurd 0.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --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/hurd] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_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: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-profile do not build profiled libraries and programs + --enable-static-progs=PROGRAMS... + build statically-linked PROGRAM.static versions + of (only) the listed programs ext2fs,ufs + --enable-boot-store-types=TYPES... + list of store types included in statically + linked filesystems used for booting + --disable-ncursesw Do not use ncursesw + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-parted disable user-space partition stores + --with-ncursesw-include-dir=DIR + Set directory containing the include files for + use with -lncursesw, when it isn't installed as + the default curses library. If DIR is "none", + then no special ncursesw include files are used. + --without-ncursesw-include-dir + Equivalent to --with-ncursesw-include-dir=none + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + +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 <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 + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GNU Hurd configure 0.3 +generated by GNU Autoconf 2.67 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* 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 $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval "test \"\${$3+set}\"" = set; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&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;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$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 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile +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 GNU Hurd $as_me 0.3, which was +generated by GNU Autoconf 2.67. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $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; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +case "$host_os" in +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 ;; +*) 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 ;; +esac + +case "$host_cpu" in +alpha*) + asm_syntax=alpha + ;; +arm*) + asm_syntax=arm + ;; +m68k | m680?0) + asm_syntax=m68k + ;; +mips*) + asm_syntax=mips + ;; +i?86) + asm_syntax=i386 + ;; +powerpc*) + asm_syntax=ppc + ;; +sparc64* | ultrasparc*) + asm_syntax=sparc64 + ;; +sparc*) + asm_syntax=sparc + ;; +*) + asm_syntax="$host_cpu" + ;; +esac + + +test -r "$srcdir/libthreads/$asm_syntax/cthreads.h" || { + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unsupported CPU type $host_cpu" >&5 +$as_echo "$as_me: WARNING: unsupported CPU type $host_cpu" >&2;} +} + +# Check whether --enable-profile was given. +if test "${enable_profile+set}" = set; then : + enableval=$enable_profile; +fi + + + +# Check whether --enable-static-progs was given. +if test "${enable_static_progs+set}" = set; then : + enableval=$enable_static_progs; +fi + +case "$enable_static_progs" in +'no') enable_static_progs= ;; # we got --disable-static +'') enable_static_progs='ext2fs,ufs' ;; +esac +# Convert comma/space-separated list into space-separated list. +enable_static_progs=`echo "$enable_static_progs" | sed 's/[, ][, ]*/ /g'` + + +# Don't needlessly overwrite files that whose contents haven't changed. This +# helps for avoinding unneccessary recompilation cycles when keeping +# cross-compilation toolchains up-to-date. Thus, unconditionally use the +# supplied `install-sh', as the GNU Coreutils one doesn't provide this +# functionality yet (TODO: change that). TODO: $ac_abs_top_builddir et al. are +# not yet available here, that's why we use `readlink' (but only if available). +INSTALL="$SHELL $(readlink -f "$ac_install_sh")"\ -C || unset INSTALL +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +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; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +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; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +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; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + 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 run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +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; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Require GCC. +if test x$GCC != xyes; then + as_fn_error $? "this code uses GNU C extensions, you must compile with GCC" "$LINENO" 5 +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. +set dummy ${ac_tool_prefix}ld; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LD="${ac_tool_prefix}ld" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LD=$ac_cv_prog_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LD"; then + ac_ct_LD=$LD + # Extract the first word of "ld", so it can be a program name with args. +set dummy ld; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LD"; then + ac_cv_prog_ac_ct_LD="$ac_ct_LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LD="ld" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LD=$ac_cv_prog_ac_ct_LD +if test -n "$ac_ct_LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LD" >&5 +$as_echo "$ac_ct_LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LD" = x; then + LD="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LD=$ac_ct_LD + fi +else + LD="$ac_cv_prog_LD" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJCOPY+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCOPY" >&5 +$as_echo "$OBJCOPY" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCOPY" >&5 +$as_echo "$ac_ct_OBJCOPY" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJCOPY" = x; then + OBJCOPY="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJCOPY=$ac_ct_OBJCOPY + fi +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mig", so it can be a program name with args. +set dummy ${ac_tool_prefix}mig; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_MIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MIG"; then + ac_cv_prog_MIG="$MIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MIG="${ac_tool_prefix}mig" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MIG=$ac_cv_prog_MIG +if test -n "$MIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MIG" >&5 +$as_echo "$MIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MIG"; then + ac_ct_MIG=$MIG + # Extract the first word of "mig", so it can be a program name with args. +set dummy mig; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_MIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MIG"; then + ac_cv_prog_ac_ct_MIG="$ac_ct_MIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MIG="mig" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MIG=$ac_cv_prog_ac_ct_MIG +if test -n "$ac_ct_MIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MIG" >&5 +$as_echo "$ac_ct_MIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MIG" = x; then + MIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MIG=$ac_ct_MIG + fi +else + MIG="$ac_cv_prog_MIG" +fi + +# Require MiG. +if test x${MIG} = x; then + as_fn_error $? " +*** You need GNU MiG to compile the GNU Hurd, please see +*** http://www.gnu.org/software/hurd/mig.html for further details, or +*** download it directly from the main GNU server (ftp.gnu.org) or any +*** GNU mirror." "$LINENO" 5 +fi + + + +# See if there's a separate libcrypt (many systems put crypt there). + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 +$as_echo_n "checking for crypt in -lcrypt... " >&6; } +if test "${ac_cv_lib_crypt_crypt+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypt $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 crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypt_crypt=yes +else + ac_cv_lib_crypt_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 +$as_echo "$ac_cv_lib_crypt_crypt" >&6; } +if test "x$ac_cv_lib_crypt_crypt" = x""yes; then : + LIBCRYPT=-lcrypt +fi + + + +# See if mig groks `retcode'. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $MIG supports the retcode keyword" >&5 +$as_echo_n "checking whether $MIG supports the retcode keyword... " >&6; } +if test "${hurd_cv_mig_retcode+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.defs <<\EOF +#include <mach/std_types.defs> +#include <mach/mach_types.defs> +subsystem foobar 1000; +type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE + ctype: mach_port_t; +simpleroutine foobar_reply ( + reply_port: reply_port_t; + err: kern_return_t, RetCode); +EOF +if { ac_try='CC="${CC}" ${MIG-false} -n conftest.defs 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + hurd_cv_mig_retcode=yes +else + hurd_cv_mig_retcode=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_mig_retcode" >&5 +$as_echo "$hurd_cv_mig_retcode" >&6; } +if test $hurd_cv_mig_retcode = yes; then + $as_echo "#define HAVE_MIG_RETCODE 1" >>confdefs.h + +fi + +# See if --version-script is available. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld --version-script" >&5 +$as_echo_n "checking for ld --version-script... " >&6; } +if test "${hurd_cv_ld_version_script_option+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <<\EOF +void foobar() {} +EOF +cat > conftest.map <<\EOF +VERS_1 { + global: sym; +}; + +VERS_2 { + global: sym; +} VERS_1; +EOF + +if { ac_try='eval $ac_compile 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } && + { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o + -nostartfiles -nostdlib + -Wl,--version-script,conftest.map + 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + hurd_cv_ld_version_script_option=yes +else + hurd_cv_ld_version_script_option=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_ld_version_script_option" >&5 +$as_echo "$hurd_cv_ld_version_script_option" >&6; } + +# See if libc was built with --enable-libio. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libio" >&5 +$as_echo_n "checking for libio... " >&6; } +if test "${hurd_cv_libio+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +#ifndef _STDIO_USES_IOSTREAM +# error No libio found. +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + hurd_cv_libio=yes +else + hurd_cv_libio=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_libio" >&5 +$as_echo "$hurd_cv_libio" >&6; } + +# The versions of the symbols in libthreads have to match those in +# libc.so. Since the symbols in a libc that includes libio will be +# versioned differently from the ones in a libc that uses stdio, this +# isn't easy to accomplish. Instead we leave things unversioned if +# libio isn't found. +if test $hurd_cv_libio = yes; then + VERSIONING=$hurd_cv_ld_version_script_option +else + VERSIONING=no +fi + + +# Check if libc contains getgrouplist and/or uselocale. +for ac_func in getgrouplist uselocale +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +# From glibc HEAD, 2007-11-07. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fgnu89-inline" >&5 +$as_echo_n "checking for -fgnu89-inline... " >&6; } +if test "${libc_cv_gnu89_inline+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <<EOF +int foo; +#ifdef __GNUC_GNU_INLINE__ +main () { return 0;} +#else +#error +#endif +EOF +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S -std=gnu99 -fgnu89-inline + -o conftest.s conftest.c 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then + libc_cv_gnu89_inline=yes +else + libc_cv_gnu89_inline=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gnu89_inline" >&5 +$as_echo "$libc_cv_gnu89_inline" >&6; } +if test $libc_cv_gnu89_inline = yes; then + libc_cv_gnu89_inline=-fgnu89-inline +else + libc_cv_gnu89_inline= +fi + + + +# Insist on libparted unless the user declines explicitely + +# Check whether --with-parted was given. +if test "${with_parted+set}" = set; then : + withval=$with_parted; +else + with_parted=yes +fi + + +PARTED_LIBS= + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +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; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +if test "x$with_parted" != xno; then : + + ac_fn_c_check_header_mongrel "$LINENO" "parted/parted.h" "ac_cv_header_parted_parted_h" "$ac_includes_default" +if test "x$ac_cv_header_parted_parted_h" = x""yes; then : + $as_echo "#define HAVE_PARTED_PARTED_H 1" >>confdefs.h + +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; } + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ped_device_read in -lparted" >&5 +$as_echo_n "checking for ped_device_read in -lparted... " >&6; } +if test "${ac_cv_lib_parted_ped_device_read+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lparted $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 ped_device_read (); +int +main () +{ +return ped_device_read (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_parted_ped_device_read=yes +else + ac_cv_lib_parted_ped_device_read=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_parted_ped_device_read" >&5 +$as_echo "$ac_cv_lib_parted_ped_device_read" >&6; } +if test "x$ac_cv_lib_parted_ped_device_read" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPARTED 1 +_ACEOF + + LIBS="-lparted $LIBS" + +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; } + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5 +$as_echo_n "checking for uuid_generate in -luuid... " >&6; } +if test "${ac_cv_lib_uuid_uuid_generate+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $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 uuid_generate (); +int +main () +{ +return uuid_generate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_uuid_uuid_generate=yes +else + ac_cv_lib_uuid_uuid_generate=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5 +$as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUUID 1 +_ACEOF + + LIBS="-luuid $LIBS" + +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; } + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +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; } + +fi + + PARTED_LIBS="-lparted -luuid -ldl" + +fi + + +# Check whether --enable-boot-store-types was given. +if test "${enable_boot_store_types+set}" = set; then : + enableval=$enable_boot_store_types; +fi +if test -z "$enable_boot_store_types"; then + boot_store_types='device remap gunzip bunzip2' + test -z "$PARTED_LIBS" || boot_store_types="$boot_store_types part" +elif test "x$enable_boot_store_types" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: you probably wanted --disable-static-progs" >&5 +$as_echo "$as_me: WARNING: you probably wanted --disable-static-progs" >&2;} +else + boot_store_types="$enable_boot_store_types" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking boot store types" >&5 +$as_echo_n "checking boot store types... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_store_types" >&5 +$as_echo "$boot_store_types" >&6; } + +# Check for ncursesw, which is needed for the console-curses client. + + # Check whether --enable-ncursesw was given. +if test "${enable_ncursesw+set}" = set; then : + enableval=$enable_ncursesw; +else + enable_ncursesw=yes +fi + + if test "$enable_ncursesw" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5 +$as_echo_n "checking for initscr in -lncursesw... " >&6; } +if test "${ac_cv_lib_ncursesw_initscr+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncursesw $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 initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncursesw_initscr=yes +else + ac_cv_lib_ncursesw_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5 +$as_echo "$ac_cv_lib_ncursesw_initscr" >&6; } +if test "x$ac_cv_lib_ncursesw_initscr" = x""yes; then : + LIBNCURSESW="-lncursesw" +fi + + if test "$LIBNCURSESW"; then + +# Check whether --with-ncursesw-include-dir was given. +if test "${with_ncursesw_include_dir+set}" = set; then : + withval=$with_ncursesw_include_dir; +fi + if test "${with_ncursesw_include_dir+set}" = set; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ncursesw include dir" >&5 +$as_echo_n "checking for ncursesw include dir... " >&6; } + case "$with_ncursesw_include_dir" in + no|none) + hurd_cv_includedir_ncursesw=none;; + *) + hurd_cv_includedir_ncursesw="$with_ncursesw_include_dir";; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_includedir_ncursesw" >&5 +$as_echo "$hurd_cv_includedir_ncursesw" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ncursesw include dir" >&5 +$as_echo_n "checking for ncursesw include dir... " >&6; } +if test "${hurd_cv_includedir_ncursesw+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + for D in $includedir $prefix/include /local/include /usr/local/include /include /usr/include; do + if test -d $D/ncursesw; then + hurd_cv_includedir_ncursesw="$D/ncursesw" + break + fi + test "$hurd_cv_includedir_ncursesw" \ + || hurd_cv_includedir_ncursesw=none + done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_includedir_ncursesw" >&5 +$as_echo "$hurd_cv_includedir_ncursesw" >&6; } + fi + if test "$hurd_cv_includedir_ncursesw" = none; then + NCURSESW_INCLUDE="" + else + NCURSESW_INCLUDE="-I$hurd_cv_includedir_ncursesw" + fi + fi + fi + + + +# 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= +else + # We are configuring in a separate build tree. + # Create a Makefile in the top-level build directory and + # one for each subdirectory Makefile in the source. + makefiles="Makeconf:build.mkcf.in \ + `cd $srcdir; for file in Makefile */Makefile; do \ + echo ${file}:build.mk.in; done`" +fi + +ac_config_files="$ac_config_files config.make ${makefiles}" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +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 + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +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="\\ +GNU Hurd config.status 0.3 +configured by $0, generated by GNU Autoconf 2.67, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.make") CONFIG_FILES="$CONFIG_FILES config.make" ;; + "${makefiles}") CONFIG_FILES="$CONFIG_FILES ${makefiles}" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + 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'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/configure.in b/configure.in index 8f55c4c1..05b959b0 100644 --- a/configure.in +++ b/configure.in @@ -1,30 +1,89 @@ dnl Process this file with autoconf to produce a configure script. -AC_REVISION([$Id: configure.in,v 1.11 1997/05/23 16:39:25 thomas Exp $]) -AC_PREREQ(2.4) dnl Minimum Autoconf version required. -AC_INIT(hurd/hurd_types.h) dnl A distinctive file to look for in srcdir. +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([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. AC_CANONICAL_HOST case "$host_os" in gnu*) ;; -*) AC_MSG_ERROR([sorry, this is the gnu os, not $host_os]) ;; +none) AC_MSG_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.]) ;; +*) AC_MSG_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.]) ;; esac case "$host_cpu" in -i[[3456]]86) - asm_syntax=i386 - ;; -*) AC_MSG_ERROR([unspported CPU type]) ;; +alpha*) + asm_syntax=alpha + ;; +arm*) + asm_syntax=arm + ;; +m68k | m680?0) + asm_syntax=m68k + ;; +mips*) + asm_syntax=mips + ;; +i?86) + asm_syntax=i386 + ;; +powerpc*) + asm_syntax=ppc + ;; +sparc64* | ultrasparc*) + asm_syntax=sparc64 + ;; +sparc*) + asm_syntax=sparc + ;; +*) + asm_syntax="$host_cpu" + ;; esac AC_SUBST(asm_syntax) +test -r "$srcdir/libthreads/$asm_syntax/cthreads.h" || { + AC_MSG_WARN([unsupported CPU type $host_cpu]) +} + +AC_ARG_ENABLE(profile, +[ --disable-profile do not build profiled libraries and programs]) +AC_SUBST(enable_profile) + +define([default_static],['ext2fs,ufs'])dnl +AC_ARG_ENABLE(static-progs, +[ --enable-static-progs=PROGRAMS... + build statically-linked PROGRAM.static versions + of (only) the listed programs ]dnl +changequote(',')[default_static]changequote([,])) +case "$enable_static_progs" in +'no') enable_static_progs= ;; # we got --disable-static +'') enable_static_progs=default_static ;; +esac +# Convert comma/space-separated list into space-separated list. +enable_static_progs=`echo "$enable_static_progs" | sed 's/[[, ]][[, ]]*/ /g'` +AC_SUBST(enable_static_progs) + +[# Don't needlessly overwrite files that whose contents haven't changed. This +# helps for avoinding unneccessary recompilation cycles when keeping +# cross-compilation toolchains up-to-date. Thus, unconditionally use the +# supplied `install-sh', as the GNU Coreutils one doesn't provide this +# functionality yet (TODO: change that). TODO: $ac_abs_top_builddir et al. are +# not yet available here, that's why we use `readlink' (but only if available). +INSTALL="$SHELL $(readlink -f "$ac_install_sh")"\ -C || unset INSTALL] AC_PROG_INSTALL +AC_PROG_AWK -AC_CHECK_TOOL(CC, gcc) -# That check handles cross-compilation well, but AC_PROG_CC tests for GCC -# and sets default CFLAGS nicely for us, so do that too. -AC_PROG_CC_LOCAL +AC_PROG_CC # Require GCC. if test x$GCC != xyes; then AC_MSG_ERROR([this code uses GNU C extensions, you must compile with GCC]) @@ -35,20 +94,148 @@ AC_CHECK_TOOL(OBJCOPY, objcopy) AC_CHECK_TOOL(AR, ar) AC_CHECK_TOOL(RANLIB, ranlib) AC_CHECK_TOOL(MIG, mig) +# Require MiG. +if test x${MIG} = x; then + AC_MSG_ERROR([ +*** You need GNU MiG to compile the GNU Hurd, please see +*** http://www.gnu.org/software/hurd/mig.html for further details, or +*** download it directly from the main GNU server (ftp.gnu.org) or any +*** GNU mirror.]) +fi dnl Let these propagate from the environment. AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) -# See if there's a separate libcrypt (many systems put crypt there) +# See if there's a separate libcrypt (many systems put crypt there). AC_CHECK_LIB(crypt, crypt, LIBCRYPT=-lcrypt) AC_SUBST(LIBCRYPT) -# Look for the crypt function itself (in libcrypt if possible) -_SAVE_LIBS="$LIBS" -LIBS="$LIBCRYPT $LIBS" -AC_CHECK_FUNCS(crypt) -LIBS="$_SAVE_LIBS" -if test $srcdir = .; then +hurd_MIG_RETCODE + +# See if --version-script is available. +AC_CACHE_CHECK(for ld --version-script, hurd_cv_ld_version_script_option, [dnl +cat > conftest.c <<\EOF +void foobar() {} +EOF +cat > conftest.map <<\EOF +VERS_1 { + global: sym; +}; + +VERS_2 { + global: sym; +} VERS_1; +EOF + +if AC_TRY_COMMAND([eval $ac_compile 1>&AS_MESSAGE_LOG_FD()]) && + AC_TRY_COMMAND([${CC-cc} $CFLAGS -shared -o conftest.so conftest.o + -nostartfiles -nostdlib + -Wl,--version-script,conftest.map + 1>&AS_MESSAGE_LOG_FD()]); then + hurd_cv_ld_version_script_option=yes +else + hurd_cv_ld_version_script_option=no +fi +rm -f conftest*]) + +# See if libc was built with --enable-libio. +AC_CACHE_CHECK([for libio], + hurd_cv_libio, + AC_TRY_COMPILE([#include <stdio.h> +#ifndef _STDIO_USES_IOSTREAM +# error No libio found. +#endif],, + hurd_cv_libio=yes, + hurd_cv_libio=no)) + +# The versions of the symbols in libthreads have to match those in +# libc.so. Since the symbols in a libc that includes libio will be +# versioned differently from the ones in a libc that uses stdio, this +# isn't easy to accomplish. Instead we leave things unversioned if +# libio isn't found. +if test $hurd_cv_libio = yes; then + VERSIONING=$hurd_cv_ld_version_script_option +else + VERSIONING=no +fi +AC_SUBST(VERSIONING) + +# Check if libc contains getgrouplist and/or uselocale. +AC_CHECK_FUNCS(getgrouplist uselocale) + + +# From glibc HEAD, 2007-11-07. +AC_CACHE_CHECK(for -fgnu89-inline, libc_cv_gnu89_inline, [dnl +cat > conftest.c <<EOF +int foo; +#ifdef __GNUC_GNU_INLINE__ +main () { return 0;} +#else +#error +#endif +EOF +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -std=gnu99 -fgnu89-inline + -o conftest.s conftest.c 1>&AS_MESSAGE_LOG_FD]) +then + libc_cv_gnu89_inline=yes +else + libc_cv_gnu89_inline=no +fi +rm -f conftest*]) +if test $libc_cv_gnu89_inline = yes; then + libc_cv_gnu89_inline=-fgnu89-inline +else + libc_cv_gnu89_inline= +fi +AC_SUBST(libc_cv_gnu89_inline) + + +# Insist on libparted unless the user declines explicitely +AC_ARG_WITH([parted], + [AS_HELP_STRING([--without-parted], [disable user-space partition stores])], + [], + [with_parted=yes]) + +PARTED_LIBS= +AC_DEFUN([PARTED_FAIL], [ + AC_MSG_FAILURE([Please install required libraries or use --without-parted.]) +]) +AS_IF([test "x$with_parted" != xno], [ + AC_CHECK_HEADER([parted/parted.h], + [AC_DEFINE(HAVE_PARTED_PARTED_H)], + [PARTED_FAIL]) + AC_CHECK_LIB([parted], [ped_device_read], [], [PARTED_FAIL]) + AC_CHECK_LIB([uuid], [uuid_generate], [], [PARTED_FAIL]) + AC_CHECK_LIB([dl], [dlopen], [], [PARTED_FAIL]) + PARTED_LIBS="-lparted -luuid -ldl" +]) +AC_SUBST([PARTED_LIBS]) + +AC_ARG_ENABLE(boot-store-types, +[ --enable-boot-store-types=TYPES... + list of store types included in statically + linked filesystems used for booting])dnl +if test -z "$enable_boot_store_types"; then + boot_store_types='device remap gunzip bunzip2' + test -z "$PARTED_LIBS" || boot_store_types="$boot_store_types part" +elif test "x$enable_boot_store_types" = xno; then + AC_MSG_WARN([you probably wanted --disable-static-progs]) +else + boot_store_types="$enable_boot_store_types" +fi +AC_SUBST(boot_store_types)dnl +AC_MSG_CHECKING(boot store types) +AC_MSG_RESULT($boot_store_types) + +# Check for ncursesw, which is needed for the console-curses client. +hurd_LIB_NCURSESW + +# 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= else @@ -60,7 +247,8 @@ else echo ${file}:build.mk.in; done`" fi -AC_OUTPUT(config.make ${makefiles}) +AC_CONFIG_FILES([config.make ${makefiles}]) +AC_OUTPUT dnl Local Variables: dnl comment-start: "dnl " diff --git a/devio/ChangeLog b/devio/ChangeLog deleted file mode 100644 index 07f59609..00000000 --- a/devio/ChangeLog +++ /dev/null @@ -1,270 +0,0 @@ -Sun Sep 8 18:10:57 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * Makefile (DIST_FILES): Variable removed. - (install, $(prefix)/dev/MAKEDEV): Targets removed. - -Fri Jul 19 15:55:27 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): Return correct values for - NUM_RUNS and NUM_OFFSETS. - -Thu Jul 18 18:33:49 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): Fill in the array-length - return values. - - * MAKEDEV: Add "com[0-9]". - -Wed Jul 17 10:00:04 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * MAKEDEV (st): New function. - Use new st function (get rid of chmods). - Accept disk device names without partitions, & with slice + partition. - -Sat Jun 15 14:13:24 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * MAKEDEV ([hrs]d*): Allow user to specify slice as well. Patch - from Gord Matzigkeit, gord@enci.ucalgary.ca. - -Thu May 9 12:15:47 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_io_select): Remove TAG arg. - (trivfs_S_file_get_storage_info): Fix param type. - -Tue May 7 16:41:48 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): Swap PORTS_TYPE & NUM_PORTS. - -Mon May 6 20:14:43 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): Enable new version. - -Fri May 3 15:09:00 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c [0] (trivfs_S_file_get_storage_info): Rewrite for new interface. - -Tue Apr 30 10:03:50 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (include ../Makeconf): BEFORE dependencies. - ($(prefix)/dev/MAKEDEV): Find MAKEDEV in $(srcdir). - -Fri Feb 16 19:28:32 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * MAKEDEV: Add rule for `time', and add `time' to std. - -Tue Jan 30 12:34:28 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * MAKEDEV: Grok `tty'. - -Thu Jan 25 18:10:24 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * devio.c (trivfs_goaway): Handle errors from ports_inhibit_class_rpcs. - Allow rpcs to resume if we're going to return EBUSY. - -Tue Jan 16 16:19:51 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * devio.c (trivfs_modify_stat): The peropen hook holds a struct - open, not a struct dev. - -Fri Dec 29 23:41:39 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * MAKEDEV (std): Make `fd' one of the standard devices. - -Fri Dec 15 13:30:33 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * MAKEDEV (ST): Variable holding the proper settrans command, - which use. - (_CWD): Use this variable to pass down the current directory to - sub MAKEDEVS. - (console): Use the new term syntax. - (tty[0-9]?|tty[0-9a-f]): New rule for normal ttys. - ([pt]ty[pqPQ]?): New rule for ptys (both master and slave). - ([pt]ty[pqPQ]): New rule for making sets of ptys. - -Mon Dec 4 15:17:14 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_set_size, trivfs_S_file_sync, - trivfs_S_file_syncfs, trivfs_S_file_get_storage_info): Add totally - gratuitous, annoying, and trouble-making reply-port args. - - * io.c (trivfs_S_file_get_storage_info): Use inline return if possible. - -Wed Nov 8 16:44:05 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_set_size): Renamed from trivfs_S_file_truncate. - -Sun Nov 5 10:00:56 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * devio.c (main): Add FLAGS arg to trivfs_startup call. - -Sat Nov 4 20:03:05 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): Add FLAGS argument. - -Fri Oct 6 17:25:37 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): Change type of ADDRESSES - to off_t **, and add BLOCK_SIZE parameter. - -Sun Oct 1 16:20:45 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * devio.c (main, trivfs_S_fsys_syncfs): Get rid of debugging noise. - * rdwr.c (open_write, open_read): Ditto. - * dev.c (dev_open, dev_sync, dev_write, dev_read): Ditto. - * io.c (trivfs_S_file_syncfs, trivfs_S_file_sync): Ditto. - * devpager.c (pager_write_page, pager_read_page): Ditto. - * window.c (position): Ditto. - -Tue Sep 26 15:33:14 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * io.c (trivfs_S_file_get_storage_info): New function. - * dev.c (dev_open): Record NAME in the returned dev structure. - * dev.h (struct dev): Add the NAME field. - -Thu Aug 24 10:28:00 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (devio): Put all dependencies here. - (HURDLIBS): Removed. - -Tue Aug 22 10:45:31 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (HURDLIBS): Add libshouldbeinlibc. - (OBJS): Get rid of error.o. - Get rid of rules dealing with error.o. - ($(prefix)/dev/MAKEDEV): Use $(INSTALL_PROGRAM) instead of - $(INSTALL_DATA) + `chmod +x'. - - * devio.c (trivfs_modify_stat): Get the device from CRED now that - we have it. - -Mon Aug 21 16:34:29 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * devio.c (trivfs_goaway, trivfs_modify_stat): Update arguments. - -Tue Aug 15 19:47:57 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * MAKEDEV ([hrs]d*): Fixed partition parsing: use glob pattern, - not regexp. - -Sun Aug 13 10:57:03 1995 Miles Bader <miles@duality.gnu.ai.mit.edu> - - * devio.c (trivfs_peropen_create_hook): This now returns an error_t. - (open_hook): And thus this does as well. - -Sat Jul 22 18:32:03 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * rdwr.c (open_read, open_write): Clean up STATE before returning - with an error. - * devpager.c (dev_get_memory_object): A new pager now comes with 1 - ref, so we allocate a ref ourselves when we're using an old one, - and once we've created the send right, remove a reference. - -Mon Jul 10 15:15:45 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * rdwr.c (open_seek): New function. - (raw_read, raw_write): Return EINVAL if *OFFS isn't a block boundary. - * open.h: Add declaration for open_seek. - * io.c (trivfs_S_io_seek): Call open_seek instead of doing ourselves. - -Sat Jul 8 18:35:17 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * MAKEDEV (fd): Put the fd server on `fd', not `stdin'. - * MAKEDEV (console): Give /hurd/term a ttyname argument. - -Thu Jul 6 15:33:33 1995 Miles Bader <miles@geech.gnu.ai.mit.edu> - - * Makefile: Remove include dependencies. - -Wed Jun 28 19:22:47 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (HURDLIBS): Add libihash. - - * iostate.c (io_state_sync): Remember that we've synced the buffer. - * devpager.c (dev_stop_paging): New function. - (pager_dropweak): New function. - * dev.h (struct dev): Add the pager_port_bucket field. - Declare dev_stop_paging (). - * devio.c (trivfs_goaway): Make trivfs_goaway do the right thing. - (clean_exit, close_device): Deleted functions. - (thread_cancel): New function. - - * devpager.c (pager_port_type): Deleted var. - (pager_port_bucket, pager_port_class): New vars. - (dev_get_memory_object): Moved here from dev.c. Also, call - init_dev_pager if necessary. - (service_paging_requests): New function. - (init_dev_pager): New function. - * dev.c (dev_get_memory_object): Moved function to devpager.c. - - * devio.c (fsys_port_class, root_port_class, port_bucket): New vars. - (trivfs_protid_portclasses, trivfs_cntl_portclasses, - trivfs_protid_nportclasses, trivfs_cntl_nportclasses): New vars. - (main): Initialize *portclasses vars, and convert to new trivfs lib. - (trivfs_protid_porttypes, trivfs_cntl_porttypes, - trivfs_protid_nporttypes, trivfs_cntl_nporttypes): Deleted vars. - (trivfs_goaway): Convert args for new trivfs lib. - (ports_cleanroutines): Delete var. - (ports_demuxer, ports_notice_idle, ports_no_live_ports, - ports_no_hard_ports): Delete functions. - * ptypes.h: Deleted file. - -Wed Jun 28 15:51:51 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile: Repair mangled include-file dependencies. - -Fri Apr 21 14:17:19 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * MAKEDEV: Split out `std' into individual device-makers it calls. - Rewrote /dev/fd stuff (still commented out). Use case built-in - instead of expr program. - -Tue Apr 11 15:46:35 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile (DIST_FILES): New var, for MAKEDEV. - (install): Depend on $(prefix)/dev/MAKEDEV. - ($(prefix)/dev/MAKEDEV): New target. - * MAKEDEV: New file. - -Mon Apr 10 10:22:26 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * rdwr.c (open_write, open_read): Bounds check I/O. - - * io.c (trivfs_S_file_truncate): Always return 0, so O_TRUNC works. - - * devio.c (main, check_open_hook, close_device, trivfs_goaway): - Add a new lock, device_lock, and use it to control access to the - DEVICE variable. - (open_hook, trivfs_modify_stat, trivfs_S_fys_syncfs): Copy DEVICE - before using it, so it doesn't change underneath us. - - * devio.c (clean_exit): Add a new argument that says whether to - aquire a lock before doing our work. - (ports_notice_idle, ports_no_live_ports): Use it. - - * devio.c (close_device): New function, closes DEVICE cleanly. - (clean_exit, ports_no_hard_ports): Use close_device. - - * devio.c (main): Use trivfs_startup instead of doing it manually. - - * devio.c (trivfs_goaway): Try and do it better, paying attention - to flags, etc.; this still isn't right though, we may want to wait - for the ports library to be fixed first. - - * devio.c (DEBUG): New macro, executes its arg with debug_lock locked. - (most everything): use DEBUG instead of doing things manually. - - * open.c (open_create): Supply our dev's size when creating a window. - -Sun Apr 9 14:49:33 1995 Miles Bader <miles@duality.gnu.ai.mit.edu> - - * window.h: Add a new window field, max_pos. Rename the location - field `pos'. - * window.c (position): Use a shorter than normal window if - necessary to avoid going past the end of the device. - (window_create): Initialize the new MAX_POS field. - (window_create, position, window_write, window_read): Rename the - location field `pos'. - - * devpager.c (pager_read_page, pager_write_page): Read or write - partial pages at the end of the device. - diff --git a/devio/MAKEDEV b/devio/MAKEDEV deleted file mode 100644 index 7d13fe3b..00000000 --- a/devio/MAKEDEV +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# -# Make standard devices -# - -PATH=/bin - -function st { - NODE="$1" - OWNER="$2" - PERM="$3" - shift 3 - settrans -cg "$NODE" - chown "$OWNER" "$NODE" - chmod "$PERM" "$NODE" - settrans "$NODE" "$@" -} - -_CWD=${_CWD:-`pwd`} -export _CWD - -for I; do - case "$I" in - std) - $0 console tty null zero fd time - ;; - console|tty[0-9][0-9a-f]|tty[0-9a-f]|com[0-9]) - st $I root 600 /hurd/term $_CWD/$I device $I;; - null) - st $I root 666 /hurd/null;; - zero) - st $I root 666 /hurd/null -z;; - tty) - st $I root 666 /hurd/magic tty;; - fd) - st $I root 666 /hurd/magic fd - ln -f -s fd/0 stdin - ln -f -s fd/1 stdout - ln -f -s fd/2 stderr - ;; - time) - st $I root 666 /hurd/devport time ;; - - # ptys - [pt]ty[pqPQ]?) - # Make one pty, both the master and slave halves - ID="`expr substr $I 4 99`" - st pty$ID root 640 /hurd/term $_CWD/pty$ID pty-master $_CWD/tty$ID - st tty$ID root 640 /hurd/term $_CWD/tty$ID pty-slave $_CWD/pty$ID - ;; - [pt]ty[pqPQ]) - # Make a bunch of ptys - $0 ${I}0 ${I}1 ${I}2 ${I}3 ${I}4 ${I}5 ${I}6 ${I}7 - $0 ${I}8 ${I}9 ${I}a ${I}b ${I}c ${I}d ${I}e ${I}f - ;; - - fd*|mt*) - st r$I root 640 /hurd/devio $I - st $I root 640 /hurd/devio -b $I - ;; - - [hrs]d*) - case "$I" in - [a-z][a-z][0-9][a-z] | [a-z][a-z][0-9]s[1-9] | [a-z][a-z][0-9]s[1-9][a-z] | [a-z][a-z][0-9]) - st r$I root 640 /hurd/devio $I - st $I root 640 /hurd/devio -b $I - ;; - *) - echo 1>&2 $0: $I: Illegal device name: must supply a device number - exit 1 - ;; - esac - ;; - - *) - echo >&2 $0: $I: Unknown device - exit 1 - ;; - esac -done diff --git a/devio/Makefile b/devio/Makefile deleted file mode 100644 index 1dda469d..00000000 --- a/devio/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile for devio -# -# Copyright (C) 1995, 1996 Free Software Foundation, Inc. -# -# This program 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. -# -# 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. - -dir := devio -makemode := server - -target = devio -SRCS = dev.c iostate.c window.c devio.c open.c devpager.c io.c rdwr.c mem.c -LCLHDRS = dev.h iostate.h window.h open.h ptypes.h mem.h - -OBJS = $(SRCS:.c=.o) - -include ../Makeconf - -devio: $(OBJS) ../libtrivfs/libtrivfs.a ../libpager/libpager.a ../libports/libports.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a diff --git a/devio/dev.c b/devio/dev.c deleted file mode 100644 index 4d3b89cb..00000000 --- a/devio/dev.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Mach devices. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> -#include <device/device.h> -#include <assert.h> -#include <hurd/pager.h> - -#include "dev.h" -#include "iostate.h" - -/* ---------------------------------------------------------------- */ - -/* Returns a pointer to a new device structure in DEV for the kernel device - NAME, with the given FLAGS. If BLOCK_SIZE is non-zero, it should be the - desired block size, and must be a multiple of the device block size. - If an error occurs, the error code is returned, otherwise 0. */ -error_t -dev_open(char *name, int flags, int block_size, struct dev **dev) -{ - error_t err = 0; - static mach_port_t device_master = MACH_PORT_NULL; - - *dev = malloc(sizeof (struct dev)); - - if (!(flags & DEV_SERIAL)) - flags |= DEV_SEEKABLE; - - if (*dev == NULL) - return ENOMEM; - - (*dev)->name = malloc (strlen (name) + 1); - if ((*dev)->name) - strcpy ((*dev)->name, name); - else - err = ENOMEM; - - (*dev)->port = MACH_PORT_NULL; - - if (!err && device_master == MACH_PORT_NULL) - err = get_privileged_ports(NULL, &device_master); - - if (!err) - err = device_open(device_master, - D_READ | (flags & DEV_READONLY ? D_WRITE : 0), - name, &(*dev)->port); - - if (!err) - { - int count = DEV_GET_SIZE_COUNT; - int sizes[DEV_GET_SIZE_COUNT]; - - /* Get info about the device: total size (in bytes) and block size (in - bytes). Block size is unit in which device addressing is done. */ - err = device_get_status((*dev)->port, DEV_GET_SIZE, sizes, &count); - if (!err) - { - (*dev)->size = sizes[DEV_GET_SIZE_DEVICE_SIZE]; - (*dev)->dev_block_size = sizes[DEV_GET_SIZE_RECORD_SIZE]; - } - } - - if (!err) - { - if (block_size > 0) - if (block_size > (*dev)->dev_block_size - && block_size % (*dev)->dev_block_size == 0) - (*dev)->block_size = block_size; - else - err = EINVAL; - else - (*dev)->block_size = (*dev)->dev_block_size; - - if ((*dev)->dev_block_size == 1) - flags |= DEV_SERIAL; - - (*dev)->flags = flags; - (*dev)->owner = 0; - } - - if (!err) - err = io_state_init(&(*dev)->io_state, *dev); - - if (err) - { - if ((*dev)->port != MACH_PORT_NULL) - mach_port_deallocate(mach_task_self(), (*dev)->port); - free(*dev); - } - - return err; -} - -/* Free DEV and any resources it consumes. */ -void -dev_close(struct dev *dev) -{ - if (!dev_is(dev, DEV_READONLY)) - { - if (dev->pager != NULL) - pager_shutdown(dev->pager); - io_state_sync(&dev->io_state, dev); - } - - device_close(dev->port); - io_state_finalize(&dev->io_state); - - free(dev); -} - -/* ---------------------------------------------------------------- */ - -/* Try and write out any pending writes to DEV. If WAIT is true, will wait - for any paging activity to cease. */ -error_t -dev_sync(struct dev *dev, int wait) -{ - error_t err = 0; - - if (!dev_is(dev, DEV_READONLY)) - { - struct io_state *ios = &dev->io_state; - - io_state_lock(ios); - - /* Sync any paged backing store. */ - if (dev->pager != NULL) - pager_sync(dev->pager, wait); - - /* Write out any stuff buffered in our io_state. */ - err = io_state_sync(ios, dev); - - io_state_unlock(ios); - } - - return err; -} - -/* ---------------------------------------------------------------- */ - -/* Writes AMOUNT bytes from the buffer pointed to by BUF to the device DEV. - *OFFS is incremented to reflect the amount read/written. Both AMOUNT and - *OFFS must be multiples of DEV's block size, and either BUF must be - page-aligned, or dev_write_valid() must return true for these arguments. - If an error occurs, the error code is returned, otherwise 0. */ -error_t -dev_write(struct dev *dev, - vm_address_t buf, vm_size_t amount, vm_offset_t *offs) -{ - int bsize = dev->dev_block_size; - vm_offset_t written = 0; - vm_offset_t block = (bsize == 1 ? *offs : *offs / bsize); - error_t err; - - assert(dev_write_valid(dev, buf, amount, *offs)); - assert(*offs % bsize == 0); - assert(amount % bsize == 0); - - if (amount < IO_INBAND_MAX) - err = - device_write_inband (dev->port, 0, block, - (io_buf_ptr_t)buf, amount, &written); - else - err = - device_write (dev->port, 0, block, (io_buf_ptr_t)buf, amount, &written); - - if (!err) - *offs += written; - - return err; -} - -/* Reads AMOUNT bytes from DEV and returns it in BUF and BUF_LEN (using the - standard mach out-array convention). *OFFS is incremented to reflect the - amount read/written. Both LEN and *OFFS must be multiples of DEV's block - size. If an error occurs, the error code is returned, otherwise 0. */ -error_t -dev_read(struct dev *dev, - vm_address_t *buf, vm_size_t *buf_len, vm_size_t amount, - vm_offset_t *offs) -{ - error_t err = 0; - int bsize = dev->dev_block_size; - vm_offset_t read = 0; - vm_offset_t block = (bsize == 1 ? *offs : *offs / bsize); - - assert(*offs % bsize == 0); - assert(amount % bsize == 0); - - if (amount < IO_INBAND_MAX) - { - if (*buf_len < amount) - err = vm_allocate(mach_task_self(), buf, amount, 1); - if (!err) - err = - device_read_inband(dev->port, 0, block, - amount, (io_buf_ptr_t)*buf, &read); - } - else - err = - device_read(dev->port, 0, block, amount, (io_buf_ptr_t *)buf, &read); - - if (!err) - { - *offs += read; - *buf_len = read; - } - - return err; -} diff --git a/devio/dev.h b/devio/dev.h deleted file mode 100644 index de51d788..00000000 --- a/devio/dev.h +++ /dev/null @@ -1,147 +0,0 @@ -/* A handle on a mach device. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 __DEV_H__ -#define __DEV_H__ - -#include <mach.h> -#include <device/device.h> - -#include "iostate.h" - -/* #define FAKE */ -#define MSG - -#ifdef MSG -#include <stdio.h> -#include <string.h> -#include <unistd.h> -extern FILE *debug; -extern struct mutex debug_lock; -#endif - -/* ---------------------------------------------------------------- */ - -/* Information about a kernel device. */ -struct dev -{ - /* The device port for the kernel device we're doing paging on. */ - device_t port; - /* The mach device name which we opened. */ - char *name; - - /* The total size of DEV. */ - vm_size_t size; - - /* The block size of DEV. I/O to DEV must occur in multiples of - block_size. */ - int dev_block_size; - /* The block size in which we will do I/O; this must be a multiple of - DEV_BLOCK_SIZE. */ - int block_size; - - /* Various attributes of this device (see below for the DEV_ flag bits). - This field is constant. */ - int flags; - - /* Current state of our output stream -- location and the buffer used to do - buffered i/o. */ - struct io_state io_state; - - /* The pager we're using to do disk i/o for us. If NULL, a pager hasn't - been allocated yet. Lock the lock in IO_STATE if you want to update - this field. */ - struct pager *pager; - /* The port_bucket for paging ports. */ - struct port_bucket *pager_port_bucket; - - /* The current owner of the open device. For terminals, this affects - controlling terminal behavior (see term_become_ctty). For all objects - this affects old-style async IO. Negative values represent pgrps. This - has nothing to do with the owner of a file (as returned by io_stat, and - as used for various permission checks by filesystems). An owner of 0 - indicates that there is no owner. */ - pid_t owner; -}; - -/* Various bits to be set in the flags field. */ - -/* True if this device should be used in `block' mode, with buffering of - sub-block-size i/o. */ -#define DEV_BUFFERED 0x1 -/* True if this device only supports serial i/o (that is, there's only one - read/write location, which must explicitly be moved to do i/o elsewhere.*/ -#define DEV_SERIAL 0x2 -/* True if we can change the current i/o location of a serial device. */ -#define DEV_SEEKABLE 0x4 -/* True if a device cannot be written on. */ -#define DEV_READONLY 0x8 - -/* Returns TRUE if any of the flags in BITS are set for DEV. */ -#define dev_is(dev, bits) ((dev)->flags & (bits)) - -/* Returns true if it's ok to call dev_write on these arguments, without - first copying BUF to a page-aligned buffer. */ -#define dev_write_valid(dev, buf, len, offs) \ - ((len) <= IO_INBAND_MAX || (buf) % vm_page_size == 0) - -/* Returns a pointer to a new device structure in DEV for the kernel device - NAME, with the given FLAGS. If BLOCK_SIZE is non-zero, it should be the - desired block size, and must be a multiple of the device block size. - If an error occurs, the error code is returned, otherwise 0. */ -error_t dev_open(char *name, int flags, int block_size, struct dev **dev); - -/* Free DEV and any resources it consumes. */ -void dev_close(struct dev *dev); - -/* Reads AMOUNT bytes from DEV and returns it in BUF and BUF_LEN (using the - standard mach out-array convention). *OFFS is incremented to reflect the - amount read/written. Both LEN and *OFFS must be multiples of DEV's block - size. If an error occurs, the error code is returned, otherwise 0. */ -error_t dev_read(struct dev *dev, - vm_address_t *buf, vm_size_t *buf_len, vm_size_t amount, - vm_offset_t *offs); - -/* Writes AMOUNT bytes from the buffer pointed to by BUF to the device DEV. - *OFFS is incremented to reflect the amount read/written. Both AMOUNT and - *OFFS must be multiples of DEV's block size, and either BUF must be - page-aligned, or dev_write_valid() must return true for these arguments. - If an error occurs, the error code is returned, otherwise 0. */ -error_t dev_write(struct dev *dev, - vm_address_t buf, vm_size_t amount, vm_offset_t *offs); - -/* Returns in MEMOBJ the port for a memory object backed by the storage on - DEV. Returns 0 or the error code if an error occurred. */ -error_t dev_get_memory_object(struct dev *dev, memory_object_t *memobj); - -/* Try to stop all paging activity on DEV, returning true if we were - successful. If NOSYNC is true, then we won't write back any (kernel) - cached pages to the device. */ -int dev_stop_paging (struct dev *dev, int nosync); - -/* Try and write out any pending writes to DEV. If WAIT is true, will wait - for any paging activity to cease. */ -error_t dev_sync(struct dev *dev, int wait); - -#ifdef MSG -char *brep(vm_address_t buf, vm_size_t len); -#endif - -#endif /* !__DEV_H__ */ diff --git a/devio/devio.c b/devio/devio.c deleted file mode 100644 index f1eb428a..00000000 --- a/devio/devio.c +++ /dev/null @@ -1,359 +0,0 @@ -/* A translator for doing I/O to mach kernel devices. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> -#include <hurd/ports.h> -#include <hurd/pager.h> -#include <hurd/trivfs.h> -#include <hurd/fsys.h> - -#include <stdio.h> -#include <error.h> -#include <getopt.h> -#include <assert.h> -#include <fcntl.h> - -#include "open.h" -#include "dev.h" - -/* ---------------------------------------------------------------- */ - -/* The port class of our file system control pointer. */ -struct port_class *fsys_port_class; -/* The port class of the (only) root file port for the opened device. */ -struct port_class *root_port_class; - -/* A bucket to put all our ports in. */ -struct port_bucket *port_bucket; - -/* Trivfs noise. */ -struct port_class *trivfs_protid_portclasses[1]; -struct port_class *trivfs_cntl_portclasses[1]; -int trivfs_protid_nportclasses = 1; -int trivfs_cntl_nportclasses = 1; - -/* ---------------------------------------------------------------- */ - -#define USAGE "Usage: %s [OPTION...] DEVICE\n" - -static void -usage(int status) -{ - if (status != 0) - fprintf(stderr, "Try `%s --help' for more information.\n", - program_invocation_name); - else - { - printf(USAGE, program_invocation_name); - printf("\ -\n\ - -d, --devnum=NUM Give DEVICE a device number NUM\n\ - -r, --readonly Disable writing to DEVICE\n\ - -p, --seekable Enable seeking if DEVICE is serial\n\ - -s, --serial Indicate that DEVICE has a single R/W point\n\ - -b, --buffered, --block Open DEVICE in `block' mode, which allows reads\n\ - or writes less than a single block and buffers\n\ - I/O to the actual device. By default, all reads\n\ - and writes are made directly to the device,\n\ - with no buffering, and any sub-block-size I/O\n\ - is padded to the nearest full block.\n\ - -B NUM, --block-size=NUM Use a block size of NUM, which must be an integer\n\ - multiple of DEVICE's real block size\n\ -"); - } - - exit(status); -} - -#define SHORT_OPTIONS "bB:d:D:?rpsu" - -static struct option options[] = -{ - {"block-size", required_argument, 0, 'B'}, - {"help", no_argument, 0, '?'}, - {"devnum", required_argument, 0, 'm'}, - {"block", no_argument, 0, 'b'}, - {"buffered", no_argument, 0, 'b'}, - {"readonly", no_argument, 0, 'r'}, - {"seekable", no_argument, 0, 'p'}, - {"serial", no_argument, 0, 's'}, - {0, 0, 0, 0} -}; - -/* ---------------------------------------------------------------- */ - -/* A struct dev for the open kernel device. */ -static struct dev *device = NULL; -/* And a lock to arbitrate changes to it. */ -static struct mutex device_lock; - -/* Desired device parameters specified by the user. */ -static char *device_name = NULL; -static int device_flags = 0; -static int device_block_size = 0; - -/* A unixy device number to return when the device is stat'd. */ -static int device_number = 0; - -void main(int argc, char *argv[]) -{ - int opt; - error_t err; - mach_port_t bootstrap; - - while ((opt = getopt_long(argc, argv, SHORT_OPTIONS, options, 0)) != EOF) - switch (opt) - { - case 'r': device_flags |= DEV_READONLY; break; - case 's': device_flags |= DEV_SERIAL; break; - case 'b': device_flags |= DEV_BUFFERED; break; - case 'p': device_flags |= DEV_SEEKABLE; break; - case 'B': device_block_size = atoi(optarg); break; - case 'd': device_number = atoi(optarg); break; - case '?': usage(0); - default: usage(1); - } - - if (device_flags & DEV_READONLY) - /* Catch illegal writes at the point of open. */ - trivfs_allow_open &= ~O_WRITE; - - if (argv[optind] == NULL || argv[optind + 1] != NULL) - { - fprintf(stderr, USAGE, program_invocation_name); - usage(1); - } - - device_name = argv[optind]; - - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error(2, 0, "Must be started as a translator"); - - fsys_port_class = ports_create_class (trivfs_clean_cntl, 0); - root_port_class = ports_create_class (trivfs_clean_protid, 0); - port_bucket = ports_create_bucket (); - trivfs_protid_portclasses[0] = root_port_class; - trivfs_cntl_portclasses[0] = fsys_port_class; - - /* Reply to our parent */ - err = - trivfs_startup(bootstrap, 0, - fsys_port_class, port_bucket, - root_port_class, port_bucket, - NULL); - if (err) - error(3, err, "Contacting parent"); - - /* Open the device only when necessary. */ - device = NULL; - mutex_init(&device_lock); - - /* Launch. */ - ports_manage_port_operations_multithread (port_bucket, trivfs_demuxer, - 30*1000, 5*60*1000, 0, 0); - - exit(0); -} - -/* Called whenever someone tries to open our node (even for a stat). We - delay opening the kernel device until this point, as we can usefully - return errors from here. */ -static error_t -check_open_hook (struct trivfs_control *trivfs_control, - uid_t *uids, u_int nuids, - gid_t *gids, u_int ngids, - int flags) -{ - error_t err = 0; - - mutex_lock(&device_lock); - if (device == NULL) - /* Try and open the device. */ - { - err = dev_open(device_name, device_flags, device_block_size, &device); - if (err) - device = NULL; - if (err && (flags & (O_READ|O_WRITE)) == 0) - /* If we're not opening for read or write, then just ignore the - error, as this allows stat to word correctly. XXX */ - err = 0; - } - mutex_unlock(&device_lock); - - return err; -} - -static error_t -open_hook(struct trivfs_peropen *peropen) -{ - struct dev *dev = device; - if (dev) - return open_create(dev, (struct open **)&peropen->hook); - else - return 0; -} - -static void -close_hook(struct trivfs_peropen *peropen) -{ - if (peropen->hook) - open_free(peropen->hook); -} - -/* ---------------------------------------------------------------- */ -/* Trivfs hooks */ - -int trivfs_fstype = FSTYPE_DEV; -int trivfs_fsid = 0; - -int trivfs_support_read = 1; -int trivfs_support_write = 1; -int trivfs_support_exec = 0; - -int trivfs_allow_open = O_READ | O_WRITE; - -void -trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st) -{ - struct open *open = cred->po->hook; - - if (open) - /* An open device. */ - { - struct dev *dev = open->dev; - vm_size_t size = dev->size; - - if (dev->block_size > 1) - st->st_blksize = dev->block_size; - - st->st_size = size; - st->st_blocks = size / 512; - - if (dev_is(dev, DEV_READONLY)) - st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - - st->st_mode &= ~S_IFMT; - st->st_mode |= dev_is(dev, DEV_BUFFERED) ? S_IFBLK : S_IFCHR; - } - else - /* Try and do things without an open device... */ - { - st->st_blksize = device_block_size; - st->st_size = 0; - st->st_blocks = 0; - st->st_mode &= ~S_IFMT; - st->st_mode |= (device_flags & DEV_BUFFERED) ? S_IFBLK : S_IFCHR; - if (device_flags & DEV_READONLY) - st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - } - - st->st_rdev = device_number; -} - -error_t -trivfs_goaway (struct trivfs_control *fsys, int flags) -{ - error_t err; - int force = (flags & FSYS_GOAWAY_FORCE); - int nosync = (flags & FSYS_GOAWAY_NOSYNC); - - mutex_lock(&device_lock); - - if (device == NULL) - exit (0); - - /* Wait until all pending rpcs are done. */ - err = ports_inhibit_class_rpcs (root_port_class); - if (err == EINTR || (err && !force)) - { - mutex_unlock (&device_lock); - return err; - } - - if (force && nosync) - /* Exit with extreme prejudice. */ - exit (0); - - if (!force && ports_count_class (root_port_class) > 0) - /* Still users, so don't exit. */ - goto busy; - - if (!nosync) - /* Sync the device here, if necessary, so that closing it won't result in - any I/O (which could get hung up trying to use one of our pagers). */ - dev_sync (device, 1); - - /* devpager_shutdown may sync the pagers as side-effect (if NOSYNC is 0), - so we put that first in this test. */ - if (dev_stop_paging (device, nosync) || force) - /* Bye-bye. */ - { - if (!nosync) - /* If NOSYNC is true, we don't close DEV, as that could cause data to - be written back. */ - dev_close (device); - exit (0); - } - - busy: - /* Allow normal operations to proceed. */ - ports_enable_class (root_port_class); - ports_resume_class_rpcs (root_port_class); - mutex_unlock(&device_lock); - - /* Complain that there are still users. */ - return EBUSY; -} - -/* If this variable is set, it is called every time an open happens. - UIDS, GIDS, and FLAGS are from the open; CNTL identifies the - node being opened. This call need not check permissions on the underlying - node. If the open call should block, then return EWOULDBLOCK. Other - errors are immediately reflected to the user. If O_NONBLOCK - is not set in FLAGS and EWOULDBLOCK is returned, then call - trivfs_complete_open when all pending open requests for this - file can complete. */ -error_t (*trivfs_check_open_hook)(struct trivfs_control *trivfs_control, - uid_t *uids, u_int nuids, - gid_t *gids, u_int ngids, - int flags) - = check_open_hook; - -/* If this variable is set, it is called every time a new peropen - structure is created and initialized. */ -error_t (*trivfs_peropen_create_hook)(struct trivfs_peropen *) = open_hook; - -/* If this variable is set, it is called every time a peropen structure - is about to be destroyed. */ -void (*trivfs_peropen_destroy_hook) (struct trivfs_peropen *) = close_hook; - -/* Sync this filesystem. */ -kern_return_t -trivfs_S_fsys_syncfs (struct trivfs_control *cntl, - mach_port_t reply, mach_msg_type_name_t replytype, - int wait, int dochildren) -{ - struct dev *dev = device; - if (dev) - return dev_sync(dev, wait); - else - return 0; -} diff --git a/devio/devpager.c b/devio/devpager.c deleted file mode 100644 index 1f3b3ee1..00000000 --- a/devio/devpager.c +++ /dev/null @@ -1,257 +0,0 @@ -/* A pager interface for raw mach devices. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> -#include <hurd/pager.h> -#include <device/device.h> -#include <assert.h> - -#include "dev.h" - -/* ---------------------------------------------------------------- */ -/* Pager library callbacks; see <hurd/pager.h> for more info. */ - -/* For pager PAGER, read one page from offset PAGE. Set *BUF to be the - address of the page, and set *WRITE_LOCK if the page must be provided - read-only. The only permissable error returns are EIO, EDQUOT, and - ENOSPC. */ -error_t -pager_read_page(struct user_pager_info *upi, - vm_offset_t page, vm_address_t *buf, int *writelock) -{ - error_t err; - int read; /* bytes actually read */ - int want = vm_page_size; /* bytes we want to read */ - struct dev *dev = (struct dev *)upi; - - if (page + want > dev->size) - /* Read a partial page if necessary to avoid reading off the end. */ - want = dev->size - page; - - err = device_read(dev->port, 0, page / dev->dev_block_size, want, - (io_buf_ptr_t *)buf, &read); - - if (!err && want < vm_page_size) - /* Zero anything we didn't read. Allocation only happens in page-size - multiples, so we know we can write there. */ - bzero((char *)*buf + want, vm_page_size - want); - - *writelock = (dev->flags & DEV_READONLY); - - if (err || read < want) - return EIO; - else - return 0; -} - -/* For pager PAGER, synchronously write one page from BUF to offset PAGE. In - addition, vm_deallocate (or equivalent) BUF. The only permissable error - returns are EIO, EDQUOT, and ENOSPC. */ -error_t -pager_write_page(struct user_pager_info *upi, - vm_offset_t page, vm_address_t buf) -{ - struct dev *dev = (struct dev *)upi; - - if (dev->flags & DEV_READONLY) - return EROFS; - else - { - error_t err; - int written; - int want = vm_page_size; - - if (page + want > dev->size) - /* Write a partial page if necessary to avoid reading off the end. */ - want = dev->size - page; - - err = device_write(dev->port, 0, page / dev->dev_block_size, - (io_buf_ptr_t)buf, want, &written); - - vm_deallocate(mach_task_self(), buf, vm_page_size); - - if (err || written < want) - return EIO; - else - return 0; - } -} - -/* A page should be made writable. */ -error_t -pager_unlock_page(struct user_pager_info *upi, vm_offset_t address) -{ - struct dev *dev = (struct dev *)upi; - - if (dev->flags & DEV_READONLY) - return EROFS; - else - return 0; -} - -/* The user must define this function. It should report back (in - *OFFSET and *SIZE the minimum valid address the pager will accept - and the size of the object. */ -error_t -pager_report_extent(struct user_pager_info *upi, - vm_address_t *offset, vm_size_t *size) -{ - *offset = 0; - *size = ((struct dev *)upi)->size; - return 0; -} - -/* This is called when a pager is being deallocated after all extant send - rights have been destroyed. */ -void -pager_clear_user_data(struct user_pager_info *upi) -{ -} - -/* ---------------------------------------------------------------- */ - -/* A top-level function for the paging thread that just services paging - requests. */ -static void -service_paging_requests (any_t arg) -{ - struct dev *dev = (struct dev *)arg; - for (;;) - ports_manage_port_operations_multithread (dev->pager_port_bucket, - pager_demuxer, - 1000 * 30, 1000 * 60 * 5, - 1, MACH_PORT_NULL); -} - -/* Initialize paging for this device. */ -static void -init_dev_paging (struct dev *dev) -{ - dev->pager_port_bucket = ports_create_bucket (); - - /* Make a thread to service paging requests. */ - cthread_detach (cthread_fork ((cthread_fn_t)service_paging_requests, - (any_t)dev)); -} - -void -pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) -{ -} - -/* ---------------------------------------------------------------- */ - -/* Try to stop all paging activity on DEV, returning true if we were - successful. If NOSYNC is true, then we won't write back any (kernel) - cached pages to the device. */ -int -dev_stop_paging (struct dev *dev, int nosync) -{ - int success = 1; /* Initially assume success. */ - - io_state_lock(&dev->io_state); - - if (dev->pager != NULL) - { - int num_pagers = ports_count_bucket (dev->pager_port_bucket); - if (num_pagers > 0 && !nosync) - { - error_t block_cache (void *arg) - { - struct pager *p = arg; - pager_change_attributes (p, 0, MEMORY_OBJECT_COPY_DELAY, 1); - return 0; - } - error_t enable_cache (void *arg) - { - struct pager *p = arg; - pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); - return 0; - } - - /* Loop through the pagers and turn off caching one by one, - synchronously. That should cause termination of each pager. */ - ports_bucket_iterate (dev->pager_port_bucket, block_cache); - - /* Give it a second; the kernel doesn't actually shutdown - immediately. XXX */ - sleep (1); - - num_pagers = ports_count_bucket (dev->pager_port_bucket); - if (num_pagers > 0) - /* Darn, there are actual honest users. Turn caching back on, - and return failure. */ - { - ports_bucket_iterate (dev->pager_port_bucket, enable_cache); - success = 0; - } - } - - if (success && !nosync) - /* shutdown the pager on DEV. If NOSYNC is set, we don't bother, for - fear that this may result in I/O. In this case we've disabled - rpcs on the pager's ports, so this will result in hanging... What - do we do??? XXXX */ - pager_shutdown (dev->pager); - } - - if (success) - dev->pager = NULL; - - io_state_lock(&dev->io_state); - - return success; -} - -/* ---------------------------------------------------------------- */ - -/* Returns in MEMOBJ the port for a memory object backed by the storage on - DEV. Returns 0 or the error code if an error occurred. */ -error_t -dev_get_memory_object(struct dev *dev, memory_object_t *memobj) -{ - if (dev_is(dev, DEV_SERIAL)) - return ENODEV; - - io_state_lock(&dev->io_state); - if (dev->pager_port_bucket == NULL) - init_dev_paging (dev); - if (dev->pager == NULL) - dev->pager = - pager_create((struct user_pager_info *)dev, dev->pager_port_bucket, - 1, MEMORY_OBJECT_COPY_DELAY); - else - ports_port_ref (dev->pager); - io_state_unlock(&dev->io_state); - - if (dev->pager == NULL) - return ENODEV; /* XXX ??? */ - - *memobj = pager_get_port(dev->pager); - ports_port_deref (dev->pager); /* Drop our original ref on PAGER. */ - - if (*memobj != MACH_PORT_NULL) - return - mach_port_insert_right(mach_task_self(), - *memobj, *memobj, - MACH_MSG_TYPE_MAKE_SEND); - - return 0; -} diff --git a/devio/io.c b/devio/io.c deleted file mode 100644 index 61f655d2..00000000 --- a/devio/io.c +++ /dev/null @@ -1,396 +0,0 @@ -/* Implements the hurd io interface to devio. - - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> -#include <hurd/ports.h> -#include <hurd/trivfs.h> -#include <stdio.h> -#include <fcntl.h> - -#include "open.h" -#include "dev.h" -#include "iostate.h" - -/* ---------------------------------------------------------------- */ - -/* Return objects mapping the data underlying this memory object. If - the object can be read then memobjrd will be provided; if the - object can be written then memobjwr will be provided. For objects - where read data and write data are the same, these objects will be - equal, otherwise they will be disjoint. Servers are permitted to - implement io_map but not io_map_cntl. Some objects do not provide - mapping; they will set none of the ports and return an error. Such - objects can still be accessed by io_read and io_write. */ -kern_return_t -trivfs_S_io_map(struct trivfs_protid *cred, - memory_object_t *rdobj, - mach_msg_type_name_t *rdtype, - memory_object_t *wrobj, - mach_msg_type_name_t *wrtype) -{ - if (!cred) - return EOPNOTSUPP; - else - { - mach_port_t memobj; - struct open *open = (struct open *)cred->po->hook; - error_t err = dev_get_memory_object(open->dev, &memobj); - - if (!err) - { - if (cred->po->openmodes & O_READ) - { - *rdobj = memobj; - *rdtype = MACH_MSG_TYPE_MOVE_SEND; - } - else - *rdobj = MACH_PORT_NULL; - - if (cred->po->openmodes & O_WRITE) - { - *wrobj = memobj; - *wrtype = MACH_MSG_TYPE_MOVE_SEND; - } - else - *wrobj = MACH_PORT_NULL; - } - - return err; - } -} - -/* ---------------------------------------------------------------- */ - -/* Read data from an IO object. If offset if -1, read from the object - maintained file pointer. If the object is not seekable, offset is - ignored. The amount desired to be read is in AMT. */ -kern_return_t -trivfs_S_io_read(struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - vm_address_t *data, - mach_msg_type_number_t *datalen, - off_t offs, - mach_msg_type_number_t amt) -{ - if (!cred) - return EOPNOTSUPP; - else if (!(cred->po->openmodes & O_READ)) - return EBADF; - else - return open_read((struct open *)cred->po->hook, data, datalen, amt, offs); -} - -/* ---------------------------------------------------------------- */ - -/* Tell how much data can be read from the object without blocking for - a "long time" (this should be the same meaning of "long time" used - by the nonblocking flag. */ -kern_return_t -trivfs_S_io_readable (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - mach_msg_type_number_t *amount) -{ - if (!cred) - return EOPNOTSUPP; - else if (!(cred->po->openmodes & O_READ)) - return EINVAL; - else - { - struct open *open = (struct open *)cred->po->hook; - struct dev *dev = open->dev; - vm_offset_t location = open_get_io_state(open)->location; - *amount = dev->size - location; - return 0; - } -} - -/* ---------------------------------------------------------------- */ - -/* Change current read/write offset */ -kern_return_t -trivfs_S_io_seek (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - off_t offs, int whence, off_t *new_offs) -{ - if (!cred) - return EOPNOTSUPP; - else - return open_seek ((struct open *)cred->po->hook, offs, whence, new_offs); -} - -/* ---------------------------------------------------------------- */ - -/* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG. - Block until one of the indicated types of i/o can be done "quickly", and - return the types that are then available. */ -kern_return_t -trivfs_S_io_select (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - int *type) -{ - if (!cred) - return EOPNOTSUPP; - else if (((*type & SELECT_READ) && !(cred->po->openmodes & O_READ)) - || ((*type & SELECT_WRITE) && !(cred->po->openmodes & O_WRITE))) - return EBADF; - else - *type &= ~SELECT_URG; - return 0; -} - -/* ---------------------------------------------------------------- */ - -/* Write data to an IO object. If offset is -1, write at the object - maintained file pointer. If the object is not seekable, offset is - ignored. The amount successfully written is returned in amount. A - given user should not have more than one outstanding io_write on an - object at a time; servers implement congestion control by delaying - responses to io_write. Servers may drop data (returning ENOBUFS) - if they recevie more than one write when not prepared for it. */ -kern_return_t -trivfs_S_io_write (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - vm_address_t data, mach_msg_type_number_t datalen, - off_t offs, mach_msg_type_number_t *amt) -{ - if (!cred) - return EOPNOTSUPP; - else if (!(cred->po->openmodes & O_WRITE)) - return EBADF; - else - return open_write((struct open *)cred->po->hook, data, datalen, amt, offs); -} - -/* ---------------------------------------------------------------- */ - -/* Truncate file. */ -kern_return_t -trivfs_S_file_set_size (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t reply_type, - off_t size) -{ - if (!cred) - return EOPNOTSUPP; - else - return 0; -} - -/* ---------------------------------------------------------------- */ -/* These four routines modify the O_APPEND, O_ASYNC, O_FSYNC, and - O_NONBLOCK bits for the IO object. In addition, io_get_openmodes - will tell you which of O_READ, O_WRITE, and O_EXEC the object can - be used for. The O_ASYNC bit affects icky async I/O; good async - I/O is done through io_async which is orthogonal to these calls. */ - -kern_return_t -trivfs_S_io_get_openmodes (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - int *bits) -{ - if (!cred) - return EOPNOTSUPP; - else - { - *bits = cred->po->openmodes; - return 0; - } -} - -error_t -trivfs_S_io_set_all_openmodes(struct trivfs_protid *cred, - mach_port_t reply, - mach_msg_type_name_t replytype, - int mode) -{ - if (!cred) - return EOPNOTSUPP; - else - return 0; -} - -kern_return_t -trivfs_S_io_set_some_openmodes (struct trivfs_protid *cred, - mach_port_t reply, - mach_msg_type_name_t replytype, - int bits) -{ - if (!cred) - return EOPNOTSUPP; - else - return 0; -} - -kern_return_t -trivfs_S_io_clear_some_openmodes (struct trivfs_protid *cred, - mach_port_t reply, - mach_msg_type_name_t replytype, - int bits) -{ - if (!cred) - return EOPNOTSUPP; - else - return 0; -} - -/* ---------------------------------------------------------------- */ -/* Get/set the owner of the IO object. For terminals, this affects - controlling terminal behavior (see term_become_ctty). For all - objects this affects old-style async IO. Negative values represent - pgrps. This has nothing to do with the owner of a file (as - returned by io_stat, and as used for various permission checks by - filesystems). An owner of 0 indicates that there is no owner. */ - -kern_return_t -trivfs_S_io_get_owner (struct trivfs_protid *cred, - mach_port_t reply, - mach_msg_type_name_t replytype, - pid_t *owner) -{ - if (!cred) - return EOPNOTSUPP; - else - { - struct open *open = (struct open *)cred->po->hook; - *owner = open->dev->owner; - return 0; - } -} - -kern_return_t -trivfs_S_io_mod_owner (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t replytype, - pid_t owner) -{ - if (!cred) - return EOPNOTSUPP; - else - { - struct open *open = (struct open *)cred->po->hook; - open->dev->owner = owner; - return 0; - } -} - - -/* ---------------------------------------------------------------- */ -/* File syncing operations; these all do the same thing, sync the underlying - device. */ - -kern_return_t -trivfs_S_file_sync (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t reply_type, - int wait) -{ - if (cred) - return dev_sync (((struct open *)cred->po->hook)->dev, wait); - else - return EOPNOTSUPP; -} - -kern_return_t -trivfs_S_file_syncfs (struct trivfs_protid *cred, - mach_port_t reply, mach_msg_type_name_t reply_type, - int wait, int dochildren) -{ - if (!cred) - return dev_sync (((struct open *)cred->po->hook)->dev, wait); - else - return EOPNOTSUPP; -} - -error_t -trivfs_S_file_get_storage_info (struct trivfs_protid *cred, - mach_port_t reply, - mach_msg_type_name_t reply_type, - mach_port_t **ports, - mach_msg_type_name_t *ports_type, - mach_msg_type_number_t *num_ports, - int **ints, mach_msg_type_number_t *num_ints, - off_t **offsets, - mach_msg_type_number_t *num_offsets, - char **data, mach_msg_type_number_t *data_len) -{ - error_t err = 0; - - if (!cred) - err = EOPNOTSUPP; - else - { - /* True when we've allocated memory for the corresponding vector. */ - int al_ports = 0, al_ints = 0, al_offsets = 0, al_data = 0; - -#define ENSURE_MEM(v, vl, alp, num) \ - if (!err && *vl < num) \ - { \ - err = vm_allocate (mach_task_self (), \ - (vm_address_t *)v, num * sizeof (**v), 1); \ - if (! err) \ - { \ - *vl = num; \ - alp = 1; \ - } \ - } - - ENSURE_MEM (ports, num_ports, al_ports, 1); - ENSURE_MEM (ints, num_ints, al_ints, 6); - ENSURE_MEM (offsets, num_offsets, al_offsets, 2); - ENSURE_MEM (data, data_len, al_data, 1); - - if (! err) - { - struct dev *dev = ((struct open *)cred->po->hook)->dev; - (*ints)[0] = STORAGE_DEVICE; /* type */ - (*ints)[1] = 0; /* flags */ - (*ints)[2] = dev->dev_block_size; /* block_size */ - (*ints)[3] = 1; /* num_runs */ - (*ints)[4] = strlen (dev->name) + 1; /* name_len */ - (*ints)[5] = 0; /* misc_len */ - *num_ints = 6; - - (*offsets)[0] = 0; - (*offsets)[1] = dev->size / dev->dev_block_size; - *num_offsets = 2; - - strcpy (*data, dev->name); - *data_len = strlen (dev->name) + 1; - - if (cred->isroot) - (*ports)[0] = dev->port; - else - (*ports)[0] = MACH_PORT_NULL; - *num_ports = 1; - *ports_type = MACH_MSG_TYPE_COPY_SEND; - } - else - /* Some memory allocation failed (not bloody likely). */ - { -#define DISCARD_MEM(v, vl, alp) \ - if (alp) \ - vm_deallocate (mach_task_self (), (vm_address_t)*v, *vl * sizeof (**v)); - - DISCARD_MEM (ports, num_ports, al_ports); - DISCARD_MEM (ints, num_ints, al_ints); - DISCARD_MEM (offsets, num_offsets, al_offsets); - DISCARD_MEM (data, data_len, al_data); - } - } - - return err; -} diff --git a/devio/iostate.c b/devio/iostate.c deleted file mode 100644 index fe40fcd2..00000000 --- a/devio/iostate.c +++ /dev/null @@ -1,79 +0,0 @@ -/* State for an I/O stream. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> - -#include "iostate.h" -#include "dev.h" - -/* ---------------------------------------------------------------- */ - -/* Initialize the io_state structure IOS to be used with the device DEV. If - a memory allocation error occurs, ENOMEM is returned, otherwise 0. */ -error_t -io_state_init(struct io_state *ios, struct dev *dev) -{ - error_t err = - vm_allocate(mach_task_self(), - (vm_address_t *)&ios->buffer, dev->block_size, 1); - - ios->location = 0; - ios->buffer_size = dev->block_size; - ios->buffer_use = 0; - mutex_init(&ios->lock); - - return err; -} - -/* Frees all resources used by IOS. */ -void -io_state_finalize(struct io_state *ios) -{ - vm_deallocate(mach_task_self(), (vm_address_t)ios->buffer, ios->buffer_size); -} - -/* If IOS's location isn't block aligned because writes have been buffered - there, then sync the whole buffer out to the device. Any error that - occurs while writing is returned, otherwise 0. */ -error_t -io_state_sync(struct io_state *ios, struct dev *dev) -{ - error_t err = 0; - - if (ios->buffer_use == IO_STATE_BUFFERED_WRITE) - { - vm_offset_t pos = ios->location; - int block_offs = pos % dev->block_size; - - if (block_offs > 0) - { - bzero((char *)ios->buffer + block_offs, - dev->block_size - block_offs); - ios->location -= block_offs; - err = - dev_write(dev, ios->buffer, dev->block_size, &ios->location); - } - - /* Remember that there's nothing left in the buffer. */ - ios->buffer_use = 0; - } - - return err; -} diff --git a/devio/iostate.h b/devio/iostate.h deleted file mode 100644 index 1795e153..00000000 --- a/devio/iostate.h +++ /dev/null @@ -1,67 +0,0 @@ -/* State for an I/O stream. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 __IOSTATE_H__ -#define __IOSTATE_H__ - -/* ---------------------------------------------------------------- */ - -enum io_state_buffer_use -{ - /* 0 means nothing */ - IO_STATE_BUFFERED_WRITE = 1, IO_STATE_BUFFERED_READ = 2 -}; - -struct io_state { - /* What we think the current position is. */ - vm_offset_t location; - - /* The buffer in which we accumulate buffered i/o. */ - vm_address_t buffer; - /* The size of BUFFER. */ - vm_size_t buffer_size; - - /* If LOCATION is not a multiple of the block size (and so points somewhere - in the middle of BUFFER), this indicates why. */ - enum io_state_buffer_use buffer_use; - - /* Lock this if you want to read/modify LOCATION or BUFFER. */ - struct mutex lock; -}; - -#define io_state_lock(ios) mutex_lock(&(ios)->lock) -#define io_state_unlock(ios) mutex_unlock(&(ios)->lock) - -/* Declare this to keep the parameter scope below sane. */ -struct dev; - -/* Initialize the io_state structure IOS to be used with the device DEV. If - a memory allocation error occurs, ENOMEM is returned, otherwise 0. */ -error_t io_state_init(struct io_state *ios, struct dev *dev); - -/* Frees all resources used by IOS. */ -void io_state_finalize(struct io_state *ios); - -/* If IOS's location isn't block aligned because writes have been buffered - there, then sync the whole buffer out to the device. Any error that - occurs while writing is returned, otherwise 0. */ -error_t io_state_sync(struct io_state *ios, struct dev *dev); - -#endif /* !__IOSTATE_H__ */ diff --git a/devio/mem.c b/devio/mem.c deleted file mode 100644 index 65caa19f..00000000 --- a/devio/mem.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Some random handy ops for dealing with rpcs that return memory. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> -#include <string.h> - -/* ---------------------------------------------------------------- */ - -/* Makes sure that BUF, points to a buffer with AMOUNT bytes available. - *BUF_LEN should be the current length of *BUF, and if this isn't enough to - hold AMOUNT bytes, then more is allocated and the new buffer is returned - in *BUF and *BUF_LEN. If a memory allocation error occurs, the error code - is returned, otherwise 0. */ -error_t -allocate(vm_address_t *buf, vm_size_t *buf_len, vm_size_t amount) -{ - if (*buf_len < amount) - { - error_t err = vm_allocate(mach_task_self(), buf, amount, 1); - if (err) - return err; - } - - *buf_len = amount; - return 0; -} - -/* Deallocates any pages entirely within the last EXCESS bytes of the BUF_LEN - long buffer, BUF. */ -error_t -deallocate_excess(vm_address_t buf, vm_size_t buf_len, vm_size_t excess) -{ - vm_size_t excess_pages = buf_len - round_page(buf_len - excess); - if (excess_pages > 0) - return - vm_deallocate(mach_task_self(), - round_page(buf + buf_len - excess), excess_pages); - else - return 0; -} diff --git a/devio/mem.h b/devio/mem.h deleted file mode 100644 index e19b590c..00000000 --- a/devio/mem.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Some random handy memory ops that know about VM. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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. */ - -/* For bcopy &c. */ -#include <string.h> - -/* Makes sure that BUF, points to a buffer with AMOUNT bytes available. - *BUF_LEN should be the current length of *BUF, and if this isn't enough to - hold AMOUNT bytes, then more is allocated and the new buffer is returned - in *BUF and *BUF_LEN. If a memory allocation error occurs, the error code - is returned, otherwise 0. */ -error_t allocate(vm_address_t *buf, vm_size_t *buf_len, vm_size_t amount); - -/* Deallocates any pages entirely within the last EXCESS bytes of the BUF_LEN - long buffer, BUF. */ -error_t deallocate_excess(vm_address_t buf, vm_size_t buf_len, vm_size_t excess); diff --git a/devio/open.c b/devio/open.c deleted file mode 100644 index bab4fe99..00000000 --- a/devio/open.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Per-open information for devio. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> - -#include "open.h" -#include "window.h" -#include "dev.h" - -/* ---------------------------------------------------------------- */ - -/* Returns a new per-open structure for the device DEV in OPEN. If an error - occurs, the error-code is returned, otherwise 0. */ -error_t -open_create(struct dev *dev, struct open **open) -{ - error_t err; - - *open = malloc(sizeof(struct open)); - - if (*open == NULL) - return ENOMEM; - - (*open)->dev = dev; - - err = io_state_init(&(*open)->io_state, dev); - - if (!err && dev_is(dev, DEV_BUFFERED) && !dev_is(dev, DEV_SERIAL)) - /* A random-access buffered device -- use a pager to do i/o to it. */ - { - mach_port_t memobj; - err = dev_get_memory_object(dev, &memobj); - if (!err) - err = - window_create(memobj, dev->size, 0, 0, dev_is(dev, DEV_READONLY), - &(*open)->window); /* XXX sizes */ - if (err) - { - mach_port_destroy(mach_task_self(), memobj); - io_state_finalize(&(*open)->io_state); - } - } - else - (*open)->window = NULL; - - if (err) - free(*open); - - return err; -} - -/* ---------------------------------------------------------------- */ - -/* Free OPEN and any resources it holds. */ -void -open_free(struct open *open) -{ - io_state_finalize(&open->io_state); - window_free(open->window); - free(open); -} - - -/* ---------------------------------------------------------------- */ - -/* Returns the appropiate io_state object for OPEN (which may be either - per-open or a per-device depending on the device). */ -struct io_state * -open_get_io_state(struct open *open) -{ - return - dev_is(open->dev, DEV_SERIAL) ? &open->dev->io_state : &open->io_state; -} diff --git a/devio/open.h b/devio/open.h deleted file mode 100644 index 80763585..00000000 --- a/devio/open.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Per-open information for devio. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 __OPEN_H__ -#define __OPEN_H__ - -#include "iostate.h" - -/* ---------------------------------------------------------------- */ - -/* A structure describing a particular i/o stream on this device. */ -struct open -{ - /* Current state of our output stream -- location and the buffer used to do - buffered i/o. */ - struct io_state io_state; - - /* The memory window we're using to do i/o. This may be NULL, indicating - we're not doing buffered random access i/o. */ - struct window *window; - - /* The device that this an open on. */ - struct dev *dev; -}; - -/* Returns a new per-open structure for the device DEV in OPEN. If an error - occurs, the error-code is returned, otherwise 0. */ -error_t open_create(struct dev *dev, struct open **open); - -/* Free OPEN and any resources it holds. */ -void open_free(struct open *open); - -/* Returns the appropiate io_state object for OPEN (which may be either - per-open or a per-device depending on the device). */ -struct io_state *open_get_io_state(struct open *open); - -/* Writes up to LEN bytes from BUF to OPEN's device at device offset OFFS - (which may be ignored if the device doesn't support random access), - and returns the number of bytes written in AMOUNT. If no error occurs, - zero is returned, otherwise the error code is returned. */ -error_t open_write(struct open *open, vm_address_t buf, vm_size_t len, - vm_size_t *amount, off_t offs); - -/* Reads up to AMOUNT bytes from the device into BUF and BUF_LEN using the - standard mach out-array convention. If no error occurs, zero is returned, - otherwise the error code is returned. */ -error_t open_read(struct open *open, vm_address_t *buf, vm_size_t *buf_len, - vm_size_t amount, off_t offs); - -/* Set OPEN's location to OFFS, interpreted according to WHENCE as by seek. - The new absolute location is returned in NEW_OFFS (and may not be the same - as OFFS). If no error occurs, zero is returned, otherwise the error code - is returned. */ -error_t open_seek (struct open *open, off_t offs, int whence, off_t *new_offs); - -#endif /* !__OPEN_H__ */ diff --git a/devio/ptypes.h b/devio/ptypes.h deleted file mode 100644 index 64aa3b0d..00000000 --- a/devio/ptypes.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Libports port types for devio. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 PT_FSYS 0 -#define PT_NODE 1 -#define PT_MEMOBJ 2 diff --git a/devio/rdwr.c b/devio/rdwr.c deleted file mode 100644 index 67f087a0..00000000 --- a/devio/rdwr.c +++ /dev/null @@ -1,471 +0,0 @@ -/* Implements various types of I/O on top of raw devices. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> -#include <assert.h> -#include <string.h> - -#include "open.h" -#include "dev.h" -#include "mem.h" -#include "window.h" - -/* ---------------------------------------------------------------- */ - -/* Writes BUF to DEV, copying through an intermediate buffer to page-align - it. If STAGING_BUF isn't 0, it is used as the copy buffer for - small-enough transfers (staging_buf is assumed to be one block in length). - AMOUNT is the actual amount written, and LEN is the amount of source - material actually in BUF; if LEN is smaller than AMOUNT, the remainder is - zero. */ -static error_t -copying_block_write(struct dev *dev, vm_address_t staging_buf, - vm_address_t buf, vm_size_t len, vm_size_t amount, - vm_offset_t *offs) -{ - error_t err = 0; - vm_address_t copy_buf = staging_buf; - vm_size_t copy_buf_len = dev->block_size; - - if (amount > dev->block_size || staging_buf == 0) - { - copy_buf_len = amount; - err = vm_allocate(mach_task_self(), ©_buf, copy_buf_len, 1); - if (err) - return err; - } - - bcopy((char *)buf, (char *)copy_buf, len); - if (len < amount && copy_buf == staging_buf) - /* We need to zero the rest of the bloc, but only if we didn't - vm_allocate it (in which case it will be zero-filled). */ - bzero((char *)buf + len, amount - len); - - err = dev_write(dev, copy_buf, amount, offs); - - if (copy_buf != staging_buf) - vm_deallocate(mach_task_self(), copy_buf, copy_buf_len); - - return err; -} - -/* ---------------------------------------------------------------- */ - -/* Copies LEN bytes from BUF to DEV, using STAGING_BUF to do buffering of - partial blocks, and returning the amount actually written in AMOUNT. - *OFFS is incremented to reflect the amount read/written. If an error - occurs, the error code is returned, otherwise 0. */ -error_t -buffered_write(struct dev *dev, vm_address_t staging_buf, - vm_address_t buf, vm_size_t len, vm_size_t *amount, - vm_offset_t *offs) -{ - error_t err = 0; - int bsize = dev->block_size; - int staging_buf_loc = *offs % bsize; - int left_in_staging_buf = bsize - staging_buf_loc; - vm_offset_t start_offs = *offs; - - if (left_in_staging_buf > 0) - /* Write what's buffered from the last I/O. */ - { - /* Amount of the current i/o we can put in the staging buffer. */ - int stage = (left_in_staging_buf > len ? len : left_in_staging_buf); - - bcopy((char *)buf, (char *)staging_buf + staging_buf_loc, stage); - - buf += stage; - len -= stage; - *offs += stage; - - if (stage == left_in_staging_buf) - /* We've filled up STAGING_BUF so we can write it out now. */ - { - /* Backup OFFS to reflect the beginning-of-block position. */ - *offs -= bsize; - err = dev_write(dev, staging_buf, bsize, offs); - } - } - - if (!err && len > bsize) - /* Enough i/o pending to do whole block transfers. */ - { - /* The number of bytes at the end of the transfer that aren't a - multiple of the block-size. We have to deal with these separately - because device i/o must be in block multiples. */ - int excess = len % bsize; - vm_size_t block_len = len - excess; - - if (dev_write_valid(dev, buf, block_len, offs)) - /* BUF is page-aligned, so we can do i/o directly to the device, or - it is small enough that it doesn't matter. */ - err = dev_write(dev, buf, block_len, offs); - else - /* Argh! BUF isn't page aligned! We must filter the i/o though an - intermediate buffer... */ - err = copying_block_write(dev, staging_buf, - buf, block_len, block_len, offs); - - if (*offs - start_offs < left_in_staging_buf + block_len) - /* Didn't write out all the blocks, so suppress buffering the rest. */ - len = 0; - else - len = excess; - } - - /* At this point, LEN should be < BLOCK_SIZE, so we use buffering again. */ - if (!err && len > 0) - { - bcopy((char *)staging_buf, (char *)buf, len); - *offs += len; - } - - *amount = *offs - start_offs; - if (*amount > 0) - /* If an error occurred, but we successfully wrote *something*, then - pretend nothing bad happened; the error will probably get caught next - time. */ - err = 0; - - return err; -} - -/* ---------------------------------------------------------------- */ - -/* Reads AMOUNT bytes from DEV and returns them in BUF and BUF_LEN (using the - standard mach out-array conventions), using STAGING_BUF to do buffering of - partial blocks. *OFFS is incremented to reflect the amount read/written. - If an error occurs, the error code is returned, otherwise 0. */ -error_t -buffered_read (struct dev *dev, vm_address_t staging_buf, - vm_address_t *buf, vm_size_t *buf_len, vm_size_t amount, - vm_offset_t *offs) -{ - error_t err = 0; - int bsize = dev->block_size; - vm_offset_t start_offs = *offs; - int staging_buf_loc = *offs % bsize; - int from_staging_buf = bsize - staging_buf_loc; - vm_address_t block_buf = *buf; - vm_size_t block_buf_size = *buf_len; - vm_size_t block_amount = amount; - - if (staging_buf_loc > 0) - { - /* Read into a temporary buffer. */ - block_buf = 0; - block_buf_size = 0; - - if (from_staging_buf > amount) - from_staging_buf = amount; - - block_amount -= from_staging_buf; - } - else - from_staging_buf = 0; - - /* Read any new block required. */ - if (block_amount > 0) - { - /* We read enough to get every full block of BLOCK_AMOUNT, plus an - additional whole block if there's any more; we just copy any excess - from that last block into STAGING_BUF for next time. */ - block_amount = ((block_amount + bsize - 1) / bsize) * bsize; - - err = dev_read(dev, &block_buf, &block_buf_size, block_amount, offs); - if (err && staging_buf_loc > 0) - /* We got an error, but don't abort, since we did get the bit from - the buffer. */ - { - err = 0; - amount = from_staging_buf; - block_amount = 0; - } - - if (amount > *offs - start_offs) - /* If we read less than we hoped, reflect this down below. */ - amount = *offs - start_offs; - } - - if (staging_buf_loc > 0) - /* Coalesce what we have in STAGING_BUF with what we read. */ - { - err = allocate(buf, buf_len, amount); - assert_perror(err); - bcopy((char *)staging_buf + staging_buf_loc, (char *)*buf, - from_staging_buf); - - if (block_amount > 0) - bcopy((char *)block_buf, (char *)*buf + from_staging_buf, - amount - from_staging_buf); - } - else - /* Otherwise, BLOCK_BUF should already contain the correct data. */ - { - *buf = block_buf; - *buf_len = block_buf_size; - } - - if (*offs - start_offs > amount) - /* We've read too far, so put some amount from the end back into - STAGING_BUF. */ - { - int excess = (*offs - start_offs) - amount; - - bcopy((char *)block_buf + amount, - (char *)staging_buf + bsize - excess, - excess); - *offs -= excess; - - if (excess >= vm_page_size) - deallocate_excess(*buf, *buf_len, excess); - *buf_len -= excess; - } - - /* Deallocate any extra copy buffer if necessary. */ - if (*buf != block_buf) - vm_deallocate(mach_task_self(), block_buf, block_buf_size); - - return err; -} - -/* ---------------------------------------------------------------- */ - -/* Write BUF_LEN bytes from BUF to DEV, padding with zeros as necessary to - write whole blocks, and returning the amount actually written in AMOUNT. - If successful, 0 is returned, otherwise an error code is returned. *OFFS - is incremented by the change in device location. */ -error_t -raw_write(struct dev *dev, - vm_address_t buf, vm_size_t buf_len, - vm_size_t *amount, vm_offset_t *offs) -{ - error_t err; - int bsize = dev->block_size; - int block_amount = ((buf_len + bsize - 1) / bsize) * bsize; - vm_offset_t start_offs = *offs; - - if (start_offs % bsize != 0) - return EINVAL; - - if (block_amount == buf_len && dev_write_valid(dev, buf, block_amount, offs)) - /* BUF is page-aligned, so we can do i/o directly to the device, or - it is small enough that it doesn't matter. */ - err = dev_write(dev, buf, block_amount, offs); - else - /* Argh! BUF isn't page aligned! We must filter the i/o though an - intermediate buffer... [We use DEV's io_state buffer, as we know - that the io_state is locked in open_rdwr, and it isn't otherwise - used...] */ - err = copying_block_write(dev, dev->io_state.buffer, - buf, buf_len, block_amount, offs); - - if (!err && *offs - start_offs < buf_len) - *amount = *offs - start_offs; - else - *amount = buf_len; - - return err; -} - -/* Read AMOUNT bytes from DEV into BUF and BUF_LEN; only whole blocks are - read, but anything greater than *AMOUNT bytes is discarded. The standard - mach out-array convention is used to return the data in BUF and BUF_LEN. - If successful, 0 is returned, otherwise an error code is returned. *OFFS - is incremented by the change in device location. */ -error_t -raw_read(struct dev *dev, - vm_address_t *buf, vm_size_t *buf_len, - vm_size_t amount, vm_offset_t *offs) -{ - error_t err; - int bsize = dev->block_size; - int block_amount = ((amount + bsize - 1) / bsize) * bsize; - - if (*offs % bsize != 0) - return EINVAL; - - err = dev_read(dev, buf, buf_len, block_amount, offs); - if (!err) - { - int excess = *buf_len - amount; - if (excess > vm_page_size) - deallocate_excess(*buf, *buf_len, excess); - if (excess > 0) - *buf_len = amount; - } - - return err; -} - -/* ---------------------------------------------------------------- */ - -struct rdwr_state -{ - struct dev *dev; - off_t user_offs; - vm_offset_t *offs_p; - struct io_state *io_state; -}; - -/* Setup state needed for I/O to/from OPEN, putting it into STATE. OFFS - should be the original user-supplied offset. */ -static void -rdwr_state_init(struct rdwr_state *state, struct open *open, off_t offs) -{ - state->dev = open->dev; - state->io_state = open_get_io_state(open); - state->user_offs = offs; - - if (dev_is(state->dev, DEV_SERIAL)) - /* For serial i/o, we always ignore the proffered offs, and use the - actual device offset. */ - state->user_offs = -1; - - if (state->user_offs == -1 || !dev_is(state->dev, DEV_BUFFERED)) - /* If we're going to use some bit of IO_STATE, lock it first. This - should only not happen if we're going to used windowed i/o with an - explicit offset. */ - io_state_lock(state->io_state); - - if (state->user_offs == -1) - state->offs_p = &state->io_state->location; - else - state->offs_p = (vm_offset_t *)&state->user_offs; -} - -/* Destroy any state created by rdwr_state_init. */ -static void -rdwr_state_finalize(struct rdwr_state *state) -{ - if (state->user_offs == -1 || !dev_is(state->dev, DEV_BUFFERED)) - io_state_unlock(state->io_state); -} - -/* ---------------------------------------------------------------- */ - -/* Writes up to LEN bytes from BUF to OPEN's device at device offset OFFS - (which may be ignored if the device doesn't support random access), - and returns the number of bytes written in AMOUNT. If no error occurs, - zero is returned, otherwise the error code is returned. */ -error_t -open_write(struct open *open, vm_address_t buf, vm_size_t len, - vm_size_t *amount, off_t offs) -{ - error_t err; - struct rdwr_state state; - struct dev *dev = open->dev; - - rdwr_state_init(&state, open, offs); - - offs = *state.offs_p; - if (offs < 0) - err = EINVAL; - if (offs + len > dev->size) - err = EIO; - else if (!dev_is(dev, DEV_BUFFERED)) - err = raw_write(dev, buf, len, amount, state.offs_p); - else if (dev_is(dev, DEV_SERIAL)) - { - state.io_state->buffer_use = IO_STATE_BUFFERED_WRITE; - err = buffered_write(dev, state.io_state->buffer, buf, len, - amount, state.offs_p); - } - else - err = window_write(open->window, buf, len, amount, state.offs_p); - - rdwr_state_finalize(&state); - - return err; -} - -/* Reads up to AMOUNT bytes from the device into BUF and BUF_LEN using the - standard mach out-array convention. If no error occurs, zero is returned, - otherwise the error code is returned. */ -error_t -open_read(struct open *open, vm_address_t *buf, vm_size_t *buf_len, - vm_size_t amount, off_t offs) -{ - error_t err; - struct rdwr_state state; - struct dev *dev = open->dev; - - rdwr_state_init(&state, open, offs); - - offs = *state.offs_p; - if (offs < 0) - err = EINVAL; - if (offs + amount > dev->size) - err = EIO; - else if (!dev_is(dev, DEV_BUFFERED)) - err = raw_read(dev, buf, buf_len, amount, state.offs_p); - else if (dev_is(dev, DEV_SERIAL)) - { - state.io_state->buffer_use = IO_STATE_BUFFERED_READ; - err = buffered_read(dev, state.io_state->buffer, buf, buf_len, - amount, state.offs_p); - } - else - err = window_read(open->window, buf, buf_len, amount, state.offs_p); - - rdwr_state_finalize(&state); - - return err; -} - -/* Set OPEN's location to OFFS, interpreted according to WHENCE as by seek. - The new absolute location is returned in NEW_OFFS (and may not be the same - as OFFS). If no error occurs, zero is returned, otherwise the error code - is returned. */ -error_t -open_seek (struct open *open, off_t offs, int whence, off_t *new_offs) -{ - error_t err = 0; - struct io_state *io_state = open_get_io_state (open); - - if (!dev_is (open->dev, DEV_SEEKABLE)) - return ESPIPE; - - io_state_lock (io_state); - - switch (whence) - { - case SEEK_SET: - *new_offs = offs; break; - case SEEK_CUR: - *new_offs = io_state->location + offs; break; - case SEEK_END: - *new_offs = open->dev->size - offs; break; - default: - err = EINVAL; - } - - if (!err) - { - if (!dev_is (open->dev, DEV_BUFFERED)) - /* On unbuffered devices force seeks to the nearest block boundary. */ - *new_offs -= *new_offs % open->dev->block_size; - io_state->location = *new_offs; - } - - io_state_unlock (io_state); - - return err; -} diff --git a/devio/window.c b/devio/window.c deleted file mode 100644 index f7df045d..00000000 --- a/devio/window.c +++ /dev/null @@ -1,171 +0,0 @@ -/* Window management routines for buffered I/O using VM. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 <hurd.h> - -#include "window.h" -#include "mem.h" - -/* ---------------------------------------------------------------- */ - -/* Create a VM window onto the memory object MEMOBJ, and return it in WIN. - MIN_SIZE and MAX_SIZE are the minimum and maximum sizes that the window - will shrink/grow to (a value of 0 will use some default). */ -error_t -window_create(mach_port_t memobj, vm_offset_t max_pos, - vm_size_t min_size, vm_size_t max_size, int read_only, - struct window **win) -{ - *win = malloc(sizeof(struct window)); - if (*win == NULL) - return ENOMEM; - - if (min_size < max_size) - min_size = max_size; - - (*win)->pos = 0; - (*win)->max_pos = max_pos; - (*win)->size = 0; - (*win)->memobj = memobj; - (*win)->min_size = (min_size < vm_page_size ? vm_page_size : min_size); - (*win)->max_size = (max_size < vm_page_size ? vm_page_size : max_size); - (*win)->read_only = read_only; - - return 0; -} - -/* Free WIN and any resources it holds. */ -void -window_free(struct window *win) -{ - if (win->size > 0) - vm_deallocate(mach_task_self(), win->buffer, win->size); - mach_port_destroy(mach_task_self(), win->memobj); - free(win); -} - -/* ---------------------------------------------------------------- */ - -/* Makes sure that WIN's memory window contains at least positions POS - through POS + LEN on the device WIN's mapping. If an error occurs in the - process, the error code is returned (and WIN may not map the desired - locations), otherwise 0. WIN is assumed to already be locked when this is - called. */ -static error_t -position(struct window *win, vm_offset_t pos, vm_size_t len) -{ - vm_offset_t end = pos + len; - vm_offset_t win_beg = win->pos; - vm_offset_t win_end = win_beg + win->size; - - if (pos >= win_beg && end <= win_end) - /* The request is totally satisfied by our current position. */ - return 0; - else -#if 0 /* XXXXXXX */ - if (end < win_beg || pos >= win_end) - /* The desired locations are entirely outside our current window, so just - trash it, and map a new buffer anywhere. */ -#endif - { - int prot = VM_PROT_READ | (win->read_only ? 0 : VM_PROT_WRITE); - - if (win->size > 0) - vm_deallocate(mach_task_self(), win->buffer, win->size); - - win->pos = trunc_page(pos); - win->size = round_page(len + (pos - win->pos)); - win->buffer = 0; - - if (win->size < win->min_size) - win->size = win->min_size; - - if (win->pos + win->size > win->max_pos) - win->size = win->max_pos - win->pos; - - return - vm_map(mach_task_self(), &win->buffer, win->size, 0, 1, - win->memobj, win->pos, 0, prot, prot, VM_INHERIT_NONE); - } - - return 0; -} - -/* ---------------------------------------------------------------- */ - -/* Write up to BUF_LEN bytes from BUF to the device that WIN is a window on, - at offset *OFFS, using memory-mapped buffered I/O. If successful, 0 is - returned, otherwise an error code is returned. *OFFS is incremented by - the amount sucessfully written. */ -error_t -window_write(struct window *win, - vm_address_t buf, vm_size_t buf_len, vm_size_t *amount, - vm_offset_t *offs) -{ - error_t err; - - mutex_lock(&win->lock); - - err = position(win, *offs, buf_len); - if (!err) - { - bcopy((char *)buf, - (char *)win->buffer + (*offs - win->pos), - buf_len); - *amount = buf_len; - *offs += buf_len; - } - - mutex_unlock(&win->lock); - - return err; -} - -/* Read up to AMOUNT bytes from the device that WIN is a window on, at offset - *OFFS, into BUF and BUF_LEN (using the standard mach out-array - conventions), using memory-mapped buffered I/O. If successful, 0 is - returned, otherwise an error code is returned. *OFFS is incremented by - the amount sucessfully written. */ -error_t -window_read(struct window *win, - vm_address_t *buf, vm_size_t *buf_len, - vm_size_t amount, vm_offset_t *offs) -{ - error_t err; - - mutex_lock(&win->lock); - - err = position(win, *offs, amount); - if (!err) - { - err = allocate(buf, buf_len, amount); - if (!err) - { - bcopy((char *)win->buffer + (*offs - win->pos), - (char *)*buf, - amount); - *offs += amount; - } - } - - mutex_unlock(&win->lock); - - return err; -} diff --git a/devio/window.h b/devio/window.h deleted file mode 100644 index c15ebd9e..00000000 --- a/devio/window.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Window management routines for buffered I/O using VM. - - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - - This program 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. - - 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 __WINDOW_H__ -#define __WINDOW_H__ - -#include <mach.h> - -/* ---------------------------------------------------------------- */ - -/* A structure describing a memory window used to do buffered random access - device i/o through the device pager. */ -struct window -{ - /* The currently allocated vm window backed by the device pager. */ - vm_address_t buffer; - - /* The device offset of the window. */ - vm_offset_t pos; - /* The end of the device. */ - vm_offset_t max_pos; - - /* The length of the window (should be a multiple of __vm_page_size). If - this is 0, this window isn't allocated. */ - vm_size_t size; - /* If SIZE < MIN_SIZE we won't shrink the window. */ - vm_size_t min_size; - /* If SIZE > MAX_SIZE, we'll try and shrink the window to fit. */ - vm_size_t max_size; - - /* The device pager providing backing store for this window. */ - mach_port_t memobj; - /* True if the mapping should be read_only. */ - int read_only; - - /* Lock this if you want to read/write some field(s) here. */ - struct mutex lock; -}; - -/* Create a VM window onto the memory object MEMOBJ, and return it in WIN. - MIN_SIZE and MAX_SIZE are the minimum and maximum sizes that the window - will shrink/grow to. */ -error_t window_create(mach_port_t memobj, vm_offset_t max_pos, - vm_size_t min_size, vm_size_t max_size, int read_only, - struct window **win); - -/* Free WIN and any resources it holds. */ -void window_free(struct window *win); - -/* Write up to BUF_LEN bytes from BUF to the device that WIN is a window on, - at offset *OFFS, using memory-mapped buffered I/O. If successful, 0 is - returned, otherwise an error code is returned. *OFFS is incremented by - the amount sucessfully written. */ -error_t window_write(struct window *win, - vm_address_t buf, vm_size_t buf_len, vm_size_t *amount, - vm_offset_t *offs); - -/* Read up to AMOUNT bytes from the device that WIN is a window on, at offset - *OFFS, into BUF and BUF_LEN (using the standard mach out-array - conventions), using memory-mapped buffered I/O. If successful, 0 is - returned, otherwise an error code is returned. *OFFS is incremented by - the amount sucessfully written. */ -error_t window_read(struct window *win, - vm_address_t *buf, vm_size_t *buf_len, - vm_size_t amount, vm_offset_t *offs); - -#endif /* !__WINDOW_H__ */ diff --git a/libmom/ChangeLog b/libmom/ChangeLog deleted file mode 100644 index f04006c5..00000000 --- a/libmom/ChangeLog +++ /dev/null @@ -1,31 +0,0 @@ -Sat May 25 17:25:09 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * refs-identical.c (mom_ports_identical): Omit uses of deleted - members of struct mom_port_ref.c. - - * ref-destroy.c (mom_ref_destroy): Omit uses of deleted members of - struct mom_port_ref.c. - - * mach-port-set.c (mom_mach_port_set): Omit uses of deleted - members of struct mom_port_ref.c. - - * fetch-mach-port.c (mom_fetch_mach_port): Omit uses of deleted - members of struct mom_port_ref.c. - - * copy-ref.c (mom_copy_ref): Likewise. - - * mom-kerndep.h (struct mom_port_ref): Delete members `lock' and - `refcnt'. - * Makefile (SRCS): Delete add-ref.c and drop-ref.c. - * mom.h (mom_add_ref, mom_drop_ref): Delete functions. - * add-ref.c, drop-ref.c: Delete files. - -Fri May 24 16:14:54 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * mom.h: Include <mom-errors.h>. - * error-trans.c: New file. - * mom-kerndep.h (mom_error_translate_mach): New function. - * Makefile (LCLHDRS, installhdrs): Add mom-errors.h. - (SRCS): Add error-trans.c. - * mom-errors.h: New file. - diff --git a/libmom/Makefile b/libmom/Makefile deleted file mode 100644 index 04df2c9c..00000000 --- a/libmom/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written by Michael I. Bushnell, p/BSG. -# -# 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. - -dir := libmom -makemode := library - -libname = libmom - -SRCS = allocate-address.c allocate-memory.c copy-ref.c \ - deallocate-memory.c fetch-mach-port.c hash-ref.c \ - mach-port-set.c make-memory-readonly.c make-memory-readwrite.c \ - memory-init.c ref-destroy.c refs-identical.c reserve-memory.c \ - reserve-memory-anywhere.c unreserve-memory.c unuse-memory.c \ - wire-memory.c error-trans.c - -LCLHDRS = mom.h mom-kerndep.h priv.h mom-errors.h -installhdrs = mom.h mom-kerndep.h mom-errors.h -installhdrsubdir = . - -OBJS = $(SRCS:.c=.o) - -include ../Makeconf - - diff --git a/libmom/allocate-address.c b/libmom/allocate-address.c deleted file mode 100644 index fa017bac..00000000 --- a/libmom/allocate-address.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_allocate_address (void *start, size_t len, int readonly, - struct mom_port_ref *obj, size_t offset, - int copy) -{ - error_t err; - mach_port_t port; - - assert ((vm_address_t) start % vm_page_size == 0); - assert (len % vm_page_size == 0); - if (obj) - { - port = mom_fetch_mach_port (obj); - assert (offset % vm_page_size == 0); - } - else - port = MACH_PORT_NULL; - - mutex_lock (&_mom_memory_lock); - err = vm_map (mach_task_self (), (vm_address_t *)&start, len, 0, 0, - port, (obj ? offset : 0), (obj ? copy : 0), - (VM_PROT_READ | VM_PROT_EXECUTE - | (!readonly ? VM_PROT_WRITE : 0)), - VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_WRITE, - VM_INHERIT_COPY); - mutex_unlock (&_mom_memory_lock); - return err; -} diff --git a/libmom/allocate-memory.c b/libmom/allocate-memory.c deleted file mode 100644 index d98632bc..00000000 --- a/libmom/allocate-memory.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_allocate_memory (void **start, size_t len, int readonly, - struct mom_port_ref *obj, size_t offset, - int copy) -{ - error_t err; - mach_port_t port; - - assert (len % vm_page_size == 0); - if (obj) - { - port = mom_fetch_mach_port (obj); - assert (offset % vm_page_size == 0); - } - else - port = MACH_PORT_NULL; - - *start = 0; - - mutex_lock (&_mom_memory_lock); - err = vm_map (mach_task_self (), (vm_address_t *)start, len, 0, 0, - port, (obj ? offset : 0), (obj ? copy : 0), - (VM_PROT_READ | VM_PROT_EXECUTE - | (!readonly ? VM_PROT_WRITE : 0)), - VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_WRITE, - VM_INHERIT_COPY); - mutex_unlock (&_mom_memory_lock); - return err; -} diff --git a/libmom/copy-ref.c b/libmom/copy-ref.c deleted file mode 100644 index 03d4ab45..00000000 --- a/libmom/copy-ref.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copy a mom port reference - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_copy_ref (struct mom_port_ref *new, - struct mom_port_ref *obj) -{ - error_t err; - - err = mach_port_mod_refs (mach_task_self (), - obj->port, MACH_PORT_RIGHT_SEND, 1); - if (!err) - new->port = obj->port; - return err; -} diff --git a/libmom/deallocate-memory.c b/libmom/deallocate-memory.c deleted file mode 100644 index bf7acfdb..00000000 --- a/libmom/deallocate-memory.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_deallocate_memory (void *start, size_t len) -{ - error_t err; - - assert ((vm_address_t) start % vm_page_size == 0); - assert (len % vm_page_size == 0); - - mutex_lock (&_mom_memory_lock); - err = vm_deallocate (mach_task_self (), (vm_address_t) start, len); - mutex_unlock (&_mom_memory_lock); - return err; -} diff --git a/libmom/error-trans.c b/libmom/error-trans.c deleted file mode 100644 index 57ef7e31..00000000 --- a/libmom/error-trans.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -mom_error_t -mom_error_translate_mach (error_t macherr) -{ - switch (macherr) - { - case EMACH_SEND_INVALID_DEST: - return EMOM_INVALID_DEST; - - case EMACH_SEND_INVALID_RIGHT: - return EMOM_INVALID_REF; - - case EMIG_SERVER_DIED: - return EMOM_SERVER_DIED; - - default: - return macherr; - } -} diff --git a/libmom/fetch-mach-port.c b/libmom/fetch-mach-port.c deleted file mode 100644 index 85262600..00000000 --- a/libmom/fetch-mach-port.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Return the Mach port corresponding to a mom port reference - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -mach_port_t -mom_fetch_mach_port (struct mom_port_ref *obj) -{ - return obj->port; -} diff --git a/libmom/hash-ref.c b/libmom/hash-ref.c deleted file mode 100644 index 6c160b1b..00000000 --- a/libmom/hash-ref.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Return a hash key for a mom port - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -int -mom_hash_port (struct mom_port_ref *obj) -{ - return mom_fetch_mach_port (obj); -} - diff --git a/libmom/mach-port-set.c b/libmom/mach-port-set.c deleted file mode 100644 index ed6842fd..00000000 --- a/libmom/mach-port-set.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Initialize a mom port reference from a Mach port - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_mach_port_set (struct mom_port_ref *obj, - mach_port_t port) -{ - obj->port = port; - return 0; -} - diff --git a/libmom/make-memory-readonly.c b/libmom/make-memory-readonly.c deleted file mode 100644 index e7ca4c87..00000000 --- a/libmom/make-memory-readonly.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_make_memory_readonly (void *start, size_t len) -{ - error_t err; - - assert ((vm_address_t) start % vm_page_size == 0); - assert (len % vm_page_size == 0); - - mutex_lock (&_mom_memory_lock); - err = vm_protect (mach_task_self (), (vm_address_t) start, len, 0, - VM_PROT_READ | VM_PROT_EXECUTE); - mutex_unlock (&_mom_memory_lock); - return err; -} diff --git a/libmom/make-memory-readwrite.c b/libmom/make-memory-readwrite.c deleted file mode 100644 index f35e6bfd..00000000 --- a/libmom/make-memory-readwrite.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_make_memory_readwrite (void *start, size_t len) -{ - error_t err; - - assert ((vm_address_t) start % vm_page_size == 0); - assert (len % vm_page_size == 0); - - mutex_lock (&_mom_memory_lock); - err = vm_protect (mach_task_self (), (vm_address_t) start, len, 0, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); - mutex_unlock (&_mom_memory_lock); - return err; -} diff --git a/libmom/memory-init.c b/libmom/memory-init.c deleted file mode 100644 index 38972018..00000000 --- a/libmom/memory-init.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Initialization and static data for mom memory management. - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -struct mutex _mom_memory_lock = MUTEX_INITIALIZER; -size_t mom_page_size; - -static void init_memory (void) __attribute__ ((constructor)); - -static void -init_memory (void) -{ - mom_page_size = vm_page_size; -} diff --git a/libmom/mom-errors.h b/libmom/mom-errors.h deleted file mode 100644 index 85a35d5e..00000000 --- a/libmom/mom-errors.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Error codes for MOM library - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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. */ - - -/* MOM uses Mach error system 0x11 and subsystem 0. */ -#define _MOM_ERRNO(n) ((0x11 << 26 | ((n) & 0x3fff))) - -enum __momerrors_error_codes -{ - /* These are standard errors to be returned by RPC user stubs - in Mom systems. */ - - /* All Mom systems must detect and return these errors */ - - /* The RPC attempted to send to an invalid mom_port_ref. This can - happen because, for example, the server it spoke to has died. */ - EMOM_INVALID_DEST = _MOM_ERRNO (1), - - /* The RPC attempted to send an invalid mom_port_ref in its content. - This shall not happen if the server the reference is to has - merely died. */ - EMOM_INVALID_REF = _MOM_ERRNO (2), - - /* The server began processing the RPC, but at some point it died. */ - EMOM_SERVER_DIED = _MOM_ERRNO (3) -}; - -typedef enum __momerrors_error_codes mom_error_t; - - diff --git a/libmom/mom-kerndep.h b/libmom/mom-kerndep.h deleted file mode 100644 index cc61db05..00000000 --- a/libmom/mom-kerndep.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Mach-specific type definitions for MOM - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 <mach/mach.h> -#include <spin-lock.h> - -struct mom_port_ref -{ - mach_port_t port; -}; - -/* Mach-specific functions */ - -/* Initialize OBJ with a reference to Mach port PORT. One Mach user - reference is consumed. */ -error_t mom_mach_port_set (struct mom_port_ref *obj, mach_port_t port); - -/* Return the Mach port corresponding to OBJ. No new Mach user - references are created, so this Mach port should not be used - after OBJ has been destroyed. */ -mach_port_t mom_fetch_mach_port (struct mom_port_ref *obj); - -/* Turn a Mach error number into a Mom error number. */ -mom_error_t mom_error_translate_mach (error_t macherr); diff --git a/libmom/mom.h b/libmom/mom.h deleted file mode 100644 index 75d4b08d..00000000 --- a/libmom/mom.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Microkernel object module - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 <stdlib.h> -#include <errno.h> - -#include <mom-errors.h> - -/* This header file defines structure layouts for the use of functions - below; it is specific to the particular microkernel in use. */ -#include <mom-kerndep.h> - - - - - -/* User RPC endpoints */ - -/* A communications end-point suitable for sending RPC's to servers. */ -struct mom_port_ref; /* layout defined in mom-kerndep.h */ - -/* Create a new port reference that refers to the same underlying channel - as OBJ. Fill *NEW with the new reference. NEW should be otherwise - unused memory. */ -error_t mom_copy_ref (struct mom_port_ref *new, struct mom_port_ref *obj); - -/* Tell if two mom ports refer to the same underlying server RPC channel */ -int mom_refs_identical (struct mom_port_ref *obj1, struct mom_port_ref *obj2); - -/* Return a hash key for a port. Different ports may have the same - hash key, but no port's hash key will ever change as long as that - port is known to this task. Two identical ports (as by - mom_ports_identical) will always have the same hash key. */ -int mom_hash_ref (struct mom_port_ref *obj); - -/* Destroy mom port reference OBJ and deallocate the underlying kernel - object. After this call, the memory in *OBJ may be used by the - user for any purpose. It is an error to call this routine if any - other thread might be calling any other mom port reference function - on OBJ concurrently. */ -void mom_ref_destroy (struct mom_port_ref *obj); - - - -/* Memory management */ - -/* Size of a physical page; mom memory management calls must be in - aligned multiples of this value. */ -extern size_t mom_page_size; - -/* Reserve a region of memory from START and continuing for LEN bytes - so that it won't be used by anyone, but don't make it directly - usable. */ -error_t mom_reserve_memory (void *start, size_t len); - -/* Reserve a region of memory anywhere of size LEN bytes and return - its address in ADDR. */ -error_t mom_reserve_memory_anywhere (void **addr, size_t len); - -/* Make a reserved region of memory usable, as specified by START and - LEN. If READONLY is set then only make it available for read - access; otherwise permit both read and write. If OBJ is null, then - use zero-filled anonymous storage. If OBJ is non-null, then it - specifies a mom port reference referring to a memory server, and - OFFSET is the offset within that server. If COPY is set, then the - data is copied from the memory object, otherwise it shares with - other users of the same object. */ -error_t mom_use_memory (void *start, size_t len, int readonly, - struct mom_port_ref *obj, size_t offset, - int copy); - -/* Ask the kernel to wire the region of memory specified to physical - memory. The exact semantics of this are kernel dependent; it is - also usually privileged in some fashion and will fail for - non-privileged users. */ -error_t mom_wire_memory (void *start, size_t len); - -/* Convert a region of usable memory to read-only */ -error_t mom_make_memory_readonly (void *start, size_t len); - -/* Convert a region of usable memory to read/write */ -error_t mom_make_memory_readwrite (void *start, size_t len); - -/* Convert a region of usable memory to reserved but unusable status. */ -error_t mom_unuse_memory (void *start, size_t len); - -/* Convert a region of reserved unusable memory to unreserved status. */ -error_t mom_unreserve_memory (void *start, size_t len); - - - -/* Optimized combination versions of memory functions; these are very - likely to be faster than using the two call sequences they are - equivalent to. */ - -/* Combined version of mom_unuse_memory followed by mom_unreserve_memory. */ -error_t mom_deallocate_memory (void *start, size_t len); - -/* Combined version of mom_reserve_memory and mom_use_memory. */ -error_t mom_allocate_address (void *start, size_t len, int readonly, - struct mom_port_ref *obj, size_t offset, - int copy); - -/* Combined version of mom_reserve_memory_anywhere and mom_use_memory. */ -error_t mom_allocate_memory (void **start, size_t len, int readonly, - struct mom_port_ref *obj, size_t offset, - int copy); - -/* Shorthand for the most common sort of allocation--like mom_allocate_memory, - but READONLY, and OBJ are both null. */ -#define mom_allocate(start,len) \ - (mom_allocate_memory ((start), (len), 0, 0, 0, 0)) - diff --git a/libmom/priv.h b/libmom/priv.h deleted file mode 100644 index 88d2d9ed..00000000 --- a/libmom/priv.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "mom.h" -#include <assert.h> -#include <cthreads.h> - -extern struct mutex _mom_memory_lock; - - diff --git a/libmom/ref-destroy.c b/libmom/ref-destroy.c deleted file mode 100644 index 6966bcdc..00000000 --- a/libmom/ref-destroy.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Completely destroy a MOM port - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -void -mom_ref_destroy (struct mom_port_ref *obj) -{ - mach_port_deallocate (mach_task_self (), obj->port); -} - - diff --git a/libmom/refs-identical.c b/libmom/refs-identical.c deleted file mode 100644 index 0c4ee885..00000000 --- a/libmom/refs-identical.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Tell if two mom port references refer to the same channel - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -int -mom_ports_identical (struct mom_port_ref *obj1, - struct mom_port_ref *obj2) -{ - return obj1->port == obj2->port; -} diff --git a/libmom/reserve-memory-anywhere.c b/libmom/reserve-memory-anywhere.c deleted file mode 100644 index 40f9ec00..00000000 --- a/libmom/reserve-memory-anywhere.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_reserve_memory_anywhere (void **start, size_t len) -{ - error_t err; - - assert (len % vm_page_size == 0); - - *start = 0; - - mutex_lock (&_mom_memory_lock); - err = vm_map (mach_task_self (), (vm_address_t *)&start, len, 0, 1, - MACH_PORT_NULL, 0, 0, 0, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE, - VM_INHERIT_COPY); - mutex_unlock (&_mom_memory_lock); - - return err; -} diff --git a/libmom/reserve-memory.c b/libmom/reserve-memory.c deleted file mode 100644 index ada9ef02..00000000 --- a/libmom/reserve-memory.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Reserve memory - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_reserve_memory (void *start, size_t len) -{ - error_t err; - - assert ((vm_address_t) start % vm_page_size == 0); - assert (len % vm_page_size == 0); - - mutex_lock (&_mom_memory_lock); - err = vm_map (mach_task_self (), (vm_address_t *)&start, len, 0, 0, - MACH_PORT_NULL, 0, 0, 0, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE, - VM_INHERIT_COPY); - mutex_unlock (&_mom_memory_lock); - - return err; -} - - diff --git a/libmom/unreserve-memory.c b/libmom/unreserve-memory.c deleted file mode 100644 index 88e8eb94..00000000 --- a/libmom/unreserve-memory.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_unreserve_memory (void *start, size_t len) -{ - return mom_deallocate_memory (start, len); -} diff --git a/libmom/unuse-memory.c b/libmom/unuse-memory.c deleted file mode 100644 index 363f2a45..00000000 --- a/libmom/unuse-memory.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - -error_t -mom_unuse_memory (void *start, size_t len) -{ - error_t err; - - assert ((vm_address_t) start % vm_page_size == 0); - assert (len % vm_page_size == 0); - - mutex_lock (&_mom_memory_lock); - /* Deallocate and reallocate so that we drop any mapping around. */ - err = vm_deallocate (mach_task_self (), (vm_address_t) start, len); - if (!err) - err = vm_map (mach_task_self (), (vm_address_t *)&start, len, 0, 0, - MACH_PORT_NULL, 0, 0, 0, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE, - VM_INHERIT_COPY); - mutex_unlock (&_mom_memory_lock); - return err; -} - - diff --git a/libmom/wire-memory.c b/libmom/wire-memory.c deleted file mode 100644 index b3832154..00000000 --- a/libmom/wire-memory.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - 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 "priv.h" - - -error_t -mom_wire_memory (void *start, size_t len) -{ - return EOPNOTSUPP; -} diff --git a/mkbootfs/ChangeLog b/mkbootfs/ChangeLog deleted file mode 100644 index 787943a2..00000000 --- a/mkbootfs/ChangeLog +++ /dev/null @@ -1,22 +0,0 @@ -Fri Jul 22 10:38:17 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile: Rewritten in accord with new scheme. - -Wed Jul 20 16:24:08 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (mkbootfs): Put -n after hostname for compat with - old broken rsh. - Use gcc literally instead of MIGHOSTCC. - -Tue Jul 5 14:22:00 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * Makefile (SRCS): New variable. - -Fri May 6 13:25:47 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * Makefile (mkbootfs): Use MIGHOSTCC instead of CC. - -Thu May 5 19:06:21 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * Makefile (mkbootfs): Call rsh with -n flag. - diff --git a/mkbootfs/Makefile b/mkbootfs/Makefile deleted file mode 100644 index df5af560..00000000 --- a/mkbootfs/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (C) 1993, 1994 Free Software Foundation -# -# This program 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. -# -# 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. - -dir := mkbootfs -makemode := misc - -SRCS = mkbootfs.c - -include ../Makeconf - -all: mkbootfs - -mkbootfs: mkbootfs.c - rsh $(mighost) -n cd `pwd` \; gcc mkbootfs.c -o mkbootfs - -clean: - rm -f mkbootfs *.o - diff --git a/mkbootfs/mkbootfs.c b/mkbootfs/mkbootfs.c deleted file mode 100644 index e3ad7137..00000000 --- a/mkbootfs/mkbootfs.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Make a bootstrap filesystem from a filesystem and an exec server - Copyright (C) 1993, 1994 Free Software Foundation - -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. */ - -/* Written by Michael I. Bushnell. */ - -/* The job is to write a .o corresponding to the exec server. This - .o contains the following symbols: - - _execserver_text_size - _execserver_data_size - _execserver_bss_size - _execserver_text - _execserver_data - _execserver_start - - The .o will then be linked along with the rest of the filesystem, which - will spawn an execserver with the right bits when it starts. - - The text should be loaded at 0x10000 and the data at - 0x10000 + _execserver_text_size and the bss cleared at - 0x10000 + _execserver_text_size + _execserver_data_size. - */ - -/* This is non-general, and only intended for the i386 Mach 3.0 with - its own weird format. It expects the header files to be from such a - Mach system as CMU sets them up. */ - -#include <a.out.h> -#include <stdio.h> -#include <sys/file.h> - -/* Usage: mkbootfs execserver newdoto */ - -main (int argc, char **argv) -{ - int execserver, newdoto; - struct exec a, newa; - unsigned long foo; - void *buf; - struct nlist n; - - signal (0, 0); - - if (argc != 3) - { - fprintf (stderr, "Usage: %s execserver newdoto\n", argv[0]); - exit (1); - } - - execserver = open (argv[1], O_RDONLY); - if (execserver == -1) - { - perror (argv[1]); - exit (1); - } - - newdoto = open (argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (newdoto == -1) - { - perror (argv[2]); - exit (1); - } - - read (execserver, &a, sizeof (struct exec)); - - /* Write the new data segment to the new file. */ - lseek (newdoto, sizeof (struct exec), L_SET); - - /* First, _execserver_text_size */ - foo = a.a_text + sizeof (struct exec); - write (newdoto, &foo, sizeof foo); - - /* Next, _execserver_data_size */ - write (newdoto, &a.a_data, sizeof a.a_data); - - /* Next, _execserver_bss_size */ - write (newdoto, &a.a_bss, sizeof a.a_bss); - - /* Next, _execserver_text */ - buf = malloc (a.a_text + sizeof (struct exec)); - lseek (execserver, 0, L_SET); - read (execserver, buf, a.a_text + sizeof (struct exec)); - write (newdoto, buf, a.a_text + sizeof (struct exec)); - free (buf); - - /* Next, _execserver_data */ - buf = malloc (a.a_data); - read (execserver, buf, a.a_data); - write (newdoto, buf, a.a_data); - free (buf); - - /* Finally, _execserver_start */ - write (newdoto, &a.a_entry, sizeof a.a_entry); - - /* We have no relocation information */ - - /* Now, write the symbol table */ - n.n_un.n_strx = 50; - n.n_type = N_DATA | N_EXT; - n.n_value = 0; - - /* First, _execserver_text_size */ - write (newdoto, &n, sizeof (n)); - n.n_value += sizeof (foo); - - /* Now, _execserver_data_size */ - n.n_un.n_strx += 50; - write (newdoto, &n, sizeof (n)); - n.n_value += sizeof (foo); - - /* Now, _execserver_bss_size */ - n.n_un.n_strx += 50; - write (newdoto, &n, sizeof (n)); - n.n_value += sizeof (foo); - - /* Now, _execserver_text */ - n.n_un.n_strx += 50; - write (newdoto, &n, sizeof (n)); - n.n_value += a.a_text + sizeof (struct exec); - - /* Now, _execserver_data */ - n.n_un.n_strx += 50; - write (newdoto, &n, sizeof (n)); - n.n_value += a.a_data; - - /* Now, _execserver_start */ - n.n_un.n_strx += 50; - write (newdoto, &n, sizeof (n)); - n.n_value += sizeof (foo); - - /* Now, we have to write out the string table */ -#define DOSTRING(x) \ - write (newdoto, x, strlen (x) + 1); \ - lseek (newdoto, 50 - strlen (x) - 1, L_INCR); - - foo = 350; /* six strings and the beginning */ - write (newdoto, &foo, sizeof foo); - lseek (newdoto, 50 - sizeof foo, L_INCR); - - DOSTRING ("_execserver_text_size"); - DOSTRING ("_execserver_data_size"); - DOSTRING ("_execserver_bss_size"); - DOSTRING ("_execserver_text"); - DOSTRING ("_execserver_data"); - DOSTRING ("_execserver_start"); - - lseek (newdoto, -1, L_INCR); - foo = 0; - write (newdoto, &foo, 1); - - /* Now write out the header */ - a.a_magic = OMAGIC; - a.a_data = - (4 * sizeof (int) + a.a_text + a.a_data + sizeof (struct exec)); - a.a_text = 0; - a.a_bss = 0; - a.a_syms = 6 * sizeof n; - a.a_entry = 0; - a.a_trsize = 0; - a.a_drsize = 0; - lseek (newdoto, 0, L_SET); - write (newdoto, &a, sizeof a); - - exit (0); -} - - - diff --git a/serverboot/ChangeLog b/serverboot/ChangeLog deleted file mode 100644 index 79b9c123..00000000 --- a/serverboot/ChangeLog +++ /dev/null @@ -1,111 +0,0 @@ -Tue Jun 10 21:54:52 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * disk_inode.h (struct icommon): Use short instead of uid_t/gid_t - in structure definition; those are now 32 bit types. - - * bootstrap.c (main): Support running from command line too; this - is useful at least for simple debugging. - -1997-06-09 Miles Bader <miles@gnu.ai.mit.edu> - - * Makefile (LCLHDRS): Add mach-exec.h. - -Thu May 1 18:40:53 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * bootstrap.c (cthread_stack_size): Don't set special value here; - use the default. - -Wed Apr 30 12:01:53 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * default_pager.c (default_pager_default_thread): Now that this is - forked, rather than run directly by the first thread, we have to - gain kernel privileges to acquire reserved pages. - -Fri Apr 18 16:44:49 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * wiring.c (__vm_allocate): New function. - -Wed Apr 16 14:18:28 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * default_pager.c (debug): Turn off. - -Mon Apr 14 12:50:20 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * default_pager.c: Remove debugging printfs. - -Thu Apr 10 15:10:25 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * Makefile (installationdir): Set variable. - -Wed Apr 9 13:57:44 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * default_pager.c (default_pager_default_thread): New function. - Delete old variable with this name, it was never used. - (default_pager): Fork default_pager_default_thread instead of - doing it here to avoid the possibility that we are on a tiny - stack. Current thread dies. - -Thu Apr 3 20:00:58 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * elf-load.c (exec_load): Include <elf.h> instead of - <mach/exec/elf.h>. Include "mach-exec.h" instead of - <mach/exec/elf.h>. - (exec_load) [i386]: Check for i386 types directly; abandon old - MY_EI_DATA and MY_E_MACHINE. - * load.c: Include "mach-exec.h" instead of <mach/exec/elf.h>. - * exec.c: Likewise. - * mach-exec.h: New file. - -Wed Mar 19 14:45:27 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * panic.c (panic): Clear possible errors on stdout before printing - panic string. - -Mon Mar 17 13:13:50 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * wiring.c (wire_all_memory): Don't attempt wire if PROTECTION is - VM_PROT_NONE. - - * panic.c (panic): Be more informative about where the error is - coming from. - - * default_pager.c (create_paging_partition): Don't print - gratuitous output noise. - * load.c (boot_script_exec_cmd): Likewise. - -Wed Mar 12 10:53:00 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * ext2_file_io.c (ext2_open_file): Clear FP before beginning - work. - * ffs_file_io.c (ffs_open_file): Likewise. - * minix_file_io.c (minix_open_file): Likewise. - - * bootstrap.c (printf_init, safe_gets): New functions. - * console.c: Deleted file. - * Makefile (SRCS): Omit console.c and gets.c. - - * load.c (read_symtab_from_file): Comment out body of function. - We don't want this. - - * defs.h: Comment out redefinitions of common types. - - * default_pager.c: Include <cthreads.h> instead of - <mach/cthreads.h>. - * file_io.h: Likewise. - * kalloc.c: Likewise. - - * panic.c: Include <varargs.h> instead of <sys/varargs.h>. - - * default_pager.c (pager_read_offset): Cast return of NO_BLOCK - properly. - -Mon Mar 10 17:07:50 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * load.c: Find boot_script.h in ../boot. - * bootstrap.c: Likewise. - - * bootstrap.c (boot_panic): Repair syntax. - - * strfcns.c: Include <varargs.h> instead of <sys/varargs.h>. - * load.c: Likewise. - diff --git a/serverboot/Makefile b/serverboot/Makefile deleted file mode 100644 index bb5553fa..00000000 --- a/serverboot/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (C) 1997 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 def_pager_setup.c \ - ffs_file_io.c minix_ffs_compat.c default_pager.c file_io.c\ - minix_file_io.c ext2_file_io.c kalloc.c strfcns.c exec.c \ - translate_root.c panic.c elf-load.c -OBJS = $(subst .c,.o,$(SRCS)) boot_script.o memory_objectServer.o \ - default_pagerServer.o excServer.o bootstrapServer.o \ - memory_object_defaultServer.o -LCLHDRS = assert.h disk_inode_ffs.h fs.h queue.h defs.h ext2_fs.h \ - minix_ffs_compat.h wiring.h dir.h ffs_compat.h minix_fs.h \ - disk_inode.h file_io.h minix_super.h translate_root.h mach-exec.h -target = serverboot -HURDLIBS = threads -installationdir := $(prefix)/boot - -vpath boot_script.c $(srcdir)/../boot - -MIGSFLAGS = -DSEQNOS - -LDFLAGS += -static - -include ../Makeconf - -# Don't even bother. -CFLAGS := $(filter-out -Wall,$(CFLAGS))
\ No newline at end of file diff --git a/serverboot/assert.h b/serverboot/assert.h deleted file mode 100644 index 9bcab69e..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 d238e8bb..00000000 --- a/serverboot/bootstrap.c +++ /dev/null @@ -1,420 +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 <file_io.h> - -#include <stdio.h> - -#include "../boot/boot_script.h" -#include "translate_root.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(); - -/* initialized in default_pager_initialize */ -extern mach_port_t default_pager_exception_port; -extern mach_port_t default_pager_bootstrap_port; - -/* - * 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; - c = index (fgets (str, maxlen, stdin), '\n'); - *c = '\0'; -} - -printf_init (device_t master) -{ - mach_port_t cons; - device_open (master, D_READ|D_WRITE, "console", &cons); - 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 doing_default_pager = 0; - int script_paging_file (const struct cmd *cmd, int *val) - { - if (add_paging_file (bootstrap_master_device_port, cmd->path)) - { - printf ("(bootstrap): %s: Cannot add paging file\n", cmd->path); - return BOOT_SCRIPT_MACH_ERROR; - } - return 0; - } - int script_default_pager (const struct cmd *cmd, int *val) - { - default_pager_initialize(bootstrap_master_host_port); - doing_default_pager = 1; - return 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; - - static char new_root[16]; - - /* - * 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 (root_name[0] == '\0') - root_name = DEFAULT_ROOT; - - /* - * If the '-a' (ask) switch was specified, ask for - * the root device. - */ - - if (index(flag_string, 'a')) { - printf("root device? [%s] ", root_name); - safe_gets(new_root, sizeof(new_root)); - } - - if (new_root[0] == '\0') - strcpy(new_root, root_name); - - root_name = translate_root(new_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_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 != 0) { - printf("Can't open server boot script %s: %d\n", - boot_script_name, - 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; - } - - /* - * Set up the default pager. - */ - partition_init(); - - { - /* Initialize boot script variables. */ - if (boot_script_set_variable ("host-port", VAL_PORT, - (int) bootstrap_master_host_port) - || boot_script_set_variable ("device-port", VAL_PORT, - (int) bootstrap_master_device_port) - || boot_script_set_variable ("root-device", VAL_STR, - (int) root_name) - || boot_script_set_variable ("boot-args", VAL_STR, - (int) flag_string) - || boot_script_define_function ("add-paging-file", VAL_NONE, - &script_paging_file) - || boot_script_define_function ("default-pager", VAL_NONE, - &script_default_pager) - ) - panic ("bootstrap: error setting boot script variables"); - - parse_script (&scriptf); - close_file (&scriptf); - } - - if (index (flag_string, 'd')) - { - char c; - printf ("Hit return to boot..."); - safe_gets (&c, 1); - } - - /* - * task_set_exception_port and task_set_bootstrap_port - * both require a send right. - */ - (void) mach_port_insert_right(my_task, default_pager_bootstrap_port, - default_pager_bootstrap_port, - MACH_MSG_TYPE_MAKE_SEND); - (void) mach_port_insert_right(my_task, default_pager_exception_port, - default_pager_exception_port, - MACH_MSG_TYPE_MAKE_SEND); - - /* - * Change our exception port. - */ - (void) task_set_exception_port(my_task, default_pager_exception_port); - - 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 - - if (! doing_default_pager) - task_terminate (mach_task_self ()); - - /* - * Become the default pager - */ - default_pager(); - /*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); - if (read_file (f, 0, buf, f->f_size, 0)) - panic ("bootstrap: error reading boot script file"); - - line = p = buf; - while (1) - { - while (p < buf + f->f_size && *p != '\n') - p++; - *p = '\0'; - err = boot_script_parse_line (line); - if (err) - boot_panic (err); - if (p == buf + f->f_size) - break; - line = ++p; - - } -} diff --git a/serverboot/def_pager_setup.c b/serverboot/def_pager_setup.c deleted file mode 100644 index fe6b33ab..00000000 --- a/serverboot/def_pager_setup.c +++ /dev/null @@ -1,136 +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 <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) - mach_port_t master_device_port; - char *file_name; -{ - 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\n", file_name); - - result = add_file_direct(fdp, &pfile); - if (result) - panic("Can't read disk addresses: %d\n", result); - - close_file(&pfile); - - /* - * Set up the default paging partition - */ - create_paging_partition(file_name, fdp, isa_file); - - 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; -} - -/* - * 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; -} diff --git a/serverboot/default_pager.c b/serverboot/default_pager.c deleted file mode 100644 index 302cf3f0..00000000 --- a/serverboot/default_pager.c +++ /dev/null @@ -1,3618 +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" - -#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(name) - 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) -{ - register partition_t part; - register vm_size_t size, bmsize; - - 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 = part_id(name); - part->bitmap = (bm_entry_t *)kalloc(bmsize); - part->going_away= FALSE; - part->file = fdp; - - bzero((char *)part->bitmap, bmsize); - - 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) -{ - register partition_t part; - - part = new_partition (name, fdp); - - 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 */ - 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; - -#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); - 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"); - 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; - - 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"); - - /* - * 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); -} - -/* - * 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); - return (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) - 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; -{ - 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) ) - 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 */ - - unsigned int readers; /* Reads in progress */ - unsigned int writers; /* Writes in progress */ - - 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; -/* We receive bootstrap requests on this port. */ -mach_port_t default_pager_bootstrap_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; - } else { - /* delay notification till send right is created */ - sync = 1; - pset = default_pager_external_set; - } - - 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; - } - - rc = default_read(&ds->dpager, dpt->dpt_buffer, - vm_page_size, offset, - &addr, protection_required & VM_PROT_WRITE); - - 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; -} - -kern_return_t -seqnos_memory_object_lock_completed(pager, seqno, pager_request, - offset, length) - memory_object_t pager; - mach_port_seqno_t seqno; - mach_port_t pager_request; - vm_offset_t offset; - vm_size_t length; -{ -#ifdef lint - pager++; seqno++; pager_request++; offset++; length++; -#endif lint - - panic("%slock_completed",my_name); - return(KERN_FAILURE); -} - -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)); -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 if (in->msgh_local_port == default_pager_bootstrap_port) { - /* - * We receive bootstrap requests - * from the startup task. - */ - - if (in->msgh_id == 999999) { - /* compatibility for old bootstrap interface */ - - bootstrap_compat(in, out); - return TRUE; - } - - return bootstrap_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) || (DMM != MACH_PORT_NULL)) - 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); - - /* - * Initialize the bootstrap port. - */ - kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE, - &default_pager_bootstrap_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); - - kr = mach_port_move_member(default_pager_self, - default_pager_bootstrap_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); - - cthread_fork (default_pager_default_thread, 0); - /* cthread_exit (cthread_self ()); */ - thread_suspend (mach_thread_self ()); -} - -/* - * Create an external object. - */ -kern_return_t default_pager_object_create(pager, mem_obj, size) - 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 default_pager_info(pager, infop) - 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 default_pager_objects(pager, objectsp, ocountp, portsp, pcountp) - 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 -default_pager_object_pages(pager, object, pagesp, countp) - 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; -} - -/* - * Add/remove extra paging space - */ - -extern mach_port_t bootstrap_master_device_port; -extern mach_port_t bootstrap_master_host_port; - -kern_return_t -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); - } 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; -} - -/* - * Handle bootstrap requests. - */ - -kern_return_t -do_bootstrap_privileged_ports(bootstrap, hostp, devicep) - mach_port_t bootstrap; - mach_port_t *hostp, *devicep; -{ - *hostp = bootstrap_master_host_port; - *devicep = bootstrap_master_device_port; - return KERN_SUCCESS; -} - -void -bootstrap_compat(in, out) - mach_msg_header_t *in, *out; -{ - mig_reply_header_t *reply = (mig_reply_header_t *) out; - mach_msg_return_t mr; - - struct imsg { - mach_msg_header_t hdr; - mach_msg_type_t port_desc_1; - mach_port_t port_1; - mach_msg_type_t port_desc_2; - mach_port_t port_2; - } imsg; - - /* - * Send back the host and device ports. - */ - - imsg.hdr.msgh_bits = MACH_MSGH_BITS_COMPLEX | - MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(in->msgh_bits), 0); - /* msgh_size doesn't need to be initialized */ - imsg.hdr.msgh_remote_port = in->msgh_remote_port; - imsg.hdr.msgh_local_port = MACH_PORT_NULL; - /* msgh_seqno doesn't need to be initialized */ - imsg.hdr.msgh_id = in->msgh_id + 100; /* this is a reply msg */ - - imsg.port_desc_1.msgt_name = MACH_MSG_TYPE_COPY_SEND; - imsg.port_desc_1.msgt_size = (sizeof(mach_port_t) * 8); - imsg.port_desc_1.msgt_number = 1; - imsg.port_desc_1.msgt_inline = TRUE; - imsg.port_desc_1.msgt_longform = FALSE; - imsg.port_desc_1.msgt_deallocate = FALSE; - imsg.port_desc_1.msgt_unused = 0; - - imsg.port_1 = bootstrap_master_host_port; - - imsg.port_desc_2 = imsg.port_desc_1; - - imsg.port_2 = bootstrap_master_device_port; - - /* - * Send the reply message. - * (mach_msg_server can not do this, because the reply - * is not in standard format.) - */ - - mr = mach_msg(&imsg.hdr, MACH_SEND_MSG, - sizeof imsg, 0, MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - if (mr != MACH_MSG_SUCCESS) - (void) mach_port_deallocate(default_pager_self, - imsg.hdr.msgh_remote_port); - - /* - * Tell mach_msg_server to do nothing. - */ - - reply->RetCode = MIG_NO_REPLY; -} - -#ifdef mips -/* - * set_ras_address for default pager - * Default pager does not have emulator support - * so it needs a local version of set_ras_address. - */ -int -set_ras_address(basepc, boundspc) - vm_offset_t basepc; - vm_offset_t boundspc; -{ - kern_return_t status; - - status = task_ras_control(mach_task_self(), basepc, boundspc, - TASK_RAS_CONTROL_INSTALL_ONE); - if (status != KERN_SUCCESS) - return -1; - return 0; -} -#endif 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 43690b2f..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 a30124a2..00000000 --- a/serverboot/elf-load.c +++ /dev/null @@ -1,92 +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; - Elf32_Ehdr x; - Elf32_Phdr *phdr, *ph; - vm_size_t phsize; - 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.e_ident[EI_MAG0] != ELFMAG0) || - (x.e_ident[EI_MAG1] != ELFMAG1) || - (x.e_ident[EI_MAG2] != ELFMAG2) || - (x.e_ident[EI_MAG3] != ELFMAG3)) - return EX_NOT_EXECUTABLE; - - /* Make sure the file is of the right architecture. */ -#ifdef i386 - if ((x.e_ident[EI_CLASS] != ELFCLASS32) || - (x.e_ident[EI_DATA] != ELFDATA2LSB) || - (x.e_machine != EM_386)) - return EX_WRONG_ARCH; -#else -#error Not ported to this architecture! -#endif - - /* XXX others */ - out_info->entry = (vm_offset_t) x.e_entry; - - phsize = x.e_phnum * x.e_phentsize; - phdr = (Elf32_Phdr *)alloca(phsize); - - result = (*read)(handle, x.e_phoff, phdr, phsize, &actual); - if (result) - return result; - if (actual < phsize) - return EX_CORRUPT; - - for (i = 0; i < x.e_phnum; i++) - { - ph = (Elf32_Phdr *)((vm_offset_t)phdr + i * x.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 a0773f4c..00000000 --- a/serverboot/exec.c +++ /dev/null @@ -1,88 +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/machine/eflags.h> -#include "mach-exec.h" - -#include <file_io.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)®s, - ®_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)®s, - reg_size); - - return (char *)regs.uesp; -} - diff --git a/serverboot/ext2_file_io.c b/serverboot/ext2_file_io.c deleted file mode 100644 index 9d743368..00000000 --- a/serverboot/ext2_file_io.c +++ /dev/null @@ -1,1099 +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; - register struct ext2_dir_entry *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 *)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); - - ovbcopy(cp, &namebuf[link_len], 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 */ -} - -/* - * 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 -ext2_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) - size = 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 -ext2_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) - size = 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/ext2_fs.h b/serverboot/ext2_fs.h deleted file mode 100644 index 4068c002..00000000 --- a/serverboot/ext2_fs.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - * linux/include/linux/ext2_fs.h - * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#ifndef _LINUX_EXT2_FS_H -#define _LINUX_EXT2_FS_H - -/* - * The second extended filesystem constants/structures - */ - -/* - * Define EXT2FS_DEBUG to produce debug messages - */ -#undef EXT2FS_DEBUG - -/* - * Define EXT2FS_DEBUG_CACHE to produce cache debug messages - */ -#undef EXT2FS_DEBUG_CACHE - -/* - * Define EXT2FS_CHECK_CACHE to add some checks to the name cache code - */ -#undef EXT2FS_CHECK_CACHE - -/* - * Define EXT2FS_PRE_02B_COMPAT to convert ext 2 fs prior to 0.2b - */ -#undef EXT2FS_PRE_02B_COMPAT - -/* - * Define DONT_USE_DCACHE to inhibit the directory cache - */ -#define DONT_USE_DCACHE - -/* - * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files - */ -#define EXT2_PREALLOCATE - -/* - * The second extended file system version - */ -#define EXT2FS_DATE "94/03/10" -#define EXT2FS_VERSION "0.5" - -/* - * Debug code - */ -#ifdef EXT2FS_DEBUG -# define ext2_debug(f, a...) { \ - printk ("EXT2-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ - printk (f, ## a); \ - } -#else -# define ext2_debug(f, a...) /**/ -#endif - -/* - * Special inodes numbers - */ -#define EXT2_BAD_INO 1 /* Bad blocks inode */ -#define EXT2_ROOT_INO 2 /* Root inode */ -#define EXT2_ACL_IDX_INO 3 /* ACL inode */ -#define EXT2_ACL_DATA_INO 4 /* ACL inode */ -#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ -#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ -#define EXT2_FIRST_INO 11 /* First non reserved inode */ - -/* - * The second extended file system magic number - */ -#define EXT2_PRE_02B_MAGIC 0xEF51 -#define EXT2_SUPER_MAGIC 0xEF53 - -/* - * Maximal count of links to a file - */ -#define EXT2_LINK_MAX 32000 - -/* - * Macro-instructions used to manage several block sizes - */ -#define EXT2_MIN_BLOCK_SIZE 1024 -#define EXT2_MAX_BLOCK_SIZE 4096 -#define EXT2_MIN_BLOCK_LOG_SIZE 10 -#ifdef __KERNEL__ -# define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) -#else -# define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) -#endif -#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) -#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (unsigned long)) -#ifdef __KERNEL__ -# define EXT2_BLOCK_SIZE_BITS(s) ((s)->u.ext2_sb.s_es->s_log_block_size + 10) -#else -# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) -#endif -#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_inode)) - -/* - * Macro-instructions used to manage fragments - */ -#define EXT2_MIN_FRAG_SIZE 1024 -#define EXT2_MAX_FRAG_SIZE 4096 -#define EXT2_MIN_FRAG_LOG_SIZE 10 -#ifdef __KERNEL__ -# define EXT2_FRAG_SIZE(s) ((s)->u.ext2_sb.s_frag_size) -# define EXT2_FRAGS_PER_BLOCK(s) ((s)->u.ext2_sb.s_frags_per_block) -#else -# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) -# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) -#endif - -/* - * ACL structures - */ -struct ext2_acl_header /* Header of Access Control Lists */ -{ - unsigned long aclh_size; - unsigned long aclh_file_count; - unsigned long aclh_acle_count; - unsigned long aclh_first_acle; -}; - -struct ext2_acl_entry /* Access Control List Entry */ -{ - unsigned long acle_size; - unsigned short acle_perms; /* Access permissions */ - unsigned short acle_type; /* Type of entry */ - unsigned short acle_tag; /* User or group identity */ - unsigned short acle_pad1; - unsigned long acle_next; /* Pointer on next entry for the */ - /* same inode or on next free entry */ -}; - -/* - * Structure of a blocks group descriptor - */ -struct ext2_old_group_desc -{ - unsigned long bg_block_bitmap; /* Blocks bitmap block */ - unsigned long bg_inode_bitmap; /* Inodes bitmap block */ - unsigned long bg_inode_table; /* Inodes table block */ - unsigned short bg_free_blocks_count; /* Free blocks count */ - unsigned short bg_free_inodes_count; /* Free inodes count */ -}; - -struct ext2_group_desc -{ - unsigned long bg_block_bitmap; /* Blocks bitmap block */ - unsigned long bg_inode_bitmap; /* Inodes bitmap block */ - unsigned long bg_inode_table; /* Inodes table block */ - unsigned short bg_free_blocks_count; /* Free blocks count */ - unsigned short bg_free_inodes_count; /* Free inodes count */ - unsigned short bg_used_dirs_count; /* Directories count */ - unsigned short bg_pad; - unsigned long bg_reserved[3]; -}; - -/* - * Macro-instructions used to manage group descriptors - */ -#ifdef __KERNEL__ -# define EXT2_BLOCKS_PER_GROUP(s) ((s)->u.ext2_sb.s_blocks_per_group) -# define EXT2_DESC_PER_BLOCK(s) ((s)->u.ext2_sb.s_desc_per_block) -# define EXT2_INODES_PER_GROUP(s) ((s)->u.ext2_sb.s_inodes_per_group) -#else -# define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) -# define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) -# define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) -#endif - -/* - * Constants relative to the data blocks - */ -#define EXT2_NDIR_BLOCKS 12 -#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS -#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) -#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) -#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) - -/* - * Inode flags - */ -#define EXT2_SECRM_FL 0x0001 /* Secure deletion */ -#define EXT2_UNRM_FL 0x0002 /* Undelete */ -#define EXT2_COMPR_FL 0x0004 /* Compress file */ -#define EXT2_SYNC_FL 0x0008 /* Synchronous updates */ - -/* - * ioctl commands - */ -#define EXT2_IOC_GETFLAGS _IOR('f', 1, long) -#define EXT2_IOC_SETFLAGS _IOW('f', 2, long) -#define EXT2_IOC_GETVERSION _IOR('v', 1, long) -#define EXT2_IOC_SETVERSION _IOW('v', 2, long) - -/* - * Structure of an inode on the disk - */ -struct ext2_inode { - unsigned short i_mode; /* File mode */ - unsigned short i_uid; /* Owner Uid */ - unsigned long i_size; /* Size in bytes */ - unsigned long i_atime; /* Access time */ - unsigned long i_ctime; /* Creation time */ - unsigned long i_mtime; /* Modification time */ - unsigned long i_dtime; /* Deletion Time */ - unsigned short i_gid; /* Group Id */ - unsigned short i_links_count; /* Links count */ - unsigned long i_blocks; /* Blocks count */ - unsigned long i_flags; /* File flags */ - unsigned long i_reserved1; - unsigned long i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ - unsigned long i_version; /* File version (for NFS) */ - unsigned long i_file_acl; /* File ACL */ - unsigned long i_dir_acl; /* Directory ACL */ - unsigned long i_faddr; /* Fragment address */ - unsigned char i_frag; /* Fragment number */ - unsigned char i_fsize; /* Fragment size */ - unsigned short i_pad1; - unsigned long i_reserved2[2]; -}; - -/* - * File system states - */ -#define EXT2_VALID_FS 0x0001 /* Unmounted cleany */ -#define EXT2_ERROR_FS 0x0002 /* Errors detected */ - -/* - * Mount flags - */ -#define EXT2_MOUNT_CHECK_NORMAL 0x0001 /* Do some more checks */ -#define EXT2_MOUNT_CHECK_STRICT 0x0002 /* Do again more checks */ -#define EXT2_MOUNT_CHECK (EXT2_MOUNT_CHECK_NORMAL | \ - EXT2_MOUNT_CHECK_STRICT) -#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */ -#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */ -#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */ -#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ -#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ - -#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt -#define set_opt(o, opt) o |= EXT2_MOUNT_##opt -#define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \ - EXT2_MOUNT_##opt) -/* - * Maximal mount counts between two filesystem checks - */ -#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ -#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ - -/* - * Behaviour when detecting errors - */ -#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ -#define EXT2_ERRORS_RO 2 /* Remount fs read-only */ -#define EXT2_ERRORS_PANIC 3 /* Panic */ -#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE - -/* - * Structure of the super block - */ -struct ext2_super_block { - unsigned long s_inodes_count; /* Inodes count */ - unsigned long s_blocks_count; /* Blocks count */ - unsigned long s_r_blocks_count;/* Reserved blocks count */ - unsigned long s_free_blocks_count;/* Free blocks count */ - unsigned long s_free_inodes_count;/* Free inodes count */ - unsigned long s_first_data_block;/* First Data Block */ - unsigned long s_log_block_size;/* Block size */ - long s_log_frag_size; /* Fragment size */ - unsigned long s_blocks_per_group;/* # Blocks per group */ - unsigned long s_frags_per_group;/* # Fragments per group */ - unsigned long s_inodes_per_group;/* # Inodes per group */ - unsigned long s_mtime; /* Mount time */ - unsigned long s_wtime; /* Write time */ - unsigned short s_mnt_count; /* Mount count */ - short s_max_mnt_count; /* Maximal mount count */ - unsigned short s_magic; /* Magic signature */ - unsigned short s_state; /* File system state */ - unsigned short s_errors; /* Behaviour when detecting errors */ - unsigned short s_pad; - unsigned long s_lastcheck; /* time of last check */ - unsigned long s_checkinterval; /* max. time between checks */ - unsigned long s_reserved[238]; /* Padding to the end of the block */ -}; - -/* - * Structure of a directory entry - */ -#define EXT2_NAME_LEN 255 - -struct ext2_dir_entry { - unsigned long inode; /* Inode number */ - unsigned short rec_len; /* Directory entry length */ - unsigned short name_len; /* Name length */ - char name[EXT2_NAME_LEN]; /* File name */ -}; - -/* - * EXT2_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 4 - */ -#define EXT2_DIR_PAD 4 -#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) -#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ - ~EXT2_DIR_ROUND) - -#ifdef __KERNEL__ -/* - * Function prototypes - */ - -/* - * Ok, these declarations are also in <linux/kernel.h> but none of the - * ext2 source programs needs to include it so they are duplicated here. - */ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define NORET_TYPE __volatile__ -# define ATTRIB_NORET /**/ -# define NORET_AND /**/ -#else -# define NORET_TYPE /**/ -# define ATTRIB_NORET __attribute__((noreturn)) -# define NORET_AND noreturn, -#endif - -/* acl.c */ -extern int ext2_permission (struct inode *, int); - -/* balloc.c */ -extern int ext2_new_block (struct super_block *, unsigned long, - unsigned long *, unsigned long *); -extern void ext2_free_blocks (struct super_block *, unsigned long, - unsigned long); -extern unsigned long ext2_count_free_blocks (struct super_block *); -extern void ext2_check_blocks_bitmap (struct super_block *); - -/* bitmap.c */ -extern unsigned long ext2_count_free (struct buffer_head *, unsigned); - -#ifndef DONT_USE_DCACHE -/* dcache.c */ -extern void ext2_dcache_invalidate (unsigned short); -extern unsigned long ext2_dcache_lookup (unsigned short, unsigned long, - const char *, int); -extern void ext2_dcache_add (unsigned short, unsigned long, const char *, - int, unsigned long); -extern void ext2_dcache_remove (unsigned short, unsigned long, const char *, - int); -#endif - -/* dir.c */ -extern int ext2_check_dir_entry (char *, struct inode *, - struct ext2_dir_entry *, struct buffer_head *, - unsigned long); - -/* file.c */ -extern int ext2_read (struct inode *, struct file *, char *, int); -extern int ext2_write (struct inode *, struct file *, char *, int); - -/* fsync.c */ -extern int ext2_sync_file (struct inode *, struct file *); - -/* ialloc.c */ -extern struct inode * ext2_new_inode (const struct inode *, int); -extern void ext2_free_inode (struct inode *); -extern unsigned long ext2_count_free_inodes (struct super_block *); -extern void ext2_check_inodes_bitmap (struct super_block *); - -/* inode.c */ -extern int ext2_bmap (struct inode *, int); - -extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *); -extern struct buffer_head * ext2_bread (struct inode *, int, int, int *); - -extern int ext2_getcluster (struct inode * inode, long block); -extern void ext2_read_inode (struct inode *); -extern void ext2_write_inode (struct inode *); -extern void ext2_put_inode (struct inode *); -extern int ext2_sync_inode (struct inode *); -extern void ext2_discard_prealloc (struct inode *); - -/* ioctl.c */ -extern int ext2_ioctl (struct inode *, struct file *, unsigned int, - unsigned long); - -/* namei.c */ -extern int ext2_open (struct inode *, struct file *); -extern void ext2_release (struct inode *, struct file *); -extern int ext2_lookup (struct inode *,const char *, int, struct inode **); -extern int ext2_create (struct inode *,const char *, int, int, - struct inode **); -extern int ext2_mkdir (struct inode *, const char *, int, int); -extern int ext2_rmdir (struct inode *, const char *, int); -extern int ext2_unlink (struct inode *, const char *, int); -extern int ext2_symlink (struct inode *, const char *, int, const char *); -extern int ext2_link (struct inode *, struct inode *, const char *, int); -extern int ext2_mknod (struct inode *, const char *, int, int, int); -extern int ext2_rename (struct inode *, const char *, int, - struct inode *, const char *, int); - -/* super.c */ -extern void ext2_error (struct super_block *, const char *, const char *, ...) - __attribute__ ((format (printf, 3, 4))); -extern NORET_TYPE void ext2_panic (struct super_block *, const char *, - const char *, ...) - __attribute__ ((NORET_AND format (printf, 3, 4))); -extern void ext2_warning (struct super_block *, const char *, const char *, ...) - __attribute__ ((format (printf, 3, 4))); -extern void ext2_put_super (struct super_block *); -extern void ext2_write_super (struct super_block *); -extern int ext2_remount (struct super_block *, int *, char *); -extern struct super_block * ext2_read_super (struct super_block *,void *,int); -extern void ext2_statfs (struct super_block *, struct statfs *); - -/* truncate.c */ -extern void ext2_truncate (struct inode *); - -/* - * Inodes and files operations - */ - -/* dir.c */ -extern struct inode_operations ext2_dir_inode_operations; - -/* file.c */ -extern struct inode_operations ext2_file_inode_operations; - -/* symlink.c */ -extern struct inode_operations ext2_symlink_inode_operations; - -#endif /* __KERNEL__ */ - -#endif /* _LINUX_EXT2_FS_H */ diff --git a/serverboot/ffs_compat.c b/serverboot/ffs_compat.c deleted file mode 100644 index 46644a9b..00000000 --- a/serverboot/ffs_compat.c +++ /dev/null @@ -1,63 +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> - -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 889ca4e5..00000000 --- a/serverboot/ffs_file_io.c +++ /dev/null @@ -1,1085 +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); - - ovbcopy(cp, &namebuf[link_len], 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 */ -} - -/* - * 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 -ffs_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) - size = 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 -ffs_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) - size = 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.c b/serverboot/file_io.c deleted file mode 100644 index 141fdcfe..00000000 --- a/serverboot/file_io.c +++ /dev/null @@ -1,225 +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 -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 */ -{ - switch (fdp->f_fstype) { - case EXT2_FS: - return ext2_page_read_file_direct(fdp, offset, size, addr, size_read); - case MINIX_FS: - return minix_page_read_file_direct(fdp, offset, size, addr, size_read); - default: - return ffs_page_read_file_direct(fdp, offset, size, addr, size_read); - } -} - -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 */ -{ - switch (fdp->f_fstype) { - case EXT2_FS: - return ext2_page_write_file_direct(fdp, offset, addr, size, size_written); - case MINIX_FS: - return minix_page_write_file_direct(fdp, offset, addr, size, size_written); - default: - return ffs_page_write_file_direct(fdp, offset, addr, size, size_written); - } -} - -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; - } -} diff --git a/serverboot/file_io.h b/serverboot/file_io.h deleted file mode 100644 index 5706ce5b..00000000 --- a/serverboot/file_io.h +++ /dev/null @@ -1,174 +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 <device/device_types.h> - -#include <defs.h> -#include "minix_fs.h" -#include "ext2_fs.h" -#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. - */ - -#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 - a routine */ - -#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/kalloc.c b/serverboot/kalloc.c deleted file mode 100644 index 80438738..00000000 --- a/serverboot/kalloc.c +++ /dev/null @@ -1,274 +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 */ - -#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); - } -} - -void *malloc(vm_size_t size) -{ - return (void *)kalloc(size); -} - -void free(void *addr) -{ - /* 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 36e8307b..00000000 --- a/serverboot/load.c +++ /dev/null @@ -1,406 +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 <assert.h> -#include <mach/mach_interface.h> -#include <varargs.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; - - 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; -} - -mach_port_t boot_script_read_file (const char *file) -{ return MACH_PORT_NULL; } /* XXX */ - -int -boot_script_exec_cmd (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; - 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("openi %d", result); - } - - /* - * Add space for: - * arg_count - * pointers to arguments - * trailing 0 pointer - * dummy 0 pointer to environment variables - * and align to integer boundary - */ - arg_len += sizeof(integer_t) + (2 + arg_count) * sizeof(char *); - 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); - if (result) - panic("(bootstrap) exec_load %s: error %d", namebuf, result); -#if 0 - printf("(bootstrap): 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: %x", namebuf, result); - arg_pos = set_regs(user_task, user_thread, &info, arg_len); - - /* - * Read symbols from the executable file. - */ -#if 0 - printf("(bootstrap): 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 *) - + 2 * sizeof(char *) - + sizeof(integer_t); - k_cp = (char *)k_arg_start + arg_count * sizeof(char *) - + 2 * sizeof(char *) - + sizeof(integer_t); - - /* - * first the argument count - */ - *k_ap++ = (char *)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; - bcopy (argstrings, k_cp, argslen); - - /* - * last, the trailing 0 argument and a null environment pointer. - */ - *k_ap++ = (char *)0; - *k_ap = (char *)0; - - /* - * 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 0a18092b..00000000 --- a/serverboot/minix_file_io.c +++ /dev/null @@ -1,966 +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 */ -} - -/* - * Special read and write routines for default pager. - * Assume that all offsets and sizes are multiples - * of DEV_BSIZE. - */ - -#define minix_fdir_blkoff(fdp, offset) /* offset % fd_bsize */ \ - ((offset) & ((fdp)->fd_bsize - 1)) -#define minix_fdir_lblkno(fdp, offset) /* offset / fd_bsize */ \ - ((offset) >> (fdp)->fd_bshift) - -#define minix_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 -minix_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 minix_daddr_t file_block; - minix_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 = minix_fdir_blkoff(fdp, offset); - file_block = minix_fdir_lblkno(fdp, offset); - - if (file_is_device(fdp)) { - disk_block = file_block; - } else { - disk_block = ((minix_daddr_t *)fdp->fd_blocks)[file_block]; - if (disk_block == 0) - return (FS_NOT_IN_FILE); - } - - if (size > fdp->fd_bsize) - size = fdp->fd_bsize; - - return (device_read(fdp->fd_dev, - 0, - (recnum_t) (minix_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 -minix_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 minix_daddr_t file_block; - minix_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 = minix_fdir_blkoff(fdp, offset); - file_block = minix_fdir_lblkno(fdp, offset); - - if (file_is_device(fdp)) { - disk_block = file_block; - } else { - disk_block = ((minix_daddr_t *)fdp->fd_blocks)[file_block]; - if (disk_block == 0) - return (FS_NOT_IN_FILE); - } - - if (size > fdp->fd_bsize) - size = 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) (minix_fdir_fsbtodb(fdp, disk_block) + btodb(off)), - (char *) addr, - size, - &num_written); - *size_written = num_written; - return rc; -} 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 80197500..00000000 --- a/serverboot/panic.c +++ /dev/null @@ -1,59 +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 <varargs.h> -#include <stdio.h> - -static mach_port_t master_host_port; - -panic_init(port) - mach_port_t port; -{ - master_host_port = port; -} - -/*VARARGS1*/ -panic(s, va_alist) - char *s; - va_dcl -{ - va_list listp; - - clearerr (stdout); - printf("bootstrap/default-pager panic: "); - va_start(listp); - 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 3e93476f..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 53c097ba..00000000 --- a/serverboot/strfcns.c +++ /dev/null @@ -1,117 +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 <varargs.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(dest, va_alist) - register char * dest; - va_dcl -{ - va_list argptr; - register char * src; - register int c; - - va_start(argptr); - while ((src = va_arg(argptr, char *)) != (char *)0) { - - while ((c = *src++) != '\0') - *dest++ = c; - } - *dest = '\0'; - 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); -} - -/* - * ovbcopy - like bcopy, but recognizes overlapping ranges and handles - * them correctly. - */ -ovbcopy(from, to, bytes) - char *from, *to; - int bytes; /* num bytes to copy */ -{ - /* Assume that bcopy copies left-to-right (low addr first). */ - if (from + bytes <= to || to + bytes <= from || to == from) - bcopy(from, to, bytes); /* non-overlapping or no-op*/ - else if (from > to) - bcopy(from, to, bytes); /* overlapping but OK */ - else { - /* to > from: overlapping, and must copy right-to-left. */ - from += bytes - 1; - to += bytes - 1; - while (bytes-- > 0) - *to-- = *from--; - } -} - -/* - * Return a pointer to the first occurence of 'c' in - * string s, or 0 if none. - */ -char * -index(s, c) - char *s; - char c; -{ - char cc; - - while ((cc = *s) != c) { - if (cc == 0) - return 0; - s++; - } - return s; -} - diff --git a/serverboot/translate_root.c b/serverboot/translate_root.c deleted file mode 100644 index b544d5c8..00000000 --- a/serverboot/translate_root.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 1995 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: Stephen Clawson, University of Utah CSL - */ - - -#include "translate_root.h" - -unsigned int atoh(ap) - char *ap; -{ - register char *p; - register unsigned int n; - register int digit,lcase; - - p = ap; - n = 0; - while(*p == ' ') - p++; - while ((digit = (*p >= '0' && *p <= '9')) || - (lcase = (*p >= 'a' && *p <= 'f')) || - (*p >= 'A' && *p <= 'F')) { - n *= 16; - if (digit) n += *p++ - '0'; - else if (lcase) n += 10 + (*p++ - 'a'); - else n += 10 + (*p++ - 'A'); - } - return(n); -} - -/* - * Translate the root device from whatever strange encoding we might - * be given. Currently that includes BSD's slightly different name - * for IDE devices, and Linux's device number encoding (since that's - * what LILO passes us, for whatever reason). - */ -char * -translate_root(root_string) - char *root_string; -{ - int linuxdev = atoh(root_string); - - /* LILO passes us a string representing the linux device number of - * our root device. Since this is _not_ what we want, we'll make - * a stab at converting it. - * - * Linux major numbers we care about: - * - * 2 = fd - * 3 = hd[ab] (IDE channel 1) - * 8 = sd - * 22 = hd[cd] (IDE channel 2) - * - */ - if (linuxdev) { - if (LINUX_MAJOR(linuxdev) == 2) { - root_string[0] = 'f'; - root_string[1] = 'd'; - root_string[2] = LINUX_FD_DEVICE_NR(linuxdev) + '0'; - root_string[3] = '\0'; - } else { - int shift; - - switch (LINUX_MAJOR(linuxdev)) { - case 3: - case 22: - shift = 6; - root_string[0] = 'h'; - break; - case 8: - shift = 4; - root_string[0] = 's'; - break; - default: - printf("Unknown linux device" - "(major = %d, minor = %d) passed as " - "root argument!\n" - "using hd0a as default.\n", - LINUX_MAJOR(linuxdev), - LINUX_MINOR(linuxdev)); - shift = 1; - root_string[0] = 'h'; - linuxdev = 1; - } - - root_string[1] = 'd'; - root_string[2] = LINUX_DEVICE_NR(linuxdev, shift)+'0'; - root_string[3] = LINUX_PARTN(linuxdev, shift)+'a' - 1; - root_string[4] = '\0'; - } - } else - /* This could be handled much simpler in the BSD boot - * adapter code, but baford insists that the boot - * adapter code shouldn't be tainted by Mach's notion - * of the `correct' device naming. Thus, we get wdxx - * instead of hdxx if booted from the BSD bootblocks, - * and this is the lame hack that tries to convert it. - */ - if (root_string[0] == 'w' && root_string[1] == 'd') - root_string[0] = 'h'; - - return root_string; -} - - - diff --git a/serverboot/translate_root.h b/serverboot/translate_root.h deleted file mode 100644 index e5bab70a..00000000 --- a/serverboot/translate_root.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 1995 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: Stephen Clawson, University of Utah CSL - */ - -#ifndef _TRANSLATE_ROOT_H_ -#define _TRANSLATE_ROOT_H_ - -#define DEFAULT_ROOT "hd0a" - -extern char *translate_root(char *); - -#define LINUX_MAJOR(a) (int)((unsigned short)(a) >> 8) -#define LINUX_MINOR(a) (int)((unsigned short)(a) & 0xFF) - -#define LINUX_PARTN(device, shift) \ - (LINUX_MINOR(device) & ((1 << (shift)) - 1)) -#define LINUX_DEVICE_NR(device, shift) \ - (LINUX_MINOR(device) >> (shift)) -#define LINUX_FD_DEVICE_NR(device) \ - ( ((device) & 3) | (((device) & 0x80 ) >> 5 )) - -#endif /* _TRANSLATE_ROOT_H_ */ diff --git a/serverboot/wiring.c b/serverboot/wiring.c deleted file mode 100644 index ddcbd373..00000000 --- a/serverboot/wiring.c +++ /dev/null @@ -1,152 +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) - wire_memory(address, size, 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/sh-version.sed b/sh-version.sed deleted file mode 100644 index d13c94d0..00000000 --- a/sh-version.sed +++ /dev/null @@ -1 +0,0 @@ -s/STANDARD_HURD_VERSION_\(.[^_]*\)_/\1 (GNU Hurd) 0.2/ diff --git a/ufs-fsck/ChangeLog b/ufs-fsck/ChangeLog deleted file mode 100644 index 7df8d5c0..00000000 --- a/ufs-fsck/ChangeLog +++ /dev/null @@ -1,289 +0,0 @@ -Wed Feb 19 23:10:39 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (argp_program_version): Make const. - -Thu Sep 12 16:40:10 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * Makefile (HURDLIBS): New variable. - ($(target)): Delete special depedency. - - * Makefile (vpath tables.c): Put after Makeconf inclusion to catch - setting of $(top_srcdir). - -Fri Sep 6 16:44:07 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * main.c (argp_program_version): Fix typo. - -Thu Sep 5 11:42:21 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * main.c: Include <version.h>. - (argp_program_version): Define with STANDARD_HURD_VERSION. - -Fri Aug 16 10:25:37 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dir.c (record_directory): Maximum number of block pointers to - record is NDADDR + NIADDR, not NDADDR * NIADDR. - * pass2.c: Include <assert.h>. - (pass2): Before copying block addresses to DINO in basic - integrity check, assert that DNP->i_numblks isn't too big. - -Mon Aug 12 11:39:12 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * Makefile (dir): Now ufs-fsck. - -Tue Jul 23 19:32:09 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (allocino): `struct timespec' now uses a field prefix - of `tv_'. - * utilities.c (pinode): Likewise. - -Thu Jul 18 14:55:14 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass2.c (pass2): If an entire directory block is null, allow - preen to patch it into a normal empty directory entry. - -Sat Jul 6 19:59:27 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (argp_program_version): New variable. - <hurd.h>: New include. - -Mon Jul 1 12:55:48 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass2.c (pass2): Don't skip empty directories in `.' and `..' - correctness check; we don't clear them the way BSD does, so we - want `.' and `..' to get created for us. Also handle `.' before - `..' so that they get created in the usual order for empty - directories. - - * dir.c (makeentry): After successful directory expansion, write - out modified directory inode. - - * pass4.c (pass4): If a reconnect fails while we are preening, - give up. - -Mon Jun 24 10:19:39 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * utilities.c (errexit, punt): Exit with status 8 for catastrophic - failures. - -Thu May 23 14:12:21 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass2.c (pass2): Don't clear all node types in directories, just - clear those that are wrong. - -Tue May 14 16:49:46 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * pass2.c (pass2): Fix up test in preen case. - -Tue May 14 15:29:36 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass2.c (pass2): Handle directory entry type fields better for - Hurd. - -Sat May 11 01:07:49 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (parse_opt): Use ARGP_ERR_UNKNOWN instead of EINVAL. - -Thu May 9 20:12:51 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass1b.c (pass1b): Bother to initialize NUMBER. - -Fri May 3 00:48:39 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (nice_size, show_stats): New functions. - (main): Use show_stats. - -Wed May 1 13:59:06 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Shorten summary message so that it fits on one line. - * utilities.c (no_preen): New function. - (problem, warning, pinode): Use it. - (warning): Don't flush all pending problems, just our own. - * dir.c (linkup): Consistently put quotes around filenames. - - * main.c (preen, num_files): New variables. - (main): Implement clean-bit checking in preen mode, and print - summary statistics. - (main, options): Add --force & --silent options. - * pass1.c (pass1): Increment NUM_FILES. - When clearing inode due to bad blocks, continue. - * inode.c (allocino, freeino): Frob NUM_FILES. - * fsck.h (force): New declaration. - * pass5.c (pass5): Vary clean msg depending on whether FSMODIFIED. - * setup.c (setup): Use error to print error msgs. - <error.h>, <errno.h>: New includes. - - * utilities.c (problem, warning, pextend, pfail): New functions. - (pinode, pfix, reply): Use new problem recording stuff. - (push_problem, resolve_problem, flush_problems): New functions. - (struct problem): New type. - (problems, free_problems): New variables. - (retch, punt): New functions. - * fsck.h (problem, warning, pextend, pfail): New declarations. - (pinode): Update declaration. - * dir.c (validdir, makeentry, linkup): Use new printing functions. - * pass1.c (pass1): Likewise. - * pass1b.c (pass1b): Likewise. - * pass2.c (pass2): Likewise. - * pass3.c (pass3): Likewise. - * pass4.c (pass4): Likewise. - * pass5.c (pass5): Likewise. - * setup.c (setup): Likewise. - -Tue Apr 30 19:06:42 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * pass5.c (pass5): Be sure to call pwarn before pfix. - * main.c (main): Don't print large obnoxious banner if PREEN. - -Fri Apr 26 16:20:37 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (allocino): Parenthesize test correctly. - - * fsck.h (swab_disk): Define as constant zero. - - * pass5.c (pass5): If not marked clean, but now it is, then offer - to mark it clean. - * utilities.c (reply): Set fix_denied anytime we return 0. - * fsck.h (fix_denied): New variable. - -Wed Apr 24 13:32:39 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass1.c (pass1): Don't print block numbers as we go anymore. - -Tue Apr 23 10:11:49 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass5.c (pass5): Correctly track contig summaries even though - they aren't used by the filesystem; we still need to preserve the - format. - -Mon Apr 15 12:51:41 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (vpath tables.c): Find ufs directory in $(top_srcdir). - -Tue Apr 2 09:00:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pass1.c (pass1): Print mode correctly in unknown file type case. - Recognize inode type IFSOCK too. - -Mon Mar 18 19:48:39 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Pass new arg to argp_parse. Use argp_usage correctly. - -Thu Oct 19 17:45:12 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Exit with a non-zero status if we fixed anything. - Use argp to parse options. - (options): Converted to argp format. - (args_doc): New variable. - (USAGE, usage, SHORT_OPTIONS): Removed. - Include <argp.h> instead of <getopt.h>. - * Makefile ($(target)): Depend on libshouldbeinlibc.a. - -Fri Sep 22 16:55:03 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * utilities.c (pfix): New function. - (pfatal, pwarn, errexit): Print DEVICE_NAME too if in preen mode. - * fsck.h: Declare DEVICE_NAME. - * setup.c (setup): Set DEVICE_NAME. - * pass1.c, pass2.c, pass3.c, pass4.c, pass5.c (pass1, pass2, - pass3, pass4, pass5): Call pfix instead of printf. - * pass1.c (pass1): Only print progress report if not in preen mode. - * main.c (main): Only print section headers if not in preen mode. - -Wed Sep 20 09:11:59 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * utilities.c (pinode): Take a message & args to print as well. - * fsck.h: Change declaration of pinode. - * pass2.c (pass2): Use changed pinode. - * pass3.c (pass3): Use changed pinode. - * pass4.c (pass4): Use changed pinode. - -Tue Sep 19 15:37:02 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * pass1.c (pass1): Change the extent of DBWARN & IBWARN so that - they actually work. - * pass2.c (pass2): Adjust our record of link counts when we - add/change dir entries; also print error messages when we can't. - * pass4.c (pass4): If an unlinked file can't be reconnected, offer - to clear it. Once a reconnect attempt fails, don't try again. - * dir.c (linkup): Print the value of LFNAME rather than `lost+found'. - (searchdir, changeino): Fix backward compare. - (linkup): Don't fail when makeentry succeeds. - (searchdir): Make searchdir return zero if there's an error - during the search. - (linkup): Print appropiate error messages if searchdir fails. - (validdir): Get rid of extra newlines in error messages -- - everyone who calls this routine prints extra information if it - fails, which should immediately follow. - * main.c (main): Use getopt to parse command line options. - (usage): New function. - (options): New variable. - (lfname, lfmode): Variables moved here from setup.c. - (lfname): Made into a char* so that we can change it. - (lfmode): Get rid of IFDIR; it's added when necessary. - * fsck.h: Change LFNAME to char*. - * setup.c (lfname, lfmode): Variables moved to main.c. - -Sat Sep 9 12:12:59 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (target): Changed to `fsck.ufs'. - (installationdir): New variable, install into $(sbindir). - -Thu Jul 6 15:33:46 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * fsck.h (lookup_directory): New decl. - - * pass1.c (pass1): Remove assignment from if test. - * utilities.c (pinode): Likewise. - - * Makefile (tables.o): Delete rule. - (vpath tables.c): Tell where to find tables.c. - - * Makefile: Removed dependencies that are now automatically - generated. - -Thu Nov 3 17:19:03 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (dir): Changed to fsck. - (target): Changed to fsck. - -Wed Nov 2 14:39:13 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * pass2.c (pass2): Use DIRECT_NAMLEN instead of d_namlen - throughout. - * dir.c (searchdir): Likewise. - (changeino): Likewise. - (makeentry): Likewise. - -Mon Oct 17 16:07:56 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (inode_iterate): FN takes new third arg. - Keep track of new var `offset' and pass it to FN. - * pass2.c (pass2/checkdirblock): New third arg. - Only scan DIRBLKSIZ chunks to the total size of the file. - * dir.c (searchdir/checkdirblock): Likewise. - (changeino/checkdirblock): Likewise. - (makeentry/checkdirblock): Likewise. - * pass1.c (pass1/checkblock): New third arg (ignored). - * pass1b.c (pass1b/checkblock): Likewise. - - * inode.c (inode_iterate): Compute MAXB correctly. - - * utilities.c (getinode): Multiple ino_to_fsbo by - sizeof (struct dinode). - (write_inode): Likewise. - (getinode): Inode buffer needs to be a full block, not a - fragment. - -Fri Oct 14 21:07:09 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * utilities.c (lastifrag): New variable. - (getinode): Use lastifrag instead of buf; Only I/O new block - if lastifrag isn't what we want. - (write_inode): Likewise. - -Fri Oct 14 17:44:59 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * setup.c (setup): Test ISCHR, not ISDIR. - Fix NCYL against NCG * CPG test. - Bother to set MAXFSBLOCK, MAXINO, and DIRECT_SYMLINK_EXTENSION. diff --git a/ufs-fsck/dir.c b/ufs-fsck/dir.c index b058fe9e..85757b16 100644 --- a/ufs-fsck/dir.c +++ b/ufs-fsck/dir.c @@ -1,5 +1,5 @@ /* Directory management subroutines - Copyright (C) 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,96,99,2002 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -28,19 +28,19 @@ record_directory (struct dinode *dp, ino_t number) { u_int blks; struct dirinfo *dnp; - + blks = howmany (dp->di_size, sblock->fs_bsize); if (blks > NDADDR) blks = NDADDR + NIADDR; blks *= sizeof (daddr_t); dnp = malloc (sizeof (struct dirinfo) + blks); - + dnp->i_number = number; dnp->i_parent = dnp->i_dotdot = 0; dnp->i_isize = dp->di_size; dnp->i_numblks = blks; bcopy (dp->di_db, dnp->i_blks, blks); - + if (dirarrayused == dirarraysize) { if (dirarraysize == 0) @@ -68,12 +68,12 @@ struct dirinfo * lookup_directory (ino_t ino) { int i; - + for (i = 0; i < dirarrayused; i++) if (dirarray[i]->i_number == ino) return dirarray[i]; - - errexit ("Cannot find chached directory I=%d\n", ino); + + errexit ("Cannot find cached directory I=%Ld\n", ino); } /* Check to see if DIR is really a readable directory; if it @@ -87,23 +87,23 @@ validdir (ino_t dir, char *action) case DIRECTORY: case DIRECTORY|DIR_REF: return 1; - + case UNALLOC: - warning (1, "CANNOT %s I=%d; NOT ALLOCATED", action, dir); + warning (1, "CANNOT %s I=%Ld; NOT ALLOCATED", action, dir); return 0; - + case BADDIR: - warning (1, "CANNOT %s I=%d; BAD BLOCKS", action, dir); + warning (1, "CANNOT %s I=%Ld; BAD BLOCKS", action, dir); return 0; - + case REG: - warning (1, "CANNOT %s I=%d; NOT DIRECTORY", action, dir); + warning (1, "CANNOT %s I=%Ld; NOT DIRECTORY", action, dir); return 0; default: errexit ("ILLEGAL STATE"); } -} +} /* Search directory DIR for name NAME. If NAME is found, then set *INO to the inode of the entry; otherwise clear INO. Returns 1 if all @@ -114,7 +114,7 @@ searchdir (ino_t dir, char *name, ino_t *ino) struct dinode dino; int len; - /* Scan through one directory block and see if it + /* Scan through one directory block and see if it contains NAME. */ void check1block (void *buf) @@ -147,7 +147,7 @@ searchdir (ino_t dir, char *name, ino_t *ino) { void *buf = alloca (nfrags * sblock->fs_fsize); void *bufp; - + readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); for (bufp = buf; bufp - buf < nfrags * sblock->fs_fsize @@ -160,7 +160,7 @@ searchdir (ino_t dir, char *name, ino_t *ino) } return 1; } - + *ino = 0; if (!validdir (dir, "READ")) @@ -220,7 +220,7 @@ changeino (ino_t dir, char *name, ino_t ino) { void *buf = alloca (nfrags * sblock->fs_fsize); void *bufp; - + readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); for (bufp = buf; bufp - buf < nfrags * sblock->fs_fsize @@ -236,10 +236,10 @@ changeino (ino_t dir, char *name, ino_t ino) } return 1; } - + if (!validdir (dir, "REWRITE")) return 0; - + getinode (dir, &dino); len = strlen (name); madechange = 0; @@ -254,7 +254,7 @@ expanddir (struct dinode *dp) { daddr_t lastbn, newblk; char *cp, buf[sblock->fs_bsize]; - + lastbn = lblkno (sblock, dp->di_size); if (blkoff (sblock, dp->di_size) && lastbn >= NDADDR - 1) return 0; @@ -264,24 +264,24 @@ expanddir (struct dinode *dp) return 0; else if (!blkoff (sblock, dp->di_size) && dp->di_db[lastbn]) return 0; - + newblk = allocblk (sblock->fs_frag); if (!newblk) return 0; - + if (blkoff (sblock, dp->di_size)) dp->di_db[lastbn + 1] = dp->di_db[lastbn]; dp->di_db[lastbn] = newblk; dp->di_size += sblock->fs_bsize; dp->di_blocks += sblock->fs_bsize / DEV_BSIZE; - + for (cp = buf; cp < buf + sblock->fs_bsize; cp += DIRBLKSIZ) { struct directory_entry *dir = (struct directory_entry *) cp; dir->d_ino = 0; dir->d_reclen = DIRBLKSIZ; } - + writeblock (fsbtodb (sblock, newblk), buf, sblock->fs_bsize); return 1; } @@ -297,10 +297,10 @@ makeentry (ino_t dir, ino_t ino, char *name) struct dinode dino; int needed; int madeentry; - + /* Read a directory block and see if it contains room for the new entry. If so, add it and return 1; otherwise return 0. */ - int + int check1block (void *buf) { struct directory_entry *dp; @@ -341,7 +341,7 @@ makeentry (ino_t dir, ino_t ino, char *name) } } return 0; - } + } /* Read part of a directory and look to see if it contains NAME. Return 1 if we should keep looking @@ -351,7 +351,7 @@ makeentry (ino_t dir, ino_t ino, char *name) { void *buf = alloca (nfrags * sblock->fs_fsize); void *bufp; - + readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); for (bufp = buf; bufp - buf < nfrags * sblock->fs_fsize @@ -367,10 +367,10 @@ makeentry (ino_t dir, ino_t ino, char *name) } return 1; } - + if (!validdir (dir, "MODIFY")) return 0; - + getinode (dir, &dino); len = strlen (name); needed = DIRSIZ (len); @@ -379,7 +379,7 @@ makeentry (ino_t dir, ino_t ino, char *name) if (!madeentry) { /* Attempt to expand the directory. */ - problem (0, "NO SPACE LEFT IN DIR INO=%d", dir); + problem (0, "NO SPACE LEFT IN DIR INO=%Ld", dir); if (preen || reply ("EXPAND")) { if (expanddir (&dino)) @@ -408,7 +408,7 @@ allocdir (ino_t parent, ino_t request, mode_t mode) ino_t ino; mode |= IFDIR; - + ino = allocino (request, mode); if (!ino) return 0; @@ -416,11 +416,11 @@ allocdir (ino_t parent, ino_t request, mode_t mode) goto bad; if (!makeentry (ino, parent, "..")) goto bad; - + linkfound[ino]++; linkfound[parent]++; return ino; - + bad: freeino (ino); return 0; @@ -471,16 +471,16 @@ linkup (ino_t ino, ino_t parent) } } } - + getinode (lfdir, &lfdino); if ((lfdino.di_model & IFMT) != IFDIR) { ino_t oldlfdir; - + problem (1, "`%s' IS NOT A DIRECTORY", lfname); if (! reply ("REALLOCATE")) return 0; - + oldlfdir = lfdir; lfdir = allocdir (ROOTINO, 0, lfmode); @@ -494,20 +494,20 @@ linkup (ino_t ino, ino_t parent) warning (1, "SORRY, CANNOT CREATE `%s' DIRECTORY", lfname); return 0; } - + /* One less link to the old one */ linkfound[oldlfdir]--; - + getinode (lfdir, &lfdino); } - + if (inodestate[lfdir] != DIRECTORY && inodestate[lfdir] != (DIRECTORY|DIR_REF)) { warning (1, "SORRY. `%s' DIRECTORY NOT ALLOCATED", lfname); return 0; } - asprintf (&tempname, "#%d", ino); + asprintf (&tempname, "#%Ld", ino); search_failed = !searchdir (lfdir, tempname, &foo); while (foo) { @@ -519,8 +519,8 @@ linkup (ino_t ino, ino_t parent) } if (search_failed) { - free (tempname); warning (1, "FAILURE SEARCHING FOR `%s' IN `%s'", tempname, lfname); + free (tempname); return 0; } if (!makeentry (lfdir, ino, tempname)) @@ -531,7 +531,7 @@ linkup (ino_t ino, ino_t parent) } free (tempname); linkfound[ino]++; - + if (parent != -1) { /* Reset `..' in ino */ @@ -539,7 +539,7 @@ linkup (ino_t ino, ino_t parent) { if (!changeino (ino, "..", lfdir)) { - warning (1, "CANNOT ADJUST `..' LINK I=%u", ino); + warning (1, "CANNOT ADJUST `..' LINK I=%Ld", ino); return 0; } /* Forget about link to old parent */ @@ -547,21 +547,21 @@ linkup (ino_t ino, ino_t parent) } else if (!makeentry (ino, lfdir, "..")) { - warning (1, "CANNOT CREAT `..' LINK I=%u", ino); + warning (1, "CANNOT CREAT `..' LINK I=%Ld", ino); return 0; } - + /* Account for link to lost+found; update inode directly here to avoid confusing warning later. */ linkfound[lfdir]++; linkcount[lfdir]++; lfdino.di_nlink++; write_inode (lfdir, &lfdino); - + if (parent) - warning (0, "DIR I=%u CONNECTED; PARENT WAS I=%u", ino, parent); + warning (0, "DIR I=%Ld CONNECTED; PARENT WAS I=%Ld", ino, parent); else - warning (0, "DIR I=%u CONNECTED", ino); + warning (0, "DIR I=%Ld CONNECTED", ino); } return 1; } diff --git a/ufs-fsck/fsck.h b/ufs-fsck/fsck.h index 7d55bea6..4a5dabf5 100644 --- a/ufs-fsck/fsck.h +++ b/ufs-fsck/fsck.h @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +/* + Copyright (C) 1994,95,96,2002 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -59,7 +59,7 @@ char *blockmap; extern char *device_name; -/* Command line flags */ +/* Command line flags */ int nowrite; /* all questions fail */ int noquery; /* all questions succeed */ @@ -81,7 +81,7 @@ struct dirinfo ino_t i_parent; /* inode entry of parent */ ino_t i_dotdot; /* inode number of `..' */ ino_t i_dot; /* inode number of `.' */ - ino_t i_isize; /* size of inode */ + u_int i_isize; /* size of inode */ u_int i_numblks; /* size of block array in bytes */ daddr_t i_blks[0]; /* array of inode block addresses */ }; @@ -121,10 +121,10 @@ extern int fix_denied; extern int fsmodified; -extern int lfdir; +extern ino_t lfdir; /* Total number of files found on the partition. */ -extern daddr_t num_files; +extern long num_files; extern mode_t lfmode; extern char *lfname; @@ -145,7 +145,7 @@ extern char *lfname; #define DI_MODE(dp) (((dp)->di_modeh << 16) | (dp)->di_model) - + int setup (char *); void pass1 (), pass1b (), pass2 (), pass3 (), pass4 (), pass5 (); diff --git a/ufs-fsck/pass1.c b/ufs-fsck/pass1.c index 066f4649..bd41cc62 100644 --- a/ufs-fsck/pass1.c +++ b/ufs-fsck/pass1.c @@ -1,5 +1,5 @@ /* Pass one of GNU fsck -- count blocks and verify inodes - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,2002 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -24,7 +24,7 @@ static struct dinode zino; -/* Find all the blocks in use by files and filesystem reserved blocks. +/* Find all the blocks in use by files and filesystem reserved blocks. Set them in the global block map. For each file, if a block is found allocated twice, then record the block and inode in DUPLIST. Initialize INODESTATE, LINKCOUNT, and TYPEMAP. */ @@ -52,7 +52,7 @@ pass1 () node. Increment NBLOCKS by the number of data blocks held. Set BLKERROR if this block is invalid. Return RET_GOOD, RET_BAD, RET_STOP if the block is good, - bad, or if we should entirely stop checking blocks in this + bad, or if we should entirely stop checking blocks in this inode. */ int checkblock (daddr_t bno, int nfrags, off_t offset) @@ -69,10 +69,10 @@ pass1 () blkerror = 1; wasbad = 1; if (nblkrngerrors == 0) - warning (0, "I=%d HAS BAD BLOCKS", number); + warning (0, "I=%Ld HAS BAD BLOCKS", number); if (nblkrngerrors++ > MAXBAD) { - problem (0, "EXCESSIVE BAD BLKS I=%d", number); + problem (0, "EXCESSIVE BAD BLKS I=%Ld", number); if (preen || reply ("SKIP")) { pfail ("SKIPPING"); @@ -93,12 +93,12 @@ pass1 () { blkerror = 1; if (nblkduperrors == 0) - warning (0, "I=%d HAS DUPLICATE BLOCKS", number); + warning (0, "I=%Ld HAS DUPLICATE BLOCKS", number); warning (0, "DUPLICATE BLOCK %ld", bno); wasbad = 1; if (nblkduperrors++ > MAXBAD) { - problem (0, "EXCESSIVE DUP BLKS I=%d", number); + problem (0, "EXCESSIVE DUP BLKS I=%Ld", number); if (preen || reply ("SKIP")) { pfail ("SKIPPING"); @@ -128,16 +128,16 @@ pass1 () } return wasbad ? RET_BAD : RET_GOOD; } - + /* Account for blocks used by meta data */ for (cg = 0; cg < sblock->fs_ncg; cg++) { daddr_t firstdata, firstcgblock, bno; - + /* Each cylinder group past the first reserves data from its cylinder group copy to (but not including) - the first datablock. + the first datablock. The first, however, reserves from the very front of the cylinder group (thus including the boot block), and it also @@ -155,7 +155,7 @@ pass1 () for (bno = firstcgblock; bno < firstdata; bno++) setbmap (bno); } - + /* Loop through each inode, doing initial checks */ for (number = 0, cg = 0; cg < sblock->fs_ncg; cg++) for (i = 0; i < sblock->fs_ipg; i++, number++) @@ -165,15 +165,15 @@ pass1 () int dbwarn = 0, ibwarn = 0; /* if (!preen && !(number % 10000)) - printf ("I=%d\n", number); */ + printf ("I=%Ld\n", number); */ if (number < ROOTINO) continue; - + getinode (number, dp); mode = DI_MODE (dp); type = mode & IFMT; - + /* If the node is not allocated, then make sure it's properly clear */ if (type == 0) @@ -184,7 +184,7 @@ pass1 () || DI_MODE (dp) || dp->di_size) { - problem (0, "PARTIALLY ALLOCATED INODE I=%d", number); + problem (0, "PARTIALLY ALLOCATED INODE I=%Ld", number); if (preen || reply ("CLEAR")) { clear_inode (number, dp); @@ -196,15 +196,15 @@ pass1 () else { /* Node is allocated. */ - + /* Check to see if we think the node should be cleared */ /* Verify size for basic validity */ holdallblocks = 0; - + if (dp->di_size + sblock->fs_bsize - 1 < dp->di_size) { - problem (1, "OVERFLOW IN FILE SIZE I=%d (SIZE == %lld)", number, + problem (1, "OVERFLOW IN FILE SIZE I=%Ld (SIZE == %lld)", number, dp->di_size); if (reply ("CLEAR")) { @@ -213,12 +213,12 @@ pass1 () continue; } inodestate[number] = UNALLOC; - warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%d AS ALLOCATED", + warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%Ld AS ALLOCATED", number); holdallblocks = 1; } - /* Decode type and set NDB + /* Decode type and set NDB also set inodestate correctly. */ inodestate[number] = REG; switch (type) @@ -227,19 +227,19 @@ pass1 () case IFCHR: ndb = 1; break; - + case IFIFO: case IFSOCK: ndb = 0; break; - + case IFLNK: if (sblock->fs_maxsymlinklen != -1) { /* Check to see if this is a fastlink. The old fast link format has fs_maxsymlinklen of zero and di_blocks zero; the new format has - fs_maxsymlinklen set and we ignore di_blocks. + fs_maxsymlinklen set and we ignore di_blocks. So check for either. */ if ((sblock->fs_maxsymlinklen && dp->di_size < sblock->fs_maxsymlinklen) @@ -262,16 +262,16 @@ pass1 () else ndb = howmany (dp->di_size, sblock->fs_bsize); break; - + case IFDIR: inodestate[number] = DIRECTORY; /* Fall through */ case IFREG: ndb = howmany (dp->di_size, sblock->fs_bsize); break; - + default: - problem (1, "UNKNOWN FILE TYPE I=%d (MODE=%ol)", number, mode); + problem (1, "UNKNOWN FILE TYPE I=%Ld (MODE=%ol)", number, mode); if (reply ("CLEAR")) { clear_inode (number, dp); @@ -280,14 +280,14 @@ pass1 () } inodestate[number] = UNALLOC; holdallblocks = 1; - warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%d " + warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%Ld " "AS ALLOCATED", number); ndb = 0; } if (ndb < 0) { - problem (1, "BAD FILE SIZE I= %d (SIZE == %lld)", number, + problem (1, "BAD FILE SIZE I= %Ld (SIZE == %lld)", number, dp->di_size); if (reply ("CLEAR")) { @@ -296,7 +296,7 @@ pass1 () continue; } inodestate[number] = UNALLOC; - warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%d AS ALLOCATED", + warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%Ld AS ALLOCATED", number); holdallblocks = 1; } @@ -308,10 +308,10 @@ pass1 () if (!holdallblocks) { if (dp->di_size - && (type == IFBLK || type == IFCHR + && (type == IFBLK || type == IFCHR || type == IFSOCK || type == IFIFO)) { - problem (1, "SPECIAL NODE I=%d (MODE=%ol) HAS SIZE %lld", + problem (1, "SPECIAL NODE I=%Ld (MODE=%ol) HAS SIZE %lld", number, mode, dp->di_size); if (reply ("TRUNCATE")) { @@ -319,10 +319,10 @@ pass1 () write_inode (number, dp); } } - + /* If we haven't set NDB speciall above, then it is set from the file size correctly by the size check. */ - + /* Check all the direct and indirect blocks that are past the amount necessary to be zero. */ for (lbn = ndb; lbn < NDADDR; lbn++) @@ -332,7 +332,7 @@ pass1 () if (!dbwarn) { dbwarn = 1; - problem (0, "INODE I=%d HAS EXTRA DIRECT BLOCKS", + problem (0, "INODE I=%Ld HAS EXTRA DIRECT BLOCKS", number); if (preen || reply ("DEALLOCATE")) { @@ -357,7 +357,7 @@ pass1 () if (ibwarn) { ibwarn = 1; - problem (0, "INODE I=%d HAS EXTRA INDIRECT BLOCKS", + problem (0, "INODE I=%Ld HAS EXTRA INDIRECT BLOCKS", number); if (preen || reply ("DEALLOCATE")) { @@ -373,7 +373,7 @@ pass1 () write_inode (number, dp); } } - + /* If this node is really allocated (as opposed to something that we should clear but the user won't) then set LINKCOUNT and TYPEMAP entries. */ @@ -397,7 +397,7 @@ pass1 () warning (1, "DUPLICATE or BAD BLOCKS"); else { - problem (0, "I=%d has ", number); + problem (0, "I=%Ld has ", number); if (nblkduperrors) { pextend ("%d DUPLICATE BLOCKS", nblkduperrors); @@ -418,7 +418,7 @@ pass1 () } else if (dp->di_blocks != nblocks) { - problem (0, "INCORRECT BLOCK COUNT I=%d (%ld should be %d)", + problem (0, "INCORRECT BLOCK COUNT I=%Ld (%ld should be %d)", number, dp->di_blocks, nblocks); if (preen || reply ("CORRECT")) { @@ -435,5 +435,3 @@ pass1 () } } } - - diff --git a/ufs-fsck/pass1b.c b/ufs-fsck/pass1b.c index 0cf50a17..4da86974 100644 --- a/ufs-fsck/pass1b.c +++ b/ufs-fsck/pass1b.c @@ -1,5 +1,5 @@ /* Pass 1b of fsck -- scan inodes for references to duplicate blocks - Copyright (C) 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,96,2002 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -31,7 +31,7 @@ pass1b () struct dups *duphead = duplist; /* Check each block of file DP; if the block is in the dup block - list then add it to the dup block list under this file. + list then add it to the dup block list under this file. Return RET_GOOD or RET_BAD if the block is good or bad, respectively. */ int @@ -39,7 +39,7 @@ pass1b () { struct dups *dlp; int hadbad = 0; - + for (; nfrags > 0; bno++, nfrags--) { if (check_range (bno, 1)) @@ -76,7 +76,7 @@ pass1b () allblock_iterate (dp, checkblock); if (dupblk) { - problem (1, "I=%d HAS %d DUPLICATE BLOCKS", number, dupblk); + problem (1, "I=%Ld HAS %d DUPLICATE BLOCKS", number, dupblk); if (reply ("CLEAR")) { clear_inode (number, dp); @@ -88,5 +88,3 @@ pass1b () } } } - - diff --git a/ufs-fsck/pass2.c b/ufs-fsck/pass2.c index a2d5996c..d95929ef 100644 --- a/ufs-fsck/pass2.c +++ b/ufs-fsck/pass2.c @@ -1,5 +1,5 @@ /* Pass 2 of GNU fsck -- examine all directories for validity - Copyright (C) 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,96,2002 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -70,7 +70,7 @@ pass2 () for (bp = (char *)buf; bp < (char *)buf + DIRBLKSIZ; bp++) if (*bp) goto reclen_problem; - + problem (0, "NULL BLOCK IN DIRECTORY"); if (preen || reply ("PATCH")) { @@ -83,7 +83,7 @@ pass2 () else return mod; } - + reclen_problem: problem (1, "BAD RECLEN IN DIRECTORY"); if (reply ("SALVAGE")) @@ -98,7 +98,7 @@ pass2 () /* But give up regardless */ return mod; } - + /* Check INO */ if (dp->d_ino > maxino) { @@ -113,7 +113,7 @@ pass2 () if (!dp->d_ino) continue; - + /* Check INO */ if (inodestate[dp->d_ino] == UNALLOC) { @@ -138,7 +138,7 @@ pass2 () dp->d_ino = 0; mod = 1; } - } + } else { /* Check for illegal characters */ @@ -165,7 +165,7 @@ pass2 () } } } - + if (!dp->d_ino) continue; @@ -181,10 +181,10 @@ pass2 () mod = 1; } } - + /* Here we should check for duplicate directory entries; that's too much trouble right now. */ - + /* Account for the inode in the linkfound map */ if (inodestate[dp->d_ino] != UNALLOC) linkfound[dp->d_ino]++; @@ -205,7 +205,7 @@ pass2 () { problem (0, "EXTRANEOUS LINK `%s' TO DIR I=%ld", dp->d_name, dp->d_ino); - pextend (" FOUND IN DIR I=%d", dnp->i_number); + pextend (" FOUND IN DIR I=%Ld", dnp->i_number); if (preen || reply ("REMOVE")) { dp->d_ino = 0; @@ -234,9 +234,9 @@ pass2 () readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); rewrite = 0; - for (bufp = buf; + for (bufp = buf; bufp - buf < nfrags * sblock->fs_fsize - && offset + (bufp - buf) + DIRBLKSIZ <= dnp->i_isize; + && offset + (bufp - buf) + DIRBLKSIZ <= dnp->i_isize; bufp += DIRBLKSIZ) { if (check1block (bufp)) @@ -251,7 +251,7 @@ pass2 () { default: errexit ("BAD STATE %d FOR ROOT INODE", (int) (inodestate[ROOTINO])); - + case DIRECTORY: break; @@ -262,7 +262,7 @@ pass2 () if (allocdir (ROOTINO, ROOTINO, 0755) != ROOTINO) errexit ("CANNOT ALLOCATE ROOT INODE"); break; - + case REG: problem (1, "ROOT INODE NOT DIRECTORY"); if (reply ("REALLOCATE")) @@ -270,7 +270,7 @@ pass2 () if (allocdir (ROOTINO, ROOTINO, 0755) != ROOTINO) errexit ("CANNOT ALLOCATE ROOT INODE"); break; - + case BADDIR: problem (1, "DUPLICATE or BAD BLOCKS IN ROOT INODE"); if (reply ("REALLOCATE")) @@ -283,20 +283,20 @@ pass2 () errexit ("ABORTING"); break; } - + /* Sort inpsort */ qsort (dirsorted, dirarrayused, sizeof (struct dirinfo *), sortfunc); - + /* Check basic integrity of each directory */ for (nd = 0; nd < dirarrayused; nd++) { dnp = dirsorted[nd]; - + if (dnp->i_isize == 0) continue; if (dnp->i_isize % DIRBLKSIZ) { - problem (0, "DIRECTORY INO=%d: LENGTH %d NOT MULTIPLE OF %d", + problem (0, "DIRECTORY INO=%Ld: LENGTH %d NOT MULTIPLE OF %d", dnp->i_number, dnp->i_isize, DIRBLKSIZ); if (preen || reply ("ADJUST")) { @@ -310,10 +310,10 @@ pass2 () dino.di_size = dnp->i_isize; assert (dnp->i_numblks <= (NDADDR + NIADDR) * sizeof (daddr_t)); bcopy (dnp->i_blks, dino.di_db, dnp->i_numblks); - + datablocks_iterate (&dino, checkdirblock); } - + /* At this point for each directory: If this directory is an entry in another directory, then i_parent is @@ -323,12 +323,12 @@ pass2 () for (nd = 0; nd < dirarrayused; nd++) { dnp = dirsorted[nd]; - + /* Root is considered to be its own parent even though it isn't listed. */ if (dnp->i_number == ROOTINO && !dnp->i_parent) dnp->i_parent = ROOTINO; - + /* Check `.' to make sure it exists and is correct */ if (dnp->i_dot == 0) { @@ -397,5 +397,4 @@ pass2 () } } } -} - +} diff --git a/ufs-fsck/pass5.c b/ufs-fsck/pass5.c index 7ea7aeed..cb426a7d 100644 --- a/ufs-fsck/pass5.c +++ b/ufs-fsck/pass5.c @@ -1,5 +1,5 @@ /* Pass 5 of GNU fsck -- check allocation maps and summaries - Copyright (C) 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,96,2001 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -23,7 +23,7 @@ /* From ../ufs/subr.c: */ /* - * Update the frsum fields to reflect addition or deletion + * Update the frsum fields to reflect addition or deletion * of some frags. */ static void @@ -87,7 +87,7 @@ pass5 () sbcsums = alloca (fragroundup (sblock, sblock->fs_cssize)); - readblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, + readblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, fragroundup (sblock, sblock->fs_cssize)); /* Construct a CG structure; initialize everything that's the same @@ -105,37 +105,37 @@ pass5 () savednrpos = sblock->fs_nrpos; sblock->fs_nrpos = 8; break; - + case FS_DYNAMICPOSTBLFMT: /* Set fields unique to new cg structure */ newcg->cg_btotoff = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); newcg->cg_boff = newcg->cg_btotoff + sblock->fs_cpg * sizeof (long); newcg->cg_iusedoff = newcg->cg_boff + (sblock->fs_cpg - * sblock->fs_nrpos + * sblock->fs_nrpos * sizeof (short)); newcg->cg_freeoff = newcg->cg_iusedoff + howmany (sblock->fs_ipg, NBBY); if (sblock->fs_contigsumsize <= 0) { - newcg->cg_nextfreeoff = + newcg->cg_nextfreeoff = (newcg->cg_freeoff + howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), NBBY)); } else { - newcg->cg_clustersumoff = + newcg->cg_clustersumoff = (newcg->cg_freeoff + howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), NBBY) - sizeof (long)); - newcg->cg_clustersumoff = + newcg->cg_clustersumoff = roundup (newcg->cg_clustersumoff, sizeof (long)); - newcg->cg_clusteroff = - (newcg->cg_clustersumoff + newcg->cg_clusteroff = + (newcg->cg_clustersumoff + (sblock->fs_contigsumsize + 1) * sizeof (long)); - newcg->cg_nextfreeoff = - (newcg->cg_clusteroff - + howmany (sblock->fs_cpg * sblock->fs_spc / NSPB (sblock), + newcg->cg_nextfreeoff = + (newcg->cg_clusteroff + + howmany (sblock->fs_cpg * sblock->fs_spc / NSPB (sblock), NBBY)); } @@ -150,32 +150,32 @@ pass5 () default: errexit ("UNKNOWN POSTBL FORMAT"); } - + bzero (&cstotal, sizeof (struct csum)); /* Mark fragments past the end of the filesystem as used. */ j = blknum (sblock, sblock->fs_size + sblock->fs_frag - 1); for (i = sblock->fs_size; i < j; i++) setbmap (i); - + /* Now walk through the cylinder groups, checking each one. */ for (c = 0; c < sblock->fs_ncg; c++) { int dbase, dmax; - + /* Read the cylinder group structure */ readblock (fsbtodb (sblock, cgtod (sblock, c)), cg, sblock->fs_cgsize); writecg = 0; - + if (!cg_chkmagic (cg)) warning (1, "CG %d: BAD MAGIC NUMBER", c); - + /* Compute first and last data block addresses in this group */ dbase = cgbase (sblock, c); dmax = dbase + sblock->fs_fpg; if (dmax > sblock->fs_size) dmax = sblock->fs_size; - + /* Initialize newcg fully; values from cg for those we can't check. */ newcg->cg_time = cg->cg_time; @@ -230,7 +230,7 @@ pass5 () pfix ("FIXED"); } } - + /* Zero the block maps and summary areas */ bzero (&newcg->cg_frsum[0], sizeof newcg->cg_frsum); bzero (&cg_blktot (newcg)[0], sumsize + mapsize); @@ -267,8 +267,8 @@ pass5 () setbit (cg_inosused (newcg), i); newcg->cg_cs.cs_nifree--; } - - /* Walk through each data block, accounting for it in + + /* Walk through each data block, accounting for it in the block map and in newcg->cg_cs. */ /* In this look, D is the block number and I is the block number relative to this CG. */ @@ -277,7 +277,7 @@ pass5 () d += sblock->fs_frag, i += sblock->fs_frag) { int frags = 0; - + /* Set each free frag of this block in the block map; count how many frags were free. */ for (j = 0; j < sblock->fs_frag; j++) @@ -287,8 +287,8 @@ pass5 () setbit (cg_blksfree (newcg), i + j); frags++; } - - /* If all the frags were free, then count this as + + /* If all the frags were free, then count this as a free block too. */ if (frags == sblock->fs_frag) { @@ -308,7 +308,7 @@ pass5 () ffs_fragacct (sblock, blk, newcg->cg_frsum, 1); } } - + if (sblock->fs_contigsumsize > 0) { long *sump = cg_clustersum (newcg); @@ -316,7 +316,7 @@ pass5 () int map = *mapp++; int bit = 1; int run = 0; - + for (i = 0; i < newcg->cg_nclusterblks; i++) { if ((map & bit) != 0) @@ -363,7 +363,7 @@ pass5 () pfix ("FIXED"); } } - + /* Check inode and block maps */ if (bcmp (cg_inosused (newcg), cg_inosused (cg), mapsize)) { @@ -375,7 +375,7 @@ pass5 () pfix ("FIXED"); } } - + if (bcmp (&cg_blktot(newcg)[0], &cg_blktot(cg)[0], sumsize)) { problem (0, "SUMMARY INFORMATION FOR CG %d BAD", c); @@ -386,7 +386,7 @@ pass5 () pfix ("FIXED"); } } - + if (bcmp (newcg, cg, basesize)) { problem (0, "CYLINDER GROUP %d BAD", c); @@ -399,14 +399,14 @@ pass5 () } if (writecg) - writeblock (fsbtodb (sblock, cgtod (sblock, c)), + writeblock (fsbtodb (sblock, cgtod (sblock, c)), cg, sblock->fs_cgsize); } - + /* Restore nrpos */ if (sblock->fs_postblformat == FS_42POSTBLFMT) sblock->fs_nrpos = savednrpos; - + if (bcmp (&cstotal, &sblock->fs_cstotal, sizeof (struct csum))) { problem (0, "TOTAL FREE BLK COUNTS WRONG IN SUPERBLOCK"); @@ -430,21 +430,21 @@ pass5 () pfix ("MARKED CLEAN"); } } - + if (writesb) writeblock (SBLOCK, sblock, SBSIZE); if (writecsum) { + const int cssize = fragroundup (sblock, sblock->fs_cssize); struct csum *test; - - writeblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, + + writeblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, fragroundup (sblock, sblock->fs_cssize)); - test = alloca (fragroundup (sblock, sblock->fs_cssize)); - readblock (fsbtodb (sblock, sblock->fs_csaddr), test, - fragroundup (sblock, sblock->fs_cssize)); - if (bcmp (test, sbcsums, fragroundup (sblock, sblock->fs_cssize))) + test = alloca (cssize); + readblock (fsbtodb (sblock, sblock->fs_csaddr), test, cssize); + if (bcmp (test, sbcsums, cssize)) warning (0, "CSUM WRITE INCONSISTENT"); } } diff --git a/ufs-fsck/setup.c b/ufs-fsck/setup.c index d40cf70b..9433bd68 100644 --- a/ufs-fsck/setup.c +++ b/ufs-fsck/setup.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1996 Free Software Foundation, Inc. +/* + Copyright (C) 1994,96,99,2002 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -42,7 +42,7 @@ int fix_denied = 0; int fsmodified = 0; -int lfdir; +ino_t lfdir; /* Get ready to run on device with pathname DEV. */ int @@ -51,7 +51,7 @@ setup (char *dev) struct stat st; int changedsb; size_t bmapsize; - + device_name = dev; if (stat (dev, &st) == -1) @@ -59,9 +59,9 @@ setup (char *dev) error (0, errno, "%s", dev); return 0; } - if (!S_ISCHR (st.st_mode)) + if (!S_ISCHR (st.st_mode) && !S_ISBLK (st.st_mode)) { - problem (1, "%s is not a character device", dev); + problem (1, "%s is not a character or block device", dev); if (! reply ("CONTINUE")) return 0; } @@ -88,7 +88,7 @@ setup (char *dev) if (preen == 0) printf ("\n"); - + lfdir = 0; /* We don't do the alternate superblock stuff here (yet). */ @@ -171,10 +171,10 @@ setup (char *dev) sblock->fs_qfmask = ~sblock->fs_fmask; newinofmt = 0; } - + if (changedsb) writeblock (SBLOCK, sblock, SBSIZE); - + /* Constants */ maxfsblock = sblock->fs_size; maxino = sblock->fs_ncg * sblock->fs_ipg; @@ -189,6 +189,3 @@ setup (char *dev) linkfound = calloc (maxino + 1, sizeof (nlink_t)); return 1; } - - - diff --git a/ufs-fsck/utilities.c b/ufs-fsck/utilities.c index 4c515f61..14705f84 100644 --- a/ufs-fsck/utilities.c +++ b/ufs-fsck/utilities.c @@ -1,5 +1,5 @@ /* Miscellaneous functions for fsck - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,99,2001,02 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -25,6 +25,7 @@ #include <stdarg.h> #include <pwd.h> #include <error.h> +#include <time.h> static void retch (char *reason); @@ -61,12 +62,12 @@ getinode (ino_t ino, struct dinode *di) if (!lastifrag) lastifrag = malloc (sblock->fs_bsize); - + iblk = ino_to_fsba (sblock, ino); if (iblk != lastifragaddr) readblock (fsbtodb (sblock, iblk), lastifrag, sblock->fs_bsize); lastifragaddr = iblk; - bcopy (lastifrag + ino_to_fsbo (sblock, ino) * sizeof (struct dinode), + bcopy (lastifrag + ino_to_fsbo (sblock, ino) * sizeof (struct dinode), di, sizeof (struct dinode)); } @@ -75,7 +76,7 @@ void write_inode (ino_t ino, struct dinode *di) { daddr_t iblk; - + iblk = ino_to_fsba (sblock, ino); if (iblk != lastifragaddr) readblock (fsbtodb (sblock, iblk), lastifrag, sblock->fs_bsize); @@ -101,10 +102,10 @@ allocblk (int nfrags) { daddr_t i; int j, k; - + if (nfrags <= 0 || nfrags > sblock->fs_frag) return 0; - + /* Examine each block of the filesystem. */ for (i = 0; i < maxfsblock - sblock->fs_frag; i += sblock->fs_frag) { @@ -115,7 +116,7 @@ allocblk (int nfrags) for (k = 0; k < nfrags; k++) if (testbmap (i + j + k)) break; - + /* If one of the frags was allocated... */ if (k < nfrags) { @@ -123,7 +124,7 @@ allocblk (int nfrags) j += k; continue; } - + /* It's free (at address i + j) */ /* Mark the frags allocated in our map */ @@ -136,16 +137,16 @@ allocblk (int nfrags) return 0; } -/* Check if a block starting at BLK and extending for CNT +/* Check if a block starting at BLK and extending for CNT fragments is out of range; if it is, then return 1; otherwise return 0. */ int check_range (daddr_t blk, int cnt) { int c; - + if ((unsigned)(blk + cnt) > maxfsblock) return 1; - + c = dtog (sblock, blk); if (blk < cgdmin (sblock, c)) { @@ -157,9 +158,9 @@ check_range (daddr_t blk, int cnt) if (blk + cnt > cgbase (sblock, c + 1)) return 1; } - + return 0; -} +} struct problem { char *desc; @@ -236,7 +237,7 @@ flush_problems () { fail (problems)->prev = free_problems; free_problems = problems; - } + } } /* Like printf, but exit after printing. */ @@ -269,14 +270,14 @@ retch (char *reason) static void punt (char *msg) { - problem (0, msg); + problem (0, "%s", msg); flush_problems (); exit (8); } /* If SEVERE is true, and we're in preen mode, then things are too hair to fix automatically, so tell the user to do it himself and punt. */ -static void +static void no_preen (int severe) { if (severe && preen) @@ -295,7 +296,7 @@ problem (int severe, char *fmt, ...) va_start (args, fmt); push_problem (fmt, args); va_end (args); - + no_preen (severe); } @@ -322,6 +323,7 @@ pextend (char *fmt, ...) strcpy (concat + strlen (concat), more); prob->desc = concat; + free (more); } /* Like problem, but as if immediately followed by pfail. */ @@ -353,7 +355,7 @@ pinode (int severe, ino_t ino, char *fmt, ...) } if (ino < ROOTINO || ino > maxino) - pextend (" (BOGUS INODE) I=%d", ino); + pextend (" (BOGUS INODE) I=%Ld", ino); else { char *p; @@ -362,7 +364,7 @@ pinode (int severe, ino_t ino, char *fmt, ...) getinode (ino, &dino); - pextend (" %s I=%d", (DI_MODE (&dino) & IFMT) == IFDIR ? "DIR" : "FILE", + pextend (" %s I=%Ld", (DI_MODE (&dino) & IFMT) == IFDIR ? "DIR" : "FILE", ino); pw = getpwuid (dino.di_uid); @@ -370,7 +372,7 @@ pinode (int severe, ino_t ino, char *fmt, ...) pextend (" O=%s", pw->pw_name); else pextend (" O=%lu", dino.di_uid); - + pextend (" M=0%o", DI_MODE (&dino)); pextend (" SZ=%llu", dino.di_size); p = ctime (&dino.di_mtime.tv_sec); @@ -406,7 +408,7 @@ reply (char *question) { int persevere; char c; - + if (preen) retch ("Got to reply() in preen mode"); @@ -448,6 +450,6 @@ reply (char *question) { fix_denied = 1; return 0; - } + } } } diff --git a/ufs-utils/ChangeLog b/ufs-utils/ChangeLog deleted file mode 100644 index 656a25ec..00000000 --- a/ufs-utils/ChangeLog +++ /dev/null @@ -1,127 +0,0 @@ -Thu Apr 10 13:54:31 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dlabel.c: Don't include <mach/sa/sys/ioctl.h>. - (_IOR, _IOC, IOC_OUT, IOCPARM_MASK): New macros. - -Wed Feb 19 23:10:54 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * mkfs.c (argp_program_version): Make const. - -Thu Sep 5 11:44:38 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * mkfs.c: Include <version.h>. - (argp_program_version): Define with STANDARD_HURD_VERSION. - -Mon Aug 19 15:18:30 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * mkfs.c (doc): Supply a useful value. - -Tue Jul 23 19:34:58 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * mkfs.c (fsinit): `struct timespec' now uses a field prefix of `tv_'. - * stati.c (timespec_rep): Likewise. - -Fri Jun 21 02:12:16 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * dlabel.c (fd_get_device): Supply new args to store_create. - -Sat May 11 01:20:18 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * mkfs.c (parse_opt): Use ARGP_ERR_UNKNOWN instead of EINVAL. - -Fri May 10 15:50:38 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * dlabel.c (fd_get_device): Update to use libstore. - <hurd/store.h>: New include. - * Makefile (mkfs.ufs): Depend on ../libstore/libstore.a. - -Tue Apr 30 10:06:21 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (include ../Makeconf): BEFORE dependencies. - (all): Delete target. - ($(targets)): Each target depends on its associated .o. - -Wed Apr 3 16:31:13 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * mkfs.c (main): In `Can't get disklabel' error message, specify - which flag the user can use to supply the needed information. - (mkfs): Fiddle with info message. - -Sun Mar 31 14:34:28 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * stati.c (mode_rep): Prefix octal number with `0'. - -Fri Mar 29 11:56:52 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * stati.c (main): Print mode & {in,}direct blocks too. - (mode_rep): New function. - (timespec_rep): P shouldn't be static. - - * mkfs.c (main): Argp interface changes. - -Wed Mar 13 18:30:55 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * mkfs.c (options, args_doc, doc): New variables for option parsing. - (struct amark): New type. - (amarks_add, amarks_contains): New functions. - (default_disklabel): New variable. - (main): Most arguments are now options (and optional). Allow many - more parameters to be specified. Consult the disk label for some - defaults. - (most functions): Add explicit return type declarations. Fix - printf format specifications. Get rid of #ifdefs for MFS. - (started, malloc, realloc, calloc, free): Functions removed. - (mfs, membase): Variables removed. - <stddef.h>, <stdlib.h>, <argp.h>, <assert.h>, <error.h>, - <string.h>: New includes - * dlabel.c: New file. - * Makefile (SRCS): Add dlabel.c. - (mkfs.ufs): New target. - -Tue Feb 27 14:52:00 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * clri.c: Move here from ../utils. - - [Entire directory renamed to `ufs-utils' from `newfs'] - -Sat Sep 9 12:17:11 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (target): Changed to `mkfs.ufs'. - (installationdir): New variable, install into $(sbindir). - -Thu Nov 24 18:39:30 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * mkfs.c: Protect all mfs code with #ifdef MFS. - -Wed Oct 12 12:59:01 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * mkfs.c (main): MAXCONTIG should be zero because we don't - do clustering. - -Fri Sep 9 09:45:23 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * mkfs.c: Include <sys/stat.h> and <fcntl.h>. - (main): New function. Punt newfs.c for now. - * Makefile (SRCS, OBJS): Comment out uses of newfs.c. - (target): Build mkfs, not newfs. - - * newfs.c (mopts): Comment out. - (mntflags): Comment out. - (main): Omit check for `mfs'. Omit var `partition'. - (main) [case 'o']: Comment out mfs specific code. - (main): Comment out check for already-mounted partition. - (main): Comment out MFS specific open of FSI. - - * mkfs.c (fsinit): Use DI_MODE to read mode from NODE, and - set di_model and di_modeh instead of di_mode. - (mkfs): Don't set fields in *PP. - - * newfs.c: Include ufs header files with "../ufs/foo.h" instead of - <ufs/ufs/foo.h>. Don't include <sys/disklabel.h>, <sys/mount.h>, - or "mntopts.h". - -Thu Sep 8 15:52:05 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * mkfs.c: Include ufs header files with "../ufs/foo.h" instead of - <ufs/ufs/foo.h>. Don't include <sys/disklabel.h>. - diff --git a/ufs-utils/Makefile b/ufs-utils/Makefile index b27b76c4..df22440e 100644 --- a/ufs-utils/Makefile +++ b/ufs-utils/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1994, 1996 Free Software Foundation +# Copyright (C) 1994, 1996, 2008 Free Software Foundation # Written by Michael I. Bushnell. # # This file is part of the GNU Hurd. @@ -27,6 +27,7 @@ SRCS = mkfs.c clri.c stati.c dlabel.c installationdir = $(sbindir) OBJS = $(SRCS:.c=.o) +HURDLIBS = store shouldbeinlibc include ../Makeconf diff --git a/ufs-utils/dlabel.c b/ufs-utils/dlabel.c index a51fc8ec..355cb3f6 100644 --- a/ufs-utils/dlabel.c +++ b/ufs-utils/dlabel.c @@ -1,8 +1,8 @@ /* Get the disklabel from a device node - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996,99,2001 Free Software Foundation, Inc. - Written by Miles Bader <miles@gnu.ai.mit.edu> + Written by Miles Bader <miles@gnu.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -43,10 +43,10 @@ fd_get_device (int fd, device_t *device) if (node == MACH_PORT_NULL) return errno; - err = store_create (node, 0, 0, &store); + err = store_create (node, 0, 0, &store); /* consumes NODE on success */ if (! err) { - if (store->class != STORAGE_DEVICE + if (store->class->id != STORAGE_DEVICE /* In addition to requiring a device, we also want the *whole* device -- one contiguous run starting at 0. */ || store->num_runs != 1 @@ -63,8 +63,8 @@ fd_get_device (int fd, device_t *device) } store_free (store); } - - mach_port_deallocate (mach_task_self (), node); + else + mach_port_deallocate (mach_task_self (), node); return err; } diff --git a/ufs-utils/mkfs.c b/ufs-utils/mkfs.c index b6303e86..aef3ea92 100644 --- a/ufs-utils/mkfs.c +++ b/ufs-utils/mkfs.c @@ -33,7 +33,7 @@ #ifndef lint /*static char sccsid[] = "from: @(#)mkfs.c 8.3 (Berkeley) 2/3/94";*/ -static char *rcsid = "$Id: mkfs.c,v 1.16 1997/02/20 04:15:02 miles Exp $"; +static char *rcsid = "$Id: mkfs.c,v 1.22 2006/03/14 23:27:50 tschwinge Exp $"; #endif /* not lint */ #include <unistd.h> @@ -63,7 +63,7 @@ static char *rcsid = "$Id: mkfs.c,v 1.16 1997/02/20 04:15:02 miles Exp $"; /* Begin misc additions for GNU Hurd */ -/* For GNU Hurd: the ufs DIRSIZ macro is different than the BSD +/* For GNU Hurd: the ufs DIRSIZ macro is different than the BSD 4.4 version that mkfs expects. So we provide here the BSD version. */ #undef DIRSIZ #if (BYTE_ORDER == LITTLE_ENDIAN) @@ -90,6 +90,7 @@ static char *rcsid = "$Id: mkfs.c,v 1.16 1997/02/20 04:15:02 miles Exp $"; #ifndef STANDALONE #include <a.out.h> #include <stdio.h> +#include <time.h> #endif /* @@ -174,22 +175,22 @@ static const struct argp_option options[] = { {"just-print", 'N', 0, 0, "Just print the file system parameters that would be used"}, {"old-format", 'O', 0, 0, "Create a 4.3BSD format filesystem"}, - {"max-contig", 'a', "BLOCKS", 0, + {"max-contig", 'a', "BLOCKS", 0, "The maximum number of contiguous blocks that will be laid out before" " forcing a rotational delay; the default is no limit"}, {"block-size", 'b', "BYTES", 0, "The block size of the file system"}, {"group-cylinders", 'c', "N", 0, "The number of cylinders per cylinder group; the default 16"}, - {"rot-delay", 'd', "MSEC", 0, + {"rot-delay", 'd', "MSEC", 0, "The expected time to service a transfer completion interrupt and" " initiate a new transfer on the same disk; the default is 0"}, - {"max-bpg", 'e', "BLOCKS", 0, + {"max-bpg", 'e', "BLOCKS", 0, "Maximum number of blocks any single file can allocate out of a cylinder" " group before it is forced to begin allocating blocks from another" " cylinder group; the default is about one quarter of the total blocks" " in a cylinder group"}, {"frag-size", 'f', "BYTES", 0, "The fragment size"}, - {"inode-density", 'i', "BYTES", 0, + {"inode-density", 'i', "BYTES", 0, "The density of inodes in the file system, in bytes of data space per" " inode; the default is one inode per 4 filesystem frags"}, {"minfree", 'm', "PERCENT", 0, @@ -211,7 +212,7 @@ static const struct argp_option options[] = { {"tracks", 't', "N", 0, "The number of tracks/cylinder"}, {"sectors", 'u', "N", 0, "The number of sectors per track (does not include sectors reserved for" - " bad block replacement"}, + " bad block replacement"}, {"spare-sectors", 'p', "N", 0, "Spare sectors (for bad sector replacement) at the end of each track"}, {"cyl-spare-sectors", 'x', "N", 0, @@ -261,7 +262,7 @@ char *device = 0; #define deverr(code, err, fmt, args...) \ error (code, err, "%s: " fmt, device , ##args) -void +int main (int argc, char **argv) { int fdo, fdi; @@ -277,11 +278,9 @@ main (int argc, char **argv) { case 'N': Nflag = 1; break; case 'O': Oflag = 1; break; - - /* Mark &VAR as being a uparam, and return a lvalue for VAR. */ -#define UP(var) (amarks_add (&uparams, &var), var) - /* Record an integer uparam into VAR. */ -#define UP_INT(var) { int _i = atoi (arg); UP (var) = _i; } + +/* Mark &VAR as being a uparam, and set VAR. */ +#define UP_INT(var) { amarks_add (&uparams, &var); var = atoi (arg); } case 'a': UP_INT (maxcontig); break; case 'b': UP_INT (bsize); break; @@ -302,7 +301,7 @@ main (int argc, char **argv) case 'p': UP_INT (nspares); break; case 'x': UP_INT (ncspares); break; - case 'o': + case 'o': amarks_add (&uparams, &opt); if (strcmp (arg, "time") == 0) opt = FS_OPTTIME; @@ -413,7 +412,7 @@ main (int argc, char **argv) nphyssectors = nsectors + nspares; secpercyl = nsectors * ntracks; - + DEFAULT (rpm, DL_INT (0, d_rpm)); DEFAULT (interleave, DL_INT (0, d_interleave)); DEFAULT (trackskew, DL_SECS (0, d_trackskew)); @@ -422,7 +421,7 @@ main (int argc, char **argv) DEFAULT (fsize, 1024); DEFAULT (bsize, 8192); - + DEFAULT (cpg, 16); DEFAULT (minfree, MINFREE); DEFAULT (opt, DEFAULTOPT); @@ -439,7 +438,7 @@ main (int argc, char **argv) mkfs (0, device, fdi, fdo); - exit (0); + return 0; } void @@ -656,7 +655,7 @@ mkfs(pp, fsys, fi, fo) } else exit(23); - /* + /* * Calculate the number of cylinders per group */ sblock.fs_cpg = cpg; @@ -863,6 +862,7 @@ next: sblock.fs_cstotal.cs_nffree = 0; sblock.fs_fmod = 0; sblock.fs_ronly = 0; + sblock.fs_clean = 1; /* * Dump out summary information about file system. @@ -904,7 +904,7 @@ next: sblock.fs_cssize - i < sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize, ((char *)fscs) + i); - /* + /* * Write out the duplicate super blocks */ for (cylno = 0; cylno < sblock.fs_ncg; cylno++) @@ -962,7 +962,7 @@ initcg(cylno, utime) acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag; acg.cg_btotoff = &acg.cg_space[0] - (u_char *)(&acg.cg_link); acg.cg_boff = acg.cg_btotoff + sblock.fs_cpg * sizeof(long); - acg.cg_iusedoff = acg.cg_boff + + acg.cg_iusedoff = acg.cg_boff + sblock.fs_cpg * sblock.fs_nrpos * sizeof(short); acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, NBBY); if (sblock.fs_contigsumsize <= 0) { @@ -1156,6 +1156,14 @@ fsinit(utime) node.di_model = IFDIR | UMASK; node.di_modeh = 0; node.di_nlink = PREDEFDIR; + + /* Set the uid/gid to non-root if run by a non-root user. This + is what mke2fs does in e2fsprogs-1.18 (actually it uses the + real IDs iff geteuid()!=0, but that is just wrong). */ + node.di_uid = geteuid(); + if (node.di_uid != 0) + node.di_gid = getegid(); + if (Oflag) node.di_size = makedir((struct directory_entry *)oroot_dir, PREDEFDIR); else @@ -1269,7 +1277,7 @@ iput(ip, ino) sblock.fs_cstotal.cs_nifree--; fscs[0].cs_nifree--; if (ino >= sblock.fs_ipg * sblock.fs_ncg) - deverr (32, 0, "fsinit: inode value out of range (%d)", ino); + deverr (32, 0, "fsinit: inode value out of range (%Ld)", ino); d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino)); rdfs(d, sblock.fs_bsize, buf); buf[ino_to_fsbo(&sblock, ino)] = *ip; diff --git a/ufs-utils/stati.c b/ufs-utils/stati.c index 2c0147d0..ba545bf2 100644 --- a/ufs-utils/stati.c +++ b/ufs-utils/stati.c @@ -61,6 +61,7 @@ static char sccsid[] __attribute__ ((unused)); #include <stdlib.h> #include <string.h> #include <stdio.h> +#include <time.h> #include <unistd.h> #include <pwd.h> #include <grp.h> @@ -94,7 +95,7 @@ mode_rep (unsigned short mode) case S_IFIFO: *p++ = 'f'; break; default: *p++ = '?'; } - + add_perms (0, S_ISUID); add_perms (3, S_ISGID); add_perms (6, 0); diff --git a/ufs/ChangeLog b/ufs/ChangeLog deleted file mode 100644 index 323da685..00000000 --- a/ufs/ChangeLog +++ /dev/null @@ -1,1766 +0,0 @@ -Thu Feb 6 01:56:27 1997 Miles Bader <miles@gnu.ai.mit.edu> - - (diskfs_S_file_getfh, diskfs_S_fsys_getfile): Functions removed. - -Tue Nov 19 18:28:26 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (read_disknode): If SBLOCK->fs_inodefmt < FS_44INODEFMT, - set ST->st_author to st->st_uid, and NP->author_tracks_uid to true. - (diskfs_validate_author_change): New function. - -Mon Nov 18 17:10:00 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (read_disknode): When setting ST->st_mode, Clear - S_ITRANS bits, and set S_IPTRANS if necessary. Don't set - NP->istranslated anymore. - (diskfs_set_translator): Frob S_IPTRANS bit in mode bits instead - of NP->istranslated. - (write_node): Don't write any bits in S_ITRANS to disk. - * alloc.c (ffs_alloc): Use S_IPTRANS in NP->dn_stat.st_mode - instead of NP->istranslated. - -Sat Nov 16 17:21:40 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * inode.c (diskfs_S_fsys_getfile): Delete var `fakecred'. - diskfs_access -> fshelp_access. - * alloc.c (ffs_alloc): diskfs_isuid -> idvec_contains. - (ffs_realloccg): Likewise. - -Thu Nov 14 16:43:36 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * inode.c (diskfs_S_file_getfh): diskfs_isuid -> idvec_contains. - (diskfs_S_fsys_getfile): Use idvecs and iousers. - -Thu Oct 24 16:07:17 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (startup_children, runtime_children): New variables. - (startup_parents, runtime_parents): Variables removed. - (startup_argp, runtime_argp): Use new *_CHILDREN variables instead of - corresponding *_PARENT ones. - -Thu Sep 19 18:02:40 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * Makefile (HURDLIBS): Add store. - -Wed Sep 18 15:30:00 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_S_file_get_storage_info): Narrow scope of RUN. - - * consts.c (diskfs_extra_version): New variable. - - * main.c (main): Remove CLASSES argument to store_parsed_open. - Use STORE_PARAMS variable to get result from parsing STORE_ARGP. - Don't force COMPAT_GNU on bootstrap filesystems (it's the default - anyway). - -Mon Sep 16 13:27:38 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * Makefile (ufs.static ufs): Add ../libstore/libstore.a. - - * hyper.c (zeroblock): Change type to `void *'. - (get_hypermetadata): Cast ZEROBLOCK when vm_{de,}allocating. - * ufs.h (zeroblock): Change type to `void *'. - * sizes.c (diskfs_truncate): Don't cast ZEROBLOCK to diskfs_node_rw. - (block_extended, diskfs_grow): Do cast it to offer_data. - - * main.c (main): Don't set DISKFS_USE_MACH_DEVICE (which is no longer). - - * inode.c (diskfs_S_file_get_storage_info): Coalesce adjacent - blocks when constructing RUNS. - Set *PORTS_TYPE, not *STORAGE_PORT_TYPE. - * inode.c (diskfs_S_file_getfh): Variable ERR removed. - - * sizes.c (indir_release): Use DISKFS_DISK_PAGER instead of DISK_PAGER. - * ufs.h (sync_disk_blocks): Likewise. - * pokeloc.c (sync_disk): Likewise. - * main.c (diskfs_reload_global_state): Likewise. - * pager.c (create_disk_pager, diskfs_shutdown_pager, - diskfs_sync_everything): Likewise. - * main.c <argp.h>, <hurd/store.h>: New includes. - * hyper.c, pager.c, inode.c <hurd/store.h>: New include. - (get_hypermetadata): Use %Zd for printfing size_t. - (diskfs_set_hypermetadata): Return EIO for incomplete writes. - Cast BUF when calling vm_deallocate. - - * dir.c (diskfs_direnter_hard): Initialize OLDSIZE to shut up gcc. - -Sat Sep 14 20:38:47 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * ufs.h (store, store_parsed, disk_image): New declarations. - - * pager.c (thread_function): Function removed. - (create_disk_pager): Create PAGER_BUCKET. - Use diskfs_start_disk_pager instead of disk_pager_setup. - (disk_image): New variable. - - * main.c (store, store_parsed, diskfs_disk_name): New variables. - (parse_opt): Propagate our input to the first child parser. - (diskfs_append_args): New function. - (diskfs_get_options): Function removed. - (startup_parents): Use DISKFS_STORE_STARTUP_ARGP instead of - DISKFS_STD_DEVICE_STARTUP_ARGP. - - * hyper.c (get_hypermetadata): Use DISKFS_DISK_NAME instead of - DISKFS_DEVICE_ARG. - * main.c (main): Likewise. - - * hyper.c (get_hypermetadata, diskfs_readonly_changed): Use - fields in STORE instead of DISKFS_DEVICE_* variables. - * inode.c (diskfs_S_file_get_storage_info): Likewise. - * pager.c (pager_report_extent): Likewise. - * main.c (main): Likewise. - * pager.c (pager_read_page, pager_write_page, pager_unlock_page): - Use store_{read,write} instead of diskfs_device_{read,write}_sync. - * hyper.c (diskfs_set_hypermetadata): Likewise. - * inode.c (diskfs_S_file_get_storage_info): Rewrite to use - libstore functions (still has NDADDR block limit, though). - -Thu Sep 12 16:36:19 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * Makefile (HURDLIBS): New variable. - (ufs.static ufs): Depend on $(library_deps) instead of long list - of libraries. - -Fri Sep 6 16:00:42 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * consts.c: Include <version.h>. - (diskfs_major_version, diskfs_minor_version, diskfs_edit_version): - Deleted variables. - (diskfs_server_version): New variable. - -Thu Aug 29 16:07:07 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set - ds->idx by looking at the size of the file. (IDX itself is no - longer at the end because of the change on Aug 16 1996.) - -Wed Aug 28 12:15:15 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dir.c (dirscanblock): Size dirents correctly when mallocing it. - (diskfs_direnter_hard): Be more careful when sizing or resizing - dirents. Correctly set to -1 all the new entries we create after - realloc call. - -Fri Aug 16 18:51:31 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * ufs.h (struct disknode): New member `dir_idx'. - * inode.c (diskfs_cached_lookup): Initialize DN->dir_idx. - * dir.c (diskfs_lookup_hard): After successful dirscanblock, - record index where we finished in DP->dn->dir_idx. Start searches - at that index. - -Mon Aug 12 13:43:46 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * hyper.c (diskfs_set_hypermetadata): Bother to return 0 at end of - function. - -Wed Aug 7 13:00:30 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * inode.c (diskfs_set_statfs): Compute st->f_blocks correctly; set - bsize to be fs_fsize, not fs_bsize. - - * hyper.c (diskfs_set_hypermetadata): Return an error as - appropriate. - - * inode.c (struct ufs_fhandle): Layout filehandle more like Unixy - NFSD. - (diskfs_S_file_getfh): Bother to clear unused parts of a - file handle so that they always compare equal. - -Tue Aug 6 12:19:38 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * inode.c: Include <fcntl.h>. - (struct ufs_fhandle): New type. - (diskfs_S_fsys_getfile, diskfs_S_file_getfh): New functions. - -Tue Jul 23 15:58:28 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (write_node, read_disknode): `struct timespec' now uses - a field prefix of `tv_'. - -Sat Jul 6 16:14:10 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (ufs_version): Variable removed. - -Sat Jul 6 12:45:36 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (read_disknode): Don't set allocsize based on st->size - for kludged symlinks. - - * sizes.c (diskfs_truncate): Call record_poke after truncating a - kludged symlink. - -Wed Jul 3 13:27:04 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * main.c: Include <argz.h>. - (startup_parents, runtime_parents): Declare const. - -Tue Jun 25 14:02:02 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (diskfs_get_options): Include `--compat=' in options. - -Mon Jun 24 16:59:12 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): Use diskfs_check_readonly instead of - diskfs_readonly. - (diskfs_dirempty): Likewise. - - * dir.c (diskfs_lookup_hard): Use diskfs_check_readonly instead of - diskfs_readonly. - (diskfs_dirempty): Likewise. - * inode.c (diskfs_cached_lookup): Likewise. - (read_symlink_hook): Likewise. - * sizes.c (diskfs_truncate): Call diskfs_check_readonly. - (diskfs_grow): Likewise. - * hyper.c (diskfs_set_hypermetadata): If CLEAN is not set, make - sure we clear the clean bit on disk. Always call sync_disk (with - appropriate WAIT). - (diskfs_readonly_changed): Don't do set_hypermetadata here. - (copy_sblock): Don't track clean state here. - - * pager.c (diskfs_shutdown_pager): Don't shutdown DISKPAGER ever, - just sync it instead. - -Sat Jun 22 17:45:34 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (diskfs_get_options): New function. - (options): Make const. - -Fri Jun 21 01:32:09 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (parse_opt): Handle runtime invalid selection of 4.2 mode. - Save select mode until we're done to correctly deal with external - errors at runtime. - (startup_parents, startup_argp, runtime_parents, runtime_argp): - New variables. - (main): Argp vars made global. - (argp_parents): diskfs_device_startup_argp --> - &diskfs_std_device_startup_argp. - -Sat Jun 15 13:57:27 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (options): New variable. - (parse_opt): New function. - (main): Parse ufs-specific options too. - <string.h>: New include. - -Fri May 10 09:29:03 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (diskfs_set_statfs): Fix one reference to old name of ST - member. - -Thu May 9 11:54:13 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (ufs.static ufs): s/ioserver/iohelp/g - * ufs.h: ioserver.h -> iohelp.h. - - * inode.c (diskfs_set_statfs): Use and fill in new statfs - structure. - -Mon May 6 14:23:54 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * main.c (ufs_version): Upgrade to 0.0. - -Fri May 3 09:15:33 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (block_extended): Rewrite code that moves pages - to be more efficient, and not deadlock too, using unlocked - pagein permission feature (read "hack"). Return value - now indicates whether we expect a sync. - (diskfs_grow): If a call to block_extended returns nonzero, - then sync the file before returning. - * pager.c (diskfs_get_filemap): Initialize - UPI->allow_unlocked_pagein and UPI->unlocked_pagein_length. - (unlocked_pagein_lock): New variable. - (find_address): New parameter `isread'; all callers changed. - If ISREAD and we are in the unlocked pagein region, don't - attempt to acquire NP->dn->allocptrlock. - * ufs.h (struct user_pager_info): New members - `allow_unlocked_pagein' and `unlocked_pagein_length'. - (unlocked_pagein_lock): New variable. - -Thu May 2 10:56:10 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (offer_data): Offer pages at ADDR each time through the - loop, not the same page over and over. - (block_extended): When moving data, sync in-core pager both before - reading from disk and after providing data to kernel. - (diskfs_grow): Always call block_extended or offer_data before - adjusting block pointer. - -Tue Apr 30 13:38:42 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (diskfs_grow): In last offer_data, don't offer a block - number as an address. - -Fri Apr 26 15:35:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (makemode): Now `servers'. - (targets): Renamed from `target'; now include ufs.static. - (ufs.static-LDFLAGS): Renamed from `LDFLAGS'. - (ufs.static): Depend on same things as `ufs'. - (include ../Makeconf): Must come before dependency information. - -Wed Apr 24 14:05:48 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.h (DIRECT_NAMLEN) [! LITTLE_ENDIAN]: Deal correctly with the - case where it was written on a little endian machine without the - extension. - (DIRECT_NAMLEN) [LITTLE_ENDIAN]: Deal with case correctly where it - was written without the extension on a big endian machine. - * dir.c (dirscanblock): Use read/write_disk_entry when reading or - writing fields from directory entries. - (diskfs_direnter_hard): Likewise. - (diskfs_dirremove_hard): Likewise. - (diskfs_dirrewrite_hard): Likewise. - (diskfs_get_directs): Likewise. - (diskfs_dirempty): Likewise. - (count_dirents): Likewise. - -Tue Apr 23 11:28:42 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_dirempty): node_update -> diskfs_node_update. - - * hyper.c (swab_sblock, swab_csums): New functions. - (get_hypermetadata): If this is a swapped filesystem, set swab_disk. - Also swap csum and sblock after reading them. - (diskfs_set_hypermetadata): If swab_disk, swap the csums back before - writing them. - (copy_sblock): If swab_disk, swap the sblock before writing it. - * ufs.h (swab_disk): New variable. - (swab_short, swab_long, swab_long_long): New functions. - (read_disk_entry, write_disk_entry): New macros. - * alloc.c (ffs_realloccg): Use read/write_disk_entry when - reading/writing on-disk inode fields. - * bmap.c (fetch_indir_spec): Likewise. - * inode.c (read_disknode): Likewise. - (write_node): Likewise. - (diskfs_set_translator): Likewise. - (diskfs_get_translator): Likewise. - (diskfs_S_file_get_storage_info): Likewise. - * sizes.c (diskfs_truncate): Likewise. - (diskfs_grow): Likewise. - * pager.c (pager_unlock_page): Likewise. - * bmap.c (fetch_indir_spec): Use read/write_disk_entry when - reading/writing on-disk indirect blocks. - * sizes.c (diskfs_truncate): Likewise. - (indir_release): Likewise. - (diskfs_grow): Likewise. - * pager.c (pager_unlock_page): Likewise. - * alloc.c: Include <string.h> - (ffs_blkpref): Use read_disk_entry when reading from BAP array. - (swab_cg, read_cg, release_cg): New functions. - (ffs_fragextend, ffs_alloccg, ffs_nodealloccg, ffs_blkfree, - diskfs_free_node): Use new cg access functions. - -Thu Apr 18 14:50:30 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (diskfs_grow): New variable `pagerpt'. - (offer_zeroes, block_extended): New functions. - (diskfs_grow): In initializing newly allocated data disk blocks with - zeroes, use less aggressive offer_zeroes instead of immediate - synchronous writes. After ffs_realloccg succeeds, use - block_extended to handle the magic. Get rid of old poke calls. - * alloc.c (ffs_realloccg): If we are allocating a new block, don't - actually free the old one here. - * sizes.c (diskfs_grow): New variable `pagerpt'. - (offer_zeroes, block_extended): New functions. - (diskfs_grow): In initializing newly allocated data disk blocks - with zeroes, use less aggressive offer_zeroes instead of immediate - synchronous writes. After ffs_realloccg succeeds, use - block_extended to handle the magic. Get rid of old poke calls. - -Tue Apr 16 15:20:07 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): Set atime appropriately, and sync - the new atime if we are running synchronously (!). - (diskfs_dirempty): Likewise. - (diskfs_direnter_hard): Set mtime appropriately. - (diskfs_dirremove_hard): Likewise. - (diskfs_dirrewrite_hard): Likewise. - - * inode.c (diskfs_write_disknode): Only do sync if WAIT is set. - -Thu Apr 4 16:39:22 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_cached_lookup): Intialize NP->cache_id *after* - NP exists. - -Wed Apr 3 16:03:51 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (diskfs_cached_lookup): Renamed from `iget'. All - callers changed. Initialize NP->cache_id. - -Fri Mar 29 16:52:31 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): Cast DI->di_shortlink to correct type - before adding a character count to it. - -Mon Mar 25 13:08:10 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_null_dirstat): New function. - -Fri Mar 22 23:43:53 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (read_symlink_hook): Only set NP's atime if !readonly. - -Wed Mar 20 14:36:31 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): Don't do initial or final permission - checking here. - * dir.c (diskfs_dirrewrite_hard): Renamed from diskfs_dirrewrite. - No longer call modification tracking routines. - (diskfs_dirremove_hard): Renamed from diskfs_dirremove. No longer call - modification tracking routines. - (diskfs_direnter_hard): Renamed from diskfs_direnter. No longer call - modification tracking routines. - (diskfs_lookup_hard): Renamed from diskfs_lookup. - -Mon Mar 18 19:50:41 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Pass new arg to argp_parse. - -Mon Mar 18 12:33:06 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pager.c (diskfs_max_user_pager_prot) [add_pager_max_prot]: - (a == b) ? 1 : 0 ====> (a == b). - -Fri Feb 23 15:27:05 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> - - * hyper.c (get_hypermetadata): Use diskfs_device_arg in unclean msgs. - -Wed Feb 21 05:57:12 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> - - * hyper.c: Implement proper handling of the filesystem `clean bit'. - (ufs_clean): New variable. - (get_hypermetadata): Set it from the fs_clean flag. If not clean, - complain and force read-only. Complain when ignoring COMPAT_BSD42. - (diskfs_set_hypermetadata): Set the clean flag in the superblock - when CLEAN and fs was clean to start with. - (copy_sblock): Remove bogus clean flag frobnication. - -Fri Feb 16 17:05:36 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Check error return from diskfs_init_diskfs. - -Sat Jan 6 11:50:14 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * ufs.h (diskpager, diskpagerport, disk_image): Variables removed. - Include <hurd/diskfs-pager.h> instead. - (sync_disk_blocks): Use `disk_pager' in place of `diskpager->p'. - * pager.c (diskfs_shutdown_pager, diskfs_sync_everything): Use - `disk_pager' in place of `diskpager->p'. - (create_disk_pager): Rewritten using disk_pager_setup. - * pokeloc.c (sync_disk): Use `disk_pager' in place of `diskpager->p'. - * sizes.c (indir_release): Likewise. - * main.c (diskfs_reload_global_state): Likewise. - -Thu Jan 4 19:10:11 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (main): Don't map disk image here; create_disk_pager now - does it. - - * hyper.c (get_hypermetadata, copy_sblock): Don't put - diskfs_catch_exception () inside assert, bonehead! Use - assert_perror on a variable of its result. - -Mon Jan 1 16:38:14 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pager.c (pager_unlock_page): When allocating block in direct - array, clear it synchronously just like we do when it goes in the - indirect array. - -Thu Nov 9 14:01:30 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (struct dirstat): New member `nbytes'. - (dirscanblock): If DS->type is COMPRESS, still look - for TAKE/SHRINK possibilities. Also, if it's COMPRESS, - still look to see if the current block can be compressed - with fewer byte copies. - -Sun Nov 5 02:08:38 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Add flags arg to diskfs_startup_diskfs call. - -Sat Nov 4 20:01:58 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_S_file_get_storage_info): Add FLAGS argument. - -Thu Oct 19 12:50:11 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * pager.c (diskfs_max_user_pager_prot): Return what we discovered, - instead of 1. - - * dir.c (diskfs_lookup, diskfs_dirempty): Give diskfs_get_filemap - a protection arg. - * sizes.c (diskfs_truncate, diskfs_grow): Ditto. - - * hyper.c (diskfs_readonly_changed): Give the 2nd arg to - vm_protect an appropiate type. - - * pager.c (diskfs_max_user_pager_prot): Stop iterating early if poss. - -Wed Oct 18 16:28:42 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * ufs.h (struct user_pager_info): Add max_prot field. - * pager.c (diskfs_get_filemap): Add PROT parameter, & use it. - (diskfs_pager_users): Split out block_caching & enable_caching. - (block_caching, enable_caching): New function. - (diskfs_max_user_pager_prot): New function. - - * main.c (main): Always include VM_PROT_WRITE in max prot. - * hyper.c (diskfs_readonly_changed): Change the protection of - DISK_IMAGE to reflect the new state. Clear SBLOCK_DIRTY if readonly. - - * inode.c (read_disknode): Bother to set the allocsize field. - - * ufs.h (struct rwlock): Structure deleted. - (rwlock_init, rwlock_reader_unlock, rwlock_reader_lock, - rwlock_writer_lock, rwlock_writer_unlock): Functions deleted. - - -Tue Oct 17 14:49:43 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_node_reload): New function. - (iget): Move allocsize setting into read_disknode. - * pager.c (flush_node_pager): New function. - * ufs.h (zeroblock, sblock, csum): Declare extern. - (flush_node_pager, flush_pokes): New declarations. - * pokeloc.c (flush_pokes): New function. - * hyper.c (diskfs_readonly_changed): New function. - (get_hypermetadata): Move compat_mode futzing & disk size - validation here from main. - (zeroblock, sblock, csum): Define (were common). - (get_hypermetadata): Only allocate SBLOCK if not already done. - Deallocate any old ZEROBLOCK and CSUM storage. - (diskfs_readonly_changed): New function. - * main.c (main): Move stuff into get_hypermetadata. - Writable init code moved to diskfs_readonly_changed. - (diskfs_reload_global_state): New function. - -Fri Oct 13 15:03:37 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Use new handy diskfs routines and get rid of - tons of junk. Main should be almost all ufs-specific now. - (USAGE, usage, SHORT_OPTS, long_opts, parse_opt, trans_parse_arg): RIP. - (printf_lock): Initialize. - -Thu Oct 12 18:48:04 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * pager.c (pager_unlock_page, pager_write_page, pager_read_page): - Use diskfs_device_{read,write}_sync instead of dev_{read,write}_sync. - * hyper.c (diskfs_set_hypermetadata): Ditto. - * sizes.c (diskfs_grow): Ditto. - * pager.c (pager_report_extent): Calculate the pager size. - * ufs.h (dev_read_sync, dev_write_sync, dev_write, diskpagersize): - Decls removed. - - * Makefile (SRCS): Remove devio.c. - * ufs.h (ufs_device, ufs_device_name): Variables removed. - * inode.c (diskfs_S_file_get_storage_info): Use DISKFS_DEVICE - instead of UFS_DEVICE, and DISKFS_DEVICE_NAME instead of - UFS_DEVICE_NAME. - -Sat Oct 7 20:47:56 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (diskfs_init_completed): Function deleted (now in libdiskfs). - (thread_cancel): Function deleted. - -Fri Oct 6 17:30:23 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_S_file_get_storage_info): Change type of - ADDRESSES to off_t **, and add the BLOCK_SIZE parameter. - -Wed Oct 4 17:21:33 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_set_statfs): fsys_stb_bsize -> fsys_stb_iosize. - fsys_stb_fsize -> fsys_stb_bsize. - - * main.c (parse_opt): Rearrange slightly. - -Tue Sep 26 11:54:35 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c: Include <netinet/in.h>. - (diskfs_S_file_get_storage_info): New function. - * main.c (main): Delete var `devname'. Use `ufs_device_name' - throughout instead. - * ufs.h (ufs_device_name): New var. - -Fri Sep 22 13:22:42 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * hyper.c (get_hypermetadata): Use %Zd format for result of sizeof. - -Tue Sep 19 13:41:46 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (LDFLAGS): New variable. - -Wed Sep 13 12:30:23 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * dir.c (diskfs_lookup): Don't attempt to lock NP if NPP is not - set. Don't even set NP if NPP is not set; use INUM as "lookup - succeeded flag" instead. Lookups for REMOVE and RENAME now *must* - set NPP. - -Wed Sep 6 11:01:50 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * pager.c (diskfs_pager_users): Ignore the disk pager when seeing - if there are any active pagers. - -Mon Aug 28 17:07:36 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (ufs): Depend on ../libshouldbeinlibc/libshouldbeinlibc.a. - -Fri Aug 25 17:14:09 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): When freeing direct blocks mentioned - in a single indirect block, or single indirect blocks mentioned in - a double, only call the free routine (ffs_blkfree or - indir_release, respectively) if the block is actually allocated. - -Wed Aug 23 12:24:07 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (ufs): Add explicit dependencies. - (HURDLIBS, LDFLAGS, REMHDRS): Removed. - Rules associated with ../lib removed. - -Fri Jul 21 17:48:12 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * pager.c (diskfs_get_filemap): Drop initial reference created by - pager_create. - - * pager.c (diskfs_get_filemap): Avoid race with simultaneous - termination by looping until we win. - (pager_clear_user_data): Only clear UPI->np->dn->fileinfo if it - still points to us. - -Mon Jul 17 14:35:25 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * pager.c (thread_function): Don't have any global timeout here; - we don't use it anyhow. - -Thu Jul 6 15:42:52 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile: Removed dependencies that are now automatically - generated. - -Mon Jun 26 20:17:42 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c: Include <unistd.h>. - (diskfs_pager_users): New function. - -Thu Jun 22 11:41:04 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c (thread_function): Move thread_function to be non-local, - of course, because it needs to live even after create_disk_pager - returns. - - * main.c (thread_cancel): New function (HACK). - - * Makefile (HURDLIBS): Add libihash. - - * main.c (main): Have main thread exit when done instead of - calling a diskfs function. - -Wed Jun 21 12:20:01 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * ufs.h (user_pager_info): Removed members next and prevp. - * pager.c (pager_clear_user_data): Don't maintain pager linked - list. - (diskfs_get_filemap): Don't maintain pager linked list. - (pager_dropweak): New function. - (pager_traverse): Delete function. - (diskfs_shutdown_pager): Use ports_bucket_iterate instead of - pager_traverse. - (diskfs_sync_everything): Likewise. - - * pager.c (pager_bucket): New variable. - (create_disk_pager): Provide pager_bucket in call to pager_create. - (diskfs_get_filemap): Likewise. - (diskfs_file_update): Use ports reference calls directly instead - of pager wrappers. - (drop_pager_softrefs): Likewise. - (allow_pager_softrefs): Likewise. - (pager_traverse): Likewise. - (create_disk_pager): Initialize pager_bucket here and fork off - service thread for pager ports. - - * sizes.c (diskfs_truncate): Likewise. - - * dir.c (diskfs_lookup): Provide initialization for BUFLEN. - (diskfs_direnter): Move assignment out of if test. - -Tue Jun 20 11:48:06 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * sizes.c (diskfs_grow): Provide initialization of POKE_OFF. - * alloc.c (ffs_realloccg): Remove assignment from if tests. - * sizes.c (diskfs_truncate): Likewise. - * bmap.c (fetch_indir_spec): Likewise. - -Mon Jun 19 21:17:21 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * inode.c (diskfs_node_iterate): New function. - (write_all_disknodes): Use it. - -Wed Jun 14 16:18:55 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * inode.c (diskfs_get_translator): Conform to new memory usage - semantic. - -Sat May 20 00:17:30 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * main.c (trans_parse_args): Use options_parse & - diskfs_standard_startup_options to parse our translator options. - (usage): New function. - (parse_opt): New function. - - * Makefile (CPPFLAGS): Add -I../lib, to get include lib include files, - and $(CPPFLAGS-$(notdir $<)) to get file-specific cpp options. - Add a vpath for %.c to ../lib, so we can use source files from there. - -Mon May 15 13:14:48 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c (pager_clear_user_data): Doc fix. - -Sat May 13 05:04:11 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (OBJS): Remove exec_server_image.o. - (exec_server_image.o): Rule removed. - -Mon May 8 08:43:43 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * dir.c (diskfs_lookup): When looping back to try_again: because - we're looking up "..", be sure and trash the mapping we made of - the directory's pager -- otherwise the reference to the pager - never gets dropped and we can never free the node. - - * dir.c (diskfs_lookup): ds->type was being compared to LOOKING, which - value it can never have. Compare ds->stat against LOOKING instead. - - * pager.c (pager_clear_user_data): Don't die when called on the - disk pager. - - * inode.c (write_all_disknodes): Fix typo `alloc' --> `alloca'. - -Tue May 2 11:59:09 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c (pager_clear_user_data): Acquire pagerlistlock around - modifications to UPI->next/prevp list structure. - -Fri Apr 28 19:02:05 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (write_all_disknodes): We have to really lock the nodes - around the calls to diskfs_set_node_times and write_node; this in - turn forces us to have real refereces. - -Thu Apr 13 16:36:57 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * main.c (main): Don't abort if a std file descriptor is already open. - -Tue Apr 4 20:08:25 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_set_translator): When freeing passive - translator, account for blocks freed in NP->dn_stat.st_blocks. - -Fri Mar 31 13:43:27 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): Don't acquire writer lock on - NP->dn->allocptrlock until after forcing delayed copies through; - otherwise the pageins will deadlock attempting to get a reader - lock to service them. This is safe, because we only need - NP->allocsize here, and that can't change as long as we hold - NP->lock. - -Mon Mar 20 13:58:44 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * consts.c (diskfs_synchronous): New variable. - -Fri Mar 17 14:31:04 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * alloc.c (ffs_clusteracct): Make static. - (alloc_sync): New function. - (ffs_alloc): Call alloc_sync. - (ffs_realloccg): Likewise. - (diskfs_alloc_node): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - -Sat Jan 28 14:59:26 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (OBJS): Remove reference to libc's devstream.o. - -Fri Nov 11 11:45:38 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * hyper.c (diskfs_set_hypermetadata): Always use dev_write_sync to - avoid device_write bug that says you can't modify the buffer until - device_write returns. Also remember to deallocate BUF. - -Thu Nov 10 13:27:09 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * main.c (main): Issue decent prompt. - - * hyper.c (diskfs_set_hypermetadata): Copy CSUM into a - page-aligned page-sized buffer for disk write to avoid inane - kernel bug. - -Wed Nov 9 05:43:14 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * main.c (main): Behave more reasonably if we can't open DEVNAME. - -Tue Nov 8 00:03:20 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * pager.c (pager_write_page): Use %p for printing PAGER. - - * ufs.h: Declare copy_sblock. - -Wed Nov 2 16:06:10 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * hyper.c (copy_sblock): Don't copy csum here. - (diskfs_set_hypermetadata): Write csum directly to disk here. - -Thu Oct 27 20:58:08 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.c (diskfs_lookup): diskfs_get_filemap returns a send right, - so don't create an additional one here. - (diskfs_dirempty): Likewise. - * sizes.c (diskfs_truncate): Likewise. - (diskfs_grow): Likewise. - -Tue Oct 25 12:49:41 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * hyper.c (copy_sblock): Call record_poke for csum and superblock - after modifying them. - - * pager.c (diskfs_shutdown_pager): Call copy_sblock. - (diskfs_sync_everything): Likewise. - - * alloc.c (ffs_fragextend): Call record_poke for CG after - modifying it. Also set CSUM_DIRTY and SBLOCK_DIRTY. - (ffs_alloccg): Likewise. - (ffs_alloccgblk): Likewise. - (ffs_nodealloccg): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - -Fri Oct 7 01:32:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (diskfs_init_completed): Don't call _hurd_proc_init. - (saved_argv): Variable removed. - (main): Don't set saved_argv. Pass ARGV to diskfs_start_bootstrap. - -Wed Oct 5 22:18:46 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (read_disknode): If we are the bootstrap filesystem, - then getpid changes once proc starts up. So only call getpid - once, thus not allowing st_dev values to mysteriously change. - -Wed Oct 5 12:56:53 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * alloc.c (diskfs_alloc_node): Abort if free inode has - translator attached. - -Tue Oct 4 18:33:35 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * pager.c (pager_unlock_page): Call diskfs_catch_exception. - -Tue Oct 4 00:16:04 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_lost_hardrefs): Comment out body. - * ufs.h (node2pagelock): New variable. - * pager.c (node2pagelock): Initialize. - (diskfs_get_filemap): Don't let node hold a reference to the pager. - (pager_clear_user_data): Acquire node2pagelock and clear - the node's reference to the pager. - (diskfs_file_update): Hold node2pagelock for reference - of NP->dn->fileinfo. - (drop_pager_softrefs): Likewise. - (allow_pager_softrefs): Likewise. - (diskfs_get_filemap): Likewise. - * sizes.c (diskfs_truncate): Likewise. - - * Makefile (SRCS): Added pokeloc.c. - -Mon Oct 3 15:03:38 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): Rewritten. - - * bmap.c (fetch_indir_spec): Initialize OFFSET values to -2, - meaning that the entry is not needed. If LBN is negative, - then don't set values for the data block. - - * inode.c (write_node): Call record_poke after writing - dinode. - (create_symlink_hook): Likewise. - (diskfs_set_translator): Likewise. - * pager.c (pager_unlock_page): Likewise. - * sizes.c (diskfs_truncate): Likewise. - * pager.c (pager_unlock_page): Call record_poke after writing - indirect block. - * sizes.c (diskfs_grow): Likewise. - (diskfs_grow): Likewise. - * pager.c (diskfs_sync_everything) [sync_one]: If this is the - disk pager, call sync_disk instead. - * pokeloc.c: New file. - -Fri Sep 30 11:25:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.h: Delete DT_* definitions; they are now in <dirent.h>. - * dir.c (diskfs_get_directs): Set USERP->d_type as DT_UNKNOWN. - When the bugs in the type fields are fixed (dealing with - multiple links and mode changes) then this can actually return - the value. - -Thu Sep 29 17:16:58 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (main): Test getpid()>0 to decide we are a normal - translator instead of the boot fs. Fetch bootstrap port after - possibly calling diskfs_parse_bootargs, not before. - -Tue Sep 27 15:24:58 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * sizes.c (diskfs_grow) [computation of newallocsize]: Last block - number is one less than the total number of blocks. - -Tue Sep 27 11:58:44 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * bmap.c (fetch_indir_spec): Single indirect block pointer is - in the INDIR_SINGLE slot, not the INDIR_DOUBLE slot. - -Mon Sep 26 20:47:30 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (SRCS): Added bmap.c. - - * main.c (main): Don't call pager_init. - - * inode.c (diskfs_get_translator): Repair to read translator - correctly. - - * sizes.c (diskfs_grow): Compute block numbers in a more clean - (and confidently correct) fashion. - (diskfs_truncate): Set NP->allocsize from a properly rounded - value. - -Mon Sep 26 12:50:38 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (diskfs_lost_hardrefs): "Know" that a pager starts - with a portinfo; we don't actually have access to the pager - struct here. - -Fri Sep 23 14:21:55 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - [ Continuing yesterday's changes. ] - * ufs.h (struct dirty_indir): New type. - (struct disknode): New member `dirty'. - * inode.c (iget): Initialize DN->dirty. - * bmap.c (mark_indir_dirty): New function. - * pager.c (pager_unlock_page): Call mark_indir_dirty before - writing into indirect blocks. - (diskfs_file_update): Sync indirect blocks here. - (pager_traverse): Simplify; do FILE_DATA and diskpager. - (pager_init): Removed function. - (create_disk_pager): New function. - * sizes.c: Completely rewritten. - * main.c (main): Spawn first thread sooner so we can - map and look at the disk image. - * hyper.c (get_hypermetadata): Moved firewall asserts - here from pager_init. - -Thu Sep 22 11:28:46 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - [This long series of changes deletes the DINODE, CG, SINDIR, - and DINDIR pagers and adds a new pager type DISK.] - * ufs.h (struct disknode) Removed DINLOCK, SINLOCK, and - SININFO members. New member ALLOCPTRLOCK renamed from DATALOCK. - Removed SINLOC, DINLOC, SINLOCLEN, and DINLOCLEN. - (struct user_pager_info) [enum pager_type]: Removed types - DINODE, CG, SINDIR and DINDIR; added type DISK. - (dinpager, dinodepager, cgpager): Deleted vars. - (diskpager): New var. - (dinmaplock, sinmaplock, pagernplock): Deleted vars. - (sblock_dirty, csum_dirty, cgs, dinodes): Deleted vars. - (fsaddr): New macro. - (dino, indir_block, cg_locate): New inline functions. - (sync_disk_blocks, sync_dinode): New inline functions. - (struct iblock_spec): New type. - * pager.c (dinport, dinodeport, cgport, sinlist): Deleted vars. - (filepagerlist): Renamed from filelist. - (pagernplock): Deleted variable. - (find_address): Removed switch; support only DISK and FILE_DATA. - (pager_report_extent): Likewise. - (pager_unlock_page): Removed switch. Return without comment for - DISK; allocate indirect blocks as necessary right here for - FILE_DATA. - (sin_map, sin_remap, sin_unmap, din_map, din_unmap): Deleted - functions. - (indir_alloc, sync_dinode): Deleted functions. - (enqueue_pager, dequeue_pager): Deleted functions. - (diskfs_file_update): No longer lock pagernplock; nothing - to do with sininfo. - (drop_pager_softrefs): Likewise. - (allow_pager_softrefs): Likewise. - (diskfs_get_filemap): Put pager on filepagerlist right here - instead of through pager_enqueue. - (pager_clear_user_data): Likewise, mutatis mutandis. - * main.c (main): Call create_disk_pager and then map the - entire disk into disk_image. - * hyper.c (get_hypermetadata): Use bcopy instead of dev_read_sync. - (diskfs_set_hypermetadata): NOP out function. - (copy_sblock): New function, substance of code is from old - diskfs_set_hypermetadata. - * inode.c (iget): Don't initialize deleted disknode fields. - (diskfs_node_norefs): Don't verify that deleted disknode - fields are not set. - (read_disknode): Get dinode from DINO, not DINODES array. - (write_node): Likewise. - (create_symlink_hook): Likewise. - (read_symlink_hook): Likewise. - (diskfs_set_translator): Likewise. - (diskfs_get_translator): Likewise. - (diskfs_node_translated): Likewise. - * alloc.c (ffs_realloccg): Likewise. - (ffs_fragextend): Use cg_locate instead of cgs array. - (ffs_alloccg): Likewise. - (ffs_nodealloccg): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - * inode.c (diskfs_set_translator): Use bcopy and sync_disk_blocks - instead of dev_write_sync. - (diskfs_get_translator): Likewise, mutatis mutandis. - (read_disknode): Initialize NP->istranslated. - (diskfs_set_translator): Set/clear NP->istranslated as appropriate. - (diskfs_node_translated): Removed function. - * bmap.c: New file. - - [This improves the RWLOCK mechanism and makes it more - orthogonal. It should probably be moved into a library.] - * ufs.h (struct rwlock): Added MASTER and WAKEUP members. - (struct disknode): Removed RWLOCK_MASTER and RWLOCK_WAKEUP - fields. - (rwlock_reader_lock): Ommitted arg DN; use new MASTER and WAKEUP - members inside LOCK instead. - (rwlock_writer_lock): Likewise. - (rwlock_reader_unlock): Likewise. - (rwlock_init): Initialize new MASTER and WAKEUP fields. - * inode.c (iget): Don't deal with RWLOCK_MASTER and RWLOCK_WAKEUP. - * pager.c (find_address): Deleted arg DNP. Only pass one - arg to rwlock functions. - (pager_read_page): Deleted var DN; only pass one arg to rwlock - functions. - (pager_write_page): Likewise. - -Wed Sep 21 00:26:25 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * pager.c (allow_pager_softrefs): Unlock PAGERNPLOCK when - we're done with it. - (sin_map): Hold PAGERNPLOCK all the way until we're done - with the sininfo pointer. - (pagernplock): No longer static. - * ufs.h (pagernplock): Declare here. - - * sizes.c (diskfs_grow): Don't call diskfs_file_update here. - This was done to prevent too much dirty data from accumulating - and then overwhelming the pager later. But that's really the - pager's responsibility. - - * ufs.h (struct disknode): New members `dinloclen' and `sinloclen'. - * inode.c (iget): Initialize DN->dinloclen and DN->sinloclen. - (diskfs_node_norefs): Verify that DN->dinloclen and DN->sinloclen - are both zero. - * pager.c (find_address) [SINDIR]: Verify that reference is - within bounds of NP->dn->dinloc. - (pager_unlock_page) [SINDIR]: Likewise. - (din_map): Set NP->dn->dinloclen. - (din_unmap): Clear NP->dn->dinloclen. - (find_address) [FILE_DATA]: Verify that reference is within - bounds of NP->dn->sinloc. - (pager_unlock_page) [FILE_DATE]: Likewise. - (sin_map): Set NP->dn->sinloclen. - (sin_remap): Reset NP->dn->sinloclen. - (sin_unmap): Clean NP->dn->sinloclen. - - * pager.c (pager_write_page): Flush stdout after printf. - (pager_unlock_page) [FILE_DATA]: Likewise. - - * sizes.c (diskfs_truncate): In all references to sinloc and - dinloc arrays, verify that references are within allocated bounds. - (diskfs_grow): Likewise. - (sindir_drop): Likewise. - - * pager.c: Create new mapping with extent NEWSIZE, not SIZE (which - was the old size of the mapping). - -Tue Sep 20 15:51:35 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * pager.c (pager_report_extent) [SINDIR]: Remove erroneous extra - division by block size. - (sin_remap): Likewise. - -Mon Sep 19 17:34:11 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (create_symlink_hook): Write assert test correctly. - - * dir.c (diskfs_direnter) [EXTEND]: Reference file size only - *once*; don't rely on the behavior if diskfs_grow vis a vis - file size. - -Fri Sep 16 10:29:42 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.c (dirscanblock): Compute offset correctly for mangled - entry notice. - - * dir.c (diskfs_direnter) [EXTEND]: Reference file size only - once before calling diskfs_grow in case diskfs_grow actually - increases the size. - - * inode.c (diskfs_set_statfs): Set fsid from getpid. - (read_disknode): Likewise. - - * dir.h (struct directory_entry): Renamed from struct direct. - * dir.c: All uses of struct direct changed to use - struct directory_entry. - (diskfs_get_directs): New var `userp'. Copy from *ENTRYP into - it (set at DATAP) more cleanly. - -Mon Sep 12 11:30:48 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * hyper.c (diskfs_set_hypermetadata): Don't frob clean and dirty - bits if we are readonly. - -Sat Sep 10 11:41:06 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (main): When started up as a passive translator, - open fds 0, 1, and 2 on /dev/console for debugging messages. - Call diskfs_init_diskfs with no args; after warp_root, call - diskfs_startup_diskfs on BOOTSTRAP. Compare BOOTSTRAP to - MACH_PORT_NULL instead of zero. - -Fri Sep 9 13:02:33 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * main.c (trans_parse_args): Fix and enable. - -Tue Sep 6 11:29:55 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (iget): Remove old assert test that checked for bad - inode block allocations. - -Thu Sep 1 11:39:12 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * tables.c: Don't include "ufs.h"; include <sys/types.h>. Then - this file can be used unmodified by fsck. - -Tue Aug 30 13:36:37 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_set_translator): ffs_blkfree doesn't have - a return value. - -Mon Aug 29 12:49:17 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_set_translator): If NAMELEN is zero, then - make the node have no translator. - -Fri Aug 26 12:28:20 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (read_disknode): 4.4 fsck sometimes sets the author - field to -1 to mean "ignore old uid location"; take that to mean - "author == uid". - (diskfs_set_translator): If we are allocating a new block for - the translator, then account for it in st_blocks. - -Thu Aug 18 12:41:12 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (HURDLIBS): Use short version. - - * alloc.c (diskfs_alloc_node): Bother to set *NPP before - returning. - -Tue Aug 16 10:48:04 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (LDFLAGS): New variable. - -Fri Aug 5 15:51:09 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.c (diskfs_direnter) [EXTEND]: Crash if the entry won't - fit in the new block. - (diskfs_lookup): Return ENAMETOOLONG if the name is bigger than - MAXNAMLEN. - - * dir.c (diskfs_get_directs): Set USERD->d_reclen correctly. - -Fri Jul 22 15:12:35 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile: Rewritten in accord with new scheme. - -Wed Jul 20 13:28:38 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * main.c (main): Don't set diskfs_dotdot_file. - -Tue Jul 19 21:51:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * ufs.h: Removed defns of u_quad_t, quad_t; now in <sys/types.h>. - Removed defn of struct timespec; now in <sys/time.h>. - -Tue Jul 19 12:47:31 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * main.c (main): Deleted var `diskfs_dotdot_file'. - (trans_parse_args): Don't set diskfs_dotdot_file; don't expect - dotdot from fsys_getroot. - - * Makefile (LDFLAGS): Moved to rule for `ufs' and commented out. - (ufs): Don't use variable $(link) anymore. - -Mon Jul 18 14:55:17 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_get_directs): Return data to user in old format. - Add new code for new format, maintaining compatibility correctly, - but comment it out until the library is ready. - - * hyper.c (diskfs_set_hypermetadata): If we presumed to - set new values of fs_maxfilesize, fs_qbmask, and fs_qfmask, - then restore the originals before writing out the superblock. - - * pager.c (diskfs_get_filemap): Test should be S_ISLNK, not - S_ISSOCK. - - * hyper.c (get_hypermetadata): Set new constants in filesystems - which don't have them yet. - (get_hypermetadata): Cast MAXSYMLINKLEN to long to avoid - converting sblock->fs_maxsymlinklen into an unsigned. - - * subr.c (scanc, skipc): New functions. - (ffs_setblock): Use assert instead of panic. - - * inode.c (read_disknode): Set old stat structure until the header - file gets changed. - -Fri Jul 15 12:07:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c: Include <string.h> for bzero. - * fs.h (blksize): Comment out dblksize macro. In blksize - macro, use NP->allocsize instead of IP->i_size. - - * dinode.h (INDIR_SINGLE, INDIR_DOUBLE, INDIR_TRIPLE): New macros. - - * inode.c (read_disknode, write_node): Use new stat and dinode - fields for times. - - * ufs.h: Change `nextgennumber' to be `u_long' instead of int. - Change prototypes of some alloc.c functions. - * alloc.c (ffs_alloc): Declare to return error_t. - (ffs_realloccg): Likewise. - (ffs_hashalloc, ffs_alloccg, ffs_fragextend, ffs_alloccg, - ffs_dirpref, ffs_nodealloccg, ffs_allccgblk, ffs_mapsearch, - ffs_clusteracct): Provide forward declarations. - (ffs_realloccg): Use printf instead of log. - Make BPREF volatile for setjmp safety. - (diskfs_alloc_node): Use diskfs global variable instead of TIME. - (ffs_nodealloccg): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - (ffs_blkfree, ffs_clusteracct): Declare as void. - (ffs_alloccg, ffs_nodealloccg): Declare as u_long. - - * ufs.h: Change prototypes of some subr.c functions. - * subr.c (ffs_isblock): Use assert instead of panic. - (ffs_clrblock): Likewise. - - * hyper.c: Include "dinode.h". - - * dinode.h (LINK_MAX): New macro, from BSD sys/sys/syslimits.h. - * fs.h (MAXBSIZE, MAXFRAG): New macros, from BSD sys/sys/param.h. - - * hyper.c (get_hypermetadata): Provide first arg in call to - fsbtodb. - (diskfs_set_hypermetadata): Likewise. - * inode.c (diskfs_set_translator): Likewise. - (diskfs_get_translator): Likewise. - * pager.c (find_address): Likewise. - (indir_alloc): Likewise. - * inode.c (iget): Provide first arg in call to lblkno. - * sizes.c (diskfs_truncate): Likewise. - * pager.c (find_address): Likewise. - * sizes.c (diskfs_grow): Likewise. - * inode.c (iget): Provide first arg in call to fragroundup. - * sizes.c (diskfs_trucate): Likewise. - * sizes.c (diskfs_grow): Likewise. - * inode.c (iget): Provide first arg in call to blkroundup. - * pager.c (pager_unlock_page): Likewise. - * sizes.c (diskfs_truncate): Likewise. - * sizes.c (diskfs_grow): Likewise. - * pager.c (find_address): Provide first arg in call to cgtod. - * pager.c (find_address): Provide first arg in call to cgimin. - * pager.c (find_address): Provide first arg in call to blktofrags. - * pager.c (find_address): Provide first arg in call to blkoff. - * sizes.c (diskfs_truncate): Likewise. - * sizes.c (diskfs_grow): Likewise. - * sizes.c (diskfs_truncate): Provide first arg in call to blksize. - * sizes.c (diskfs_grow): Likewise. - * sizes.c (diskfs_truncate): Provide first arg in call to numfrags. - - * ufs.h: Added temporary declarations of `u_quad_t', `quad_t', and - `struct timespec'. - - * pager.c (diskfs_get_filemap): Make sure that this is - a kind of node that can be validly read. - - * inode.c (create_symlink_hook): Renamed from symlink_hook. - (read_symlink_hook): New function. - (diskfs_read_symlink_hook): Initialize. - -Thu Jul 14 12:23:45 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * alloc.c: New from 4.4 BSD; BSD version `8.8 2/21/94'. - Remove old includes; include "ufs.h", "fs.h", "dinode.h", - and <stdio.h>. Replace panics with asserts and comment out - uprintfs. Use prototypes throughout. Replace calls - to ffs_fserr with printf. - (alloclock): New variable. - (ffs_alloc): Variable struct inode *IP is now struct node *NP; - refer to it appropriately. Initialize FS to sblock. - Lock alloclock around actual allocation steps. Reverse order - of BNP and CRED arguments; declare CRED as a protid and use - accordingly. Permit CRED to be null. - (ffs_realloccg): Variable struct inode *IP is now struct node *NP; - refer to it accordingly. Comment out U*x buffer management code. - Lock alloclock around actual allocation steps. Initialize FS - from sblock. Declare CRED as a protid and use it accordingly. - Change BUF arg to PBN (physical block number); return new block - there. - (ffs_reallocblks): Comment out. - (diskfs_alloc_node): Renamed from ialloc. Initialize FS from - sblock. Use calling sequence from <hurd/diskfs.h>. Acquire - alloclock aroud actual allocation steps. Deleted vars - `pip', `pvp' (use dir instead). Use iget instead of VFS_VGET. - Var struct inode *IP now struct node *NP. Lock gennumberlock - around frobbing of nextgennumber. - (ffs_blkpref): Arg struct inode *ip is now struct node *np; - refer to it accordingly. Initialize FS to sblock. Lock - alloclock during actual work. Use csum instead of fs_cs macro. - (ffs_hashalloc): Arg struct inode *IP is now struct node *NP; - use it accordingly. Initialize FS from sblock. - (ffs_fragextend): Arg struct inode *IP is now struct node *NP; - use it accordingly. Initialize FS from sblock. Initialize - CGP from cgs array; don't use bread. Comment out calls to brelse - and bdwrite. Set CGP->time from diskfs global var. Use csum - instead of fs_cs macro. - (ffs_alloccg): Arg struct inode *IP is now struct node *NP. - Initialize FS from sblock. Initialize CGP from cgs array; - don't use bread. Comment out calls to brelse and bdwrite. - Set CGP->time from diskfs global var. Use csum instead of - fs_cs macro. - (ffs_nodealloccg): Arg struct inode *IP is now struct node *NP. - Initialize FS from sblock. Initialize CGP from cgs array; - don't use bread. Comment out calls to brelse and bdwrite. Use - csum instead of fs_cs macro. - (ffs_blkfree): Arg struct inode *IP is now struct node *NP. - Initialize FS from sblock. Initialize CGP from cgs array; - don't use bread. Comment out calls to brelse and bdwrite. Use - csum instead of fs_cs macro. - (diskfs_free_node): Renamed from ffs_vfree. Use calling - sequence from <hurd/diskfs.h>. Initialize FS from sblock. - Deleted vars pip,pvp (use NP instead). Initialize CGP from - cgs array; don't use bread. Comment out calls to brelse and - bdwrite. Use csum instead of fs_cs macro. - (ffs_fserr): Commented out. - (ffs_dirpref): Use csum instead of fs_cs macro. - - * ufs.h (ffs_alloc): Renamed from alloc; all callers changed. - (ffs_blkfree): New arg NP; renamed from blkfree; all callers changed. - (ffs_blkpref): Renamed from blkpref; all callers changed. - (ffs_realloocg): Rename from realloccg; all callers changed. - - * fs.h: New from 4.4 BSD; BSD version `8.7 4/19/94'. - (fs_cs): Don't use fs_csp; use global csum instead. - - * subr.c: New from 4.4 BSD; BSD version `8.2 9/21/93'. - Remove old includes. Include "ufs.h" and "fs.h". - (ffs_blkatoff, ffs_checkoverlap): Comment out. - - * tables.c: New from 4.4 BSD; BSD version `8.1 6/11/93'. - Don't include <param.h>; do include "ufs.h" and "fs.h". - - * dinode.h: New from 4.4 BSD; BSD version `8.3 1/21/94'. - Remove oldids/inum union; replace with author. - Renamed di_mode to be di_model; allocated di_modeh from spare. - Allocate di_trans from spare. - (di_inumber): Remove macro. - * inode.c (read_disknode): Fetch uid and gid from new (long) - fields in dinode unless we are the old inode format, in which - case fetch them from the old fields. - (write_node): Only set new uid and gid fields if we are not - COMPAT_BSD4. Set old fields if the superblock says to. - (symlink_hook): New function. - (diskfs_create_symlink_hook): Initialize. - * sizes.c (diskfs_truncate): Deal with truncation of short - symlink properly. - - * dir.h: New from 4.4 BSD; BSD version `8.2 1/21/94'. - Substitute our version of DIRSIZ which uses the namelen. - Comment out declarations of struct dirtemplate and struct - odirtemplate. - (DIRECT_TYPE, DIRECT_NAMLEN): New macros. - * ufs.h (direct_symlink_extension): New variable. - * hyper.c (get_hypermetadata): Set direct_symlink_extension. - * dir.c (dirscanblock): Use DIRECT_NAMLEN instead of d_namlen. - (diskfs_direnter): Likewise. - (diskfs_dirempty): Likewise. - (diskfs_get_directs): Likewise. - (diskfs_direnter): Set d_type field of new slot if - direct_symlink_extension is set. - (diskfs_dirrewrite): Likewise. - - * ufs.h (compat_mode): New variable. - * main.c (main): Set compat_mode to zero if we are the bootstrap - filesystem. - * inode.c (diskfs_set_translator): Return error if compat_mode - is set. - (write_node): Don't set GNU dinode field extensions unless - compat_mode is COMPAT_GNU. - -Mon Jul 11 18:14:26 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_get_directs): When copying entries into DATAP, - set the d_reclen parameter of the copy to the minimum length - (because that's all we use) rather than the size that it had - in the directory itself. - -Wed Jul 6 14:41:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (dirscanblock): In main loop, initialize PREVOFF - to zero, not BLOCKADDR. Otherwise, the wrong value is - stored into DS->prevoff and then diskfs_dirremove crashes. - -Tue Jul 5 14:07:38 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dinode.h: Include <endian.h> before test of BYTE_ORDER. - - * Makefile (TAGSLIBS): New variable. - -Tue Jun 21 13:45:04 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_direnter): Update dirents of DP, not NP. - -Mon Jun 20 16:43:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_direnter) [case SHRINK]: NEW should be set to - OLDNEEDED past DS->entry, not to the start of the next entry. - - * dir.c (diskfs_direnter) [case EXTEND]: Cast in assignment - to NEW needs proper scope. - - * inode.c (diskfs_node_norefs): Free dirents list of structure - being deallocated. Also add assert checks to make sure other - state is already clean. - -Thu Jun 16 11:38:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * dir.c (diskfs_dirempty): Map directory contents ourselves - instead of using diskfs_node_rdwr. - (struct dirstat): New structure to cache mapping between - lookup and commit operation and avoid use of diskfs_node_rdwr. - (diskfs_lookup): Map directory ourselves. Keep mapping in - DS if DS is nonzero and we might use it in direnter, dirremove, - or dirrewrite. Deallocate mapped buffer if we return some - error (other than ENOENT), or if DS is zero, or if there is - no possible commit operation to follow. When setting DS->stat - to EXTEND, do it the new way. - (dirscanblock): Changed BLKOFF to be virtual address of mapped - block and renamed it BLKADDR. New arg IDX. Use mapped block - instead of calling diskfs_node_rdwr. Set DS according to the new - rules. - (diskfs_direnter): Interpret new dirstat format. - (diskfs_dirremove): Likewise. - (diskfs_dirrewrite): Likewise. - (diskfs_drop_dirstat): Deallocate cached mapping here. - - * dir.c (dirscanblock): When we find the node for type CREATE, - invalidate DS by setting type to LOOKUP, not LOOKING. - - * dir.c (diskfs_direnter, diskfs_dirremove, diskfs_dirrewrite): - Call diskfs_notice_dirchange when appropriate. - - * dir.c (diskfs_get_directs): Deal properly with case where - BUFSIZ==0 and where NENTRIES==-1. - -Wed Jun 15 16:40:12 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * main.c (main): Check device sector size and media size - on startup. - -Tue Jun 14 14:41:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * ufs.h (struct disknode) [dirents]: New member. - * inode.c (iget): Initialize DN->dirents. - * dir.c (diskfs_direnter, diskfs_dirremove): Keep track - of dirents member. - (dirscanblock): New var `nentries'; use it to count the - number of directory entries in this block and set it if - we end up scanning the entire block. - (count_dirents): New function. - (diskfs_get_directs): New function. - -Mon Jun 13 13:50:00 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * ufs.h (sinmaplock, dinmaplock): New global vars. - * inode.c (inode_init): Initialize sinmaplock and dinmaplock. - * pager.c (find_address, pager_unlock_page): Protect use - if dinloc array with dinmaplock. - (din_map, din_unmap): Doc fix. - (find_address, pager_unlock_page): Protect use of sinloc array - with sinmaplock. - (sin_map, sin_remap, sin_unmap): Doc fix. - (pager_clear_user_data): Acquire sinmaplock and dinmaplock - instead of NP->dn->datalock and NP->dn->sinlock respectively. - - * sizes.c (diskfs_truncate, diskfs_grow): Protect use of sinloc - and sindir mapping functions with sinmaplock. - (sindir_drop): Protect use of dinloc and dindir mapping functions - with dinmaplock. - - * ufs.h (struct rwlock): New type. - (struct disknode) [dinlock, sinlock, datalock]: Use read-write lock. - Change comments so that these don't lock dinloc and sinloc anymore. - [rwlock_master, rwlock_wakeup]: New members. - (rwlock_reader_lock, rwlock_writer_lock, rwlock_reader_unlock, - rwlock_writer_unlock, rwlock_init): New functions. - * inode.c (iget): Initialize DN->rwlock_master and - DN->rwlock_wakeup. Change initialization of DN->dinlock, - DN->sinlock, and DN->datalock to use rwlock_init. - * pager.c (find_address): Lock NP->dn->dinlock, NP->dn->sinlock, - and NP->dn->datalock with rwlock_reader_lock. Change type of - parameter NPLOCK to be a read-write lock. New parm DNP. Callers - changed. - (pager_read_page, pager_write_page): Change type of NPLOCK to be - read-write lock; call rwlock_reader_unlock instead of - mutex_unlock. New variable DN. - (pager_unlock_page): Use rwlock_writer_lock to lock - NP->dn->dinlock, NP->dn->sinlock, and NP->dn->datalock. - * sizes.c (diskfs_truncate, diskfs_grow): Change locks of DATALOCK - field to use rwlock_writer_{un,}lock. - (sindir_drop): Ditto for SINLOCK field. - (dindir_drop): Ditto for DINLOCK field. - -Mon Jun 6 19:23:26 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_grow): After realloccg, zero new data (which I'm - not sure is really necessary, but until I figure it out, this is - safest). Also poke old data (the latter only if the block has - moved)--otherwise the kernel won't know to page it out to the new - location. - (poke_pages): When poking, be careful not to actually change the data. - LEN should be end - start, not start - end. - -Fri Jun 3 12:37:27 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * inode.c (iget): When we find the node in the table, acquire the - mutex *after* incrementing NP->references and unlocking - diskfs_node_refcnt_lock; otherwise we can deadlock against - diskfs_nput. - -Thu Jun 2 12:16:09 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * ufs.h (sblock_dirty, csum_dirty, alloclock): New global variables. - * alloc.c (alloclock): Remove static keyword.. - * alloc.c (realloccg): Set sblock_dirty after changing sblock. - (blkpref): Likewise. - (fragextend): Likewise. - (alloccg): Likewise. - (alloccgblk): Likewise. - (ialloccg): Likewise. - (blkfree): Likewise. - (diskfs_free_node): Likewise. - * hyper.c (diskfs_set_hypermetadata): Likewise. - * alloc.c (fragextend): Set csum_dirty after changi csum. - (alloccg): Likewise. - (alloccgblk): Likewise. - (ialloccg): Likewise. - (blkfree): Likewise. - (diskfs_free_node): Likewise. - * hyper.c (diskfs_set_hypermetadata): Acquire alloclock while - writing hypermetadata. Only write csum and sblock if - csum_dirty or sblock_dirty, respectively, is set, and then - clear it after starting the write. - - * main.c (main): Likewise. - - * sizes.c (diskfs_truncate): Don't turn off caching; the new - light reference system takes care of this. - * pager.c (diskfs_get_filemap): No longer necessary to turn - on caching here, because truncate no longer turns it off. - - * inode.c (diskfs_lost_hardrefs, diskfs_new_hardrefs): New functions. - * pager.c (drop_pager_softrefs, allow_pager_softrefs): New functions. - (sin_map): Use diskfs_nref_light, not diskfs_nref. - (diskfs_get_filemap): Use diskfs_nref_light, not diskfs_nref. - (pager_clear_user_data): Use diskfs_nrele_light, not diskfs_nrele. - * ufs.h (drop_pager_softrefs, allow_pager_softrefs): New - declarations. - -Wed Jun 1 13:35:11 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): After calling sin_unmap, turn - off caching on the sininfo pager so that it gets freed promptly - (there's generally no value in keeping it around because there - is no live fileinfo pager). - * pager.c (diskfs_get_filemap): Make sure we turn caching back on - here, however, if we start using the file pager. - - * pager.c (sin_map): When np->dn->sininfo is set, we have - to insert a valid send right after fetching the receive name. - - * pager.c (sin_unmap, din_unmap): New functions. - (pager_clear_user_data): Call sin_unmap and din_unmap - instead of doing it right here. - - * sizes.c (diskfs_truncate): Call sin_unmap instead of - doing it right here. - (sindir_drop): Call din_unmap instead of doing it right - here. Also, call it always, not just when wo do dindir_drop. - - * sizes.c (diskfs_grow): After alloc into sindir area, - unmap it if we don't have an active data pager. - * ufs.h (sin_unmap, din_unmap): New declarations. - - * sizes.c (diskfs_grow): In computing OSIZE in the realloc - case of lbn < NDADDR, deal correctly with the case where - np->allocsize is already an integral number of blocks. - - * sizes.c (diskfs_grow): Compute SIZE correctly. - - * alloc.c (alloc, realloccg, blkfree): When checking validity - of size arguments, also make sure the size isn't zero. - - * alloc.c (diskfs_alloc_node): Lock ALLOCLOCK before checking - sblock->fs_cstotal.cs_nifree. - -Tue May 31 18:47:42 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * ufs.h (DONT_CACHE_MEMORY_OBJECTS): Define it. - - * dir.c (diskfs_direnter: case TAKE): Assert that OLD->d_reclen >= - NEEDED, not that it is strictly >. - -Tue May 31 11:10:28 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_grow): Call diskfs_node_update (but don't wait) - after successful completion to prevent old data from hanging around - too long and getting flushed all at once from the kernel. - - * sizes.c (diskfs_grow): Change SIZE to be the size of the last - block allocated. Delete variable NSIZE; use SIZE instead. - -Fri May 27 13:15:26 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): Set NP->dn_stat_dirty after each - modification of NP->dn_stat. - - * sizes.c (diskfs_truncate): Compute new value of NP->allocsize - correctly. - - * inode.c (iget): Set NP->allocsize to be the *actual* allocsize. - -Thu May 26 11:51:45 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): In blkfree loop of blocks past - NDADDR, subtract NDADDR from idx to index correctly into - sinloc array. Start this loop with idx not less than NDADDR. - (diskfs_truncate): If olastblock == NDADDR, then we also - need to truncate blocks (one) mapped by single indirect blocks. - (diskfs_truncate): New variable `first2free'. Use in place - of older losing calculations involving lastblock. - (sindir_drop): Rename parameters to be FIRST and LAST. Change - interpretation of FIRST by one to correspond with changed call - in diskfs_truncate. - - * pager.c (sin_remap): When computing NEWSIZE, round up to - a page boundary, thus mimicing the SINDIR computation in - pager_report_extent properly. - - * pager.c (pager_unlock_page) [case SINDIR; vblkno == 0]: Read - from ....di_ib[INDIR_SINGLE] rather than invalid data before - NP->dn->dinloc. - - * alloc.c (alloc) [nospace]: Unlock alloclock. - (realloccg): Unlock alloclock before jumping to nospace. - (blkpref) [!(lbn < NDADDR)]: Unlock alloclock before returning - success. - - * sizes.c (diskfs_grow): When allocing a block past NDADDR, the - tbl arg to blkpref is the table of direct block pointers - NP->dn->sinloc, not the table of indirect block pointers - ...->di_ib. - - * sizes.c (diskfs_grow): When writing into the SINDIR area, call - sin_map instead of sin_remap if the sindir isn't already mapped. - Also set np->allocsize *before* calling sin_map, but *after* - calling sin_remap, to meet the requirements of those separate - routines. - - * sizes.c (diskfs_grow): If END isn't bigger than NP->allocsize, - then don't try and do anything. In computation of LBN and the - first use of NB, round up to block boundary correctly. Don't - attempt to realloc an old block if the size is 0 (in which case - NB is -1 and unsigned comparison rules might foul things up). - -Mon May 23 13:18:33 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * Makefile (ufs): Give -n in the proper order to rsh. - - * main.c: Include <hurd/startup.h>. - - * ufs.h (DONT_CACHE_MEMORY_OBJECTS): New compilation flag. - * pager.c (pager_report_attributes): Deleted function. - (MAY_CACHE): New macro; more useful form for using - DONT_CACHE_MEMORY_OBJECTS. - (sin_map, pager_init, diskfs_get_filemap): Provide new - args in calls to pager_create. - * sizes.c (MAY_CACHE): New macro; more useful form for - using DONT_CACHE_MEMORY_OBJECTS. - (diskfs_truncate): Use MAY_CACHE in calls to pager_change_attributes. - -Fri May 20 18:52:41 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): Force any delayed copies of the - vanishing region to be taken immediately before stopping, and - prevent any new delayed copies from being made until we are done - manipulating things. - (poke_pages): New function. - * pager.c (pager_report_attributes): New function. - -Wed May 18 15:51:40 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * alloc.c (alloc, realloccg, diskfs_alloc_node, alloccgblk, - blkfree, diskfs_free_node, mapsearch): Added helpful strings to - asserts. - (realloccg): Split up assert. - -Tue May 17 13:26:22 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * main.c (main): Delete unused variable PROC. - -Mon May 16 15:32:07 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * alloc.c (realloccg): When fragextend succeeds, bother to set - *PBN. - - * sizes.c (diskfs_grow): In fragment growth case, NSIZE should - not be the amount to hold SIZE (SIZE is the amount the file is - growing by), but rather the old size of the fragment plus the - SIZE. - - * dir.c (diskfs_direnter case COMPRESS): Rewrite loop to deal - properly with the case where from and to overlap. - -Mon May 9 16:51:44 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * main.c (ufs_version): New variable. - (save_argv): New variable. - (main): Set save_argv. - (diskfs_init_completed): New function. - -Thu May 5 19:06:54 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * Makefile (exec_server_image.o): Use -n when calling rsh. - -Thu May 5 07:39:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * Makefile ($(OBJS)): Use $(includedir) instead of $(headers) in deps. - diff --git a/ufs/Makefile b/ufs/Makefile index 202316f8..cf5c40d7 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,5 +1,6 @@ - -# Copyright (C) 1994, 1995, 1996 Free Software Foundation +# Makefile for ufs +# +# Copyright (C) 1994,95,96,99,2000,02 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -16,18 +17,16 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dir := ufs -makemode := servers +makemode := server -targets = ufs ufs.static +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) -HURDLIBS = diskfs iohelp fshelp store pager ports threads ihash shouldbeinlibc - -ufs.static-LDFLAGS += -static +HURDLIBS = diskfs iohelp fshelp store pager threads ports ihash shouldbeinlibc include ../Makeconf -ufs.static ufs: $(OBJS) $(library_deps) +ufs.static: $(boot-store-types:%=../libstore/libstore_%.a) diff --git a/ufs/alloc.c b/ufs/alloc.c index ac72c928..d8f92255 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,5 +1,5 @@ /* Disk allocation routines - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993,94,95,96,98,2002 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -8,7 +8,7 @@ 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, +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. @@ -67,7 +67,7 @@ extern u_long nextgennumber; spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; /* Forward declarations */ -static u_long ffs_hashalloc (struct node *, int, long, int, +static u_long ffs_hashalloc (struct node *, int, long, int, u_long (*)(struct node *, int, daddr_t, int)); static u_long ffs_alloccg (struct node *, int, daddr_t, int); static daddr_t ffs_fragextend (struct node *, int, long, int, int); @@ -96,7 +96,7 @@ void swab_cg (struct cg *cg) { int i, j; - + if (swab_long (cg->cg_magic) == CG_MAGIC || cg->cg_magic == CG_MAGIC) { @@ -125,12 +125,12 @@ swab_cg (struct cg *cg) /* blktot map */ for (i = 0; i < cg->cg_ncyl; i++) cg_blktot(cg)[i] = swab_long (cg_blktot(cg)[i]); - + /* blks map */ for (i = 0; i < cg->cg_ncyl; i++) for (j = 0; j < sblock->fs_nrpos; j++) cg_blks(sblock, cg, i)[j] = swab_short (cg_blks (sblock, cg, i)[j]); - + for (i = 0; i < sblock->fs_contigsumsize; i++) cg_clustersum(cg)[i] = swab_long (cg_clustersum(cg)[i]); @@ -140,11 +140,11 @@ swab_cg (struct cg *cg) { /* Old format cylinder group... */ struct ocg *ocg = (struct ocg *) cg; - + if (swab_long (ocg->cg_magic) != CG_MAGIC && ocg->cg_magic != CG_MAGIC) return; - + ocg->cg_time = swab_long (ocg->cg_time); ocg->cg_cgx = swab_long (ocg->cg_cgx); ocg->cg_ncyl = swab_short (ocg->cg_ncyl); @@ -176,7 +176,7 @@ int read_cg (int cg, struct cg **cgpp) { struct cg *diskcg = cg_locate (cg); - + if (swab_disk) { *cgpp = malloc (sblock->fs_cgsize); @@ -205,7 +205,7 @@ release_cg (struct cg *cgp) /* * Allocate a block in the file system. - * + * * The size of the requested block is given, which must be some * multiple of fs_fsize and <= fs_bsize. * A preference may be optionally specified. If a preference is given @@ -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. @@ -224,7 +224,7 @@ release_cg (struct cg *cgp) */ error_t ffs_alloc(register struct node *np, - daddr_t lbn, + daddr_t lbn, daddr_t bpref, int size, daddr_t *bnp, @@ -233,7 +233,7 @@ ffs_alloc(register struct node *np, register struct fs *fs; daddr_t bno; int cg; - + *bnp = 0; fs = sblock; #ifdef DIAGNOSTIC @@ -297,7 +297,7 @@ error_t ffs_realloccg(register struct node *np, daddr_t lbprev, volatile daddr_t bpref, - int osize, + int osize, int nsize, daddr_t *pbn, struct protid *cred) @@ -306,7 +306,7 @@ ffs_realloccg(register struct node *np, int cg, error; volatile int request; daddr_t bprev, bno; - + *pbn = 0; fs = sblock; #ifdef DIAGNOSTIC @@ -322,8 +322,8 @@ ffs_realloccg(register struct node *np, #endif /* DIAGNOSTIC */ spin_lock (&alloclock); - - if (!idvec_contains (cred->user->uids, 0) + + if (!idvec_contains (cred->user->uids, 0) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; error = diskfs_catch_exception (); @@ -378,8 +378,8 @@ ffs_realloccg(register struct node *np, switch ((int)fs->fs_optim) { case FS_OPTSPACE: /* - * Allocate an exact sized fragment. Although this makes - * best use of space, we will waste time relocating it if + * Allocate an exact sized fragment. Although this makes + * best use of space, we will waste time relocating it if * the file continues to grow. If the fragmentation is * less than half of the minimum free reserve, we choose * to begin optimizing for time. @@ -419,7 +419,7 @@ ffs_realloccg(register struct node *np, bno = (daddr_t)ffs_hashalloc(np, cg, (long)bpref, request, (u_long (*)())ffs_alloccg); if (bno > 0) { -#if 0 /* Not necessary in GNU Hurd ufs */ +#if 0 /* Not necessary in GNU Hurd ufs */ bp->b_blkno = fsbtodb(fs, bno); (void) vnode_pager_uncache(ITOV(ip)); #endif @@ -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. @@ -585,7 +585,7 @@ ffs_reallocblks(ap) * Next we must write out the modified inode and indirect blocks. * For strict correctness, the writes should be synchronous since * the old block values may have been written to disk. In practise - * they are almost never written, but if we are concerned about + * they are almost never written, but if we are concerned about * strict correctness, the `doasyncfree' flag should be set to zero. * * The test on `doasyncfree' should be changed to test a flag @@ -631,20 +631,20 @@ fail: /* * Allocate an inode in the file system. - * + * * If allocating a directory, use ffs_dirpref to select the inode. * If allocating in a directory, the following hierarchy is followed: * 1) allocate the preferred inode. * 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 * available inode is located. */ -/* This is now the diskfs_alloc_node callback from the diskfs library +/* This is now the diskfs_alloc_node callback from the diskfs library (described in <hurd/diskfs.h>). It used to be ffs_valloc in BSD. */ error_t diskfs_alloc_node (struct node *dir, @@ -656,7 +656,7 @@ diskfs_alloc_node (struct node *dir, ino_t ino, ipref; int cg, error; int sex; - + fs = sblock; @@ -685,7 +685,7 @@ diskfs_alloc_node (struct node *dir, assert ("duplicate allocation" && !np->dn_stat.st_mode); assert (! (np->dn_stat.st_mode & S_IPTRANS)); if (np->dn_stat.st_blocks) { - printf("free inode %d had %d blocks\n", + printf("free inode %Ld had %Ld blocks\n", ino, np->dn_stat.st_blocks); np->dn_stat.st_blocks = 0; np->dn_set_ctime = 1; @@ -700,7 +700,7 @@ diskfs_alloc_node (struct node *dir, nextgennumber = sex; np->dn_stat.st_gen = nextgennumber; spin_unlock (&gennumberlock); - + *npp = np; alloc_sync (np); return (0); @@ -739,7 +739,7 @@ ffs_dirpref(register struct fs *fs) * Select the desired position for the next block in a file. The file is * logically divided into sections. The first section is composed of the * direct blocks. Each additional section contains fs_maxbpg blocks. - * + * * If no blocks have been allocated in the first section, the policy is to * request a block in the same cylinder group as the inode that describes * the file. If no blocks have been allocated in any other section, the @@ -753,7 +753,7 @@ ffs_dirpref(register struct fs *fs) * indirect block, the information on the previous allocation is unavailable; * here a best guess is made based upon the logical block number being * allocated. - * + * * If a section is already partially allocated, the policy is to * contiguously allocate fs_maxcontig blocks. The end of one of these * contiguous blocks and the beginning of the next is physically separated @@ -786,10 +786,10 @@ ffs_blkpref(struct node *np, */ if (indx == 0 || bap[indx - 1] == 0) startcg = - (ino_to_cg(fs, np->dn->number) + (ino_to_cg(fs, np->dn->number) + lbn / fs->fs_maxbpg); else - startcg = dtog(fs, + startcg = dtog(fs, read_disk_entry (bap[indx - 1])) + 1; startcg %= fs->fs_ncg; avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; @@ -892,14 +892,14 @@ ffs_hashalloc(struct node *np, /* * Determine whether a fragment can be extended. * - * Check to see if the necessary fragments are available, and + * Check to see if the necessary fragments are available, and * if they are, allocate them. */ static daddr_t ffs_fragextend(struct node *np, int cg, long bprev, - int osize, + int osize, int nsize) { register struct fs *fs; @@ -1016,7 +1016,7 @@ ffs_alloccg(struct node *np, bno = ffs_alloccgblk(fs, cgp, bpref); /* bdwrite(bp); */ if (releasecg) - release_cg (cgp); + release_cg (cgp); return (bno); } /* @@ -1030,7 +1030,7 @@ ffs_alloccg(struct node *np, break; if (allocsiz == fs->fs_frag) { /* - * no fragments were available, so a block will be + * no fragments were available, so a block will be * allocated, and hacked up */ if (cgp->cg_cs.cs_nbfree == 0) { @@ -1049,7 +1049,7 @@ ffs_alloccg(struct node *np, csum[cg].cs_nffree += i; fs->fs_fmod = 1; cgp->cg_frsum[i]++; - + if (releasecg) release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); @@ -1127,7 +1127,7 @@ ffs_alloccgblk(register struct fs *fs, /* * Block layout information is not available. * Leaving bpref unchanged means we take the - * next available free block following the one + * next available free block following the one * we just allocated. Hopefully this will at * least hit a track cache on drives of unknown * geometry (e.g. SCSI). @@ -1135,7 +1135,7 @@ ffs_alloccgblk(register struct fs *fs, goto norot; } /* - * check the summary information to see if a block is + * check the summary information to see if a block is * available in the requested cylinder starting at the * requested rotational position and proceeding around. */ @@ -1285,7 +1285,7 @@ fail: brelse(bp); return (0); } -#endif +#endif /* * Determine whether an inode can be allocated. @@ -1377,7 +1377,7 @@ gotit: * Free a block or fragment. * * The specified block or fragment is placed back in the - * free map. If a fragment is deallocated, a possible + * free map. If a fragment is deallocated, a possible * block reassembly is checked. */ void @@ -1395,7 +1395,7 @@ ffs_blkfree(register struct node *np, assert ((u_int)size <= fs->fs_bsize && !fragoff (fs, size)); cg = dtog(fs, bno); if ((u_int)bno >= fs->fs_size) { - printf("bad block %ld, ino %d\n", bno, np->dn->number); + printf("bad block %ld, ino %Ld\n", bno, np->dn->number); /* ffs_fserr(fs, ip->i_uid, "bad block"); */ return; } @@ -1409,7 +1409,7 @@ ffs_blkfree(register struct node *np, cgp = (struct cg *)bp->b_data; #else releasecg = read_cg (cg, &cgp); -#endif +#endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ if (releasecg) @@ -1484,7 +1484,7 @@ ffs_blkfree(register struct node *np, * * The specified inode is placed back in the free map. */ -/* Implement diskfs call back diskfs_free_node (described in +/* Implement diskfs call back diskfs_free_node (described in <hurd/diskfs.h>. This was called ffs_vfree in BSD. */ void diskfs_free_node (struct node *np, mode_t mode) @@ -1508,17 +1508,17 @@ diskfs_free_node (struct node *np, mode_t mode) cgp = (struct cg *)bp->b_data; #else releasecg = read_cg (cg, &cgp); -#endif +#endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ if (releasecg) - release_cg (cgp); + release_cg (cgp); return; } cgp->cg_time = diskfs_mtime->seconds; ino %= fs->fs_ipg; if (isclr(cg_inosused(cgp), ino)) { -/* printf("dev = 0x%x, ino = %d, fs = %s\n", +/* printf("dev = 0x%x, ino = %Ld, fs = %s\n", pip->i_dev, ino, fs->fs_fsmnt); */ assert (diskfs_readonly); } @@ -1687,7 +1687,7 @@ ffs_clusteracct(struct fs *fs, #if 0 /* * Fserr prints the name of a file system with an error diagnostic. - * + * * The form of the error message is: * fs: error message */ diff --git a/ufs/consts.c b/ufs/consts.c index 8806049e..69221233 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -1,5 +1,5 @@ /* Various constants wanted by the diskfs library - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -16,9 +16,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" +#include "dir.h" #include <version.h> int diskfs_link_max = LINK_MAX; +int diskfs_name_max = MAXNAMLEN; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; int diskfs_shortcut_chrdev = 1; @@ -1,5 +1,7 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996 Free Software Foundation + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2007 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -64,8 +66,8 @@ struct dirstat /* Index of this directory block. */ int idx; - - /* For stat COMPRESS, this is the address (inside mapbuf) + + /* For stat COMPRESS, this is the address (inside mapbuf) of the first direct in the directory block to be compressed. */ /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ struct directory_entry *entry; @@ -79,24 +81,24 @@ struct dirstat size_t nbytes; }; -size_t diskfs_dirstat_size = sizeof (struct dirstat); +const size_t diskfs_dirstat_size = sizeof (struct dirstat); /* Initialize DS such that diskfs_drop_dirstat will ignore it. */ -void +void diskfs_null_dirstat (struct dirstat *ds) { ds->type = LOOKUP; } -static error_t -dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, struct dirstat *ds, - ino_t *inum); +static error_t +dirscanblock (vm_address_t blockoff, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, + struct dirstat *ds, ino_t *inum); /* Implement the diskfs_lookup from the diskfs library. See <hurd/diskfs.h> for the interface specification. */ error_t -diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, +diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; @@ -113,7 +115,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx, lastidx; int looped; - + if ((type == REMOVE) || (type == RENAME)) assert (npp); @@ -122,12 +124,16 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, spec_dotdot = type & SPEC_DOTDOT; type &= ~SPEC_DOTDOT; - + namelen = strlen (name); if (namelen > MAXNAMLEN) - return ENAMETOOLONG; - + { + if (ds) + diskfs_null_dirstat (ds); + return ENAMETOOLONG; + } + try_again: if (ds) { @@ -137,7 +143,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } if (buf) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); buf = 0; } if (ds && (type == CREATE || type == RENAME)) @@ -145,6 +151,10 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp, prot); + + if (memobj == MACH_PORT_NULL) + return errno; + buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); @@ -153,10 +163,9 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, mach_port_deallocate (mach_task_self (), memobj); inum = 0; - - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; - + + diskfs_set_node_atime (dp); + /* Start the lookup at DP->dn->dir_idx. */ idx = dp->dn->dir_idx; if (idx * DIRBLKSIZ > dp->dn_stat.st_size) @@ -177,7 +186,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } if (err != ENOENT) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); return err; } @@ -192,8 +201,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -217,7 +225,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, goto out; } } - + /* We are looking up .. */ /* Check to see if this is the root of the filesystem. */ else if (dp->dn->number == 2) @@ -225,7 +233,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, err = EAGAIN; goto out; } - + /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) @@ -259,11 +267,11 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, retry_dotdot = inum; goto try_again; } - + /* Here below are the spec dotdot cases. */ else if (type == RENAME || type == REMOVE) np = ifind (inum); - + else if (type == LOOKUP) { diskfs_nput (dp); @@ -274,7 +282,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, else assert (0); } - + if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ @@ -291,7 +299,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, || !ds || ds->type == LOOKUP) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); if (ds) ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ } @@ -300,7 +308,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, ds->mapbuf = buf; ds->mapextent = buflen; } - + if (np) { assert (npp); @@ -334,8 +342,8 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, diskfs_lookup. If found, set *INUM to the inode number, else return ENOENT. */ static error_t -dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, +dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, struct dirstat *ds, ino_t *inum) { int nfree = 0; @@ -347,7 +355,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, int looking = 0; int countcopies = 0; int consider_compress = 0; - + if (ds && (ds->stat == LOOKING || ds->stat == COMPRESS)) { @@ -361,30 +369,30 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, prevoff = currentoff, currentoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *)currentoff; - + if (!entry->d_reclen || read_disk_entry (entry->d_reclen) % 4 || DIRECT_NAMLEN (entry) > MAXNAMLEN - || (currentoff + read_disk_entry (entry->d_reclen) + || (currentoff + read_disk_entry (entry->d_reclen) > blockaddr + DIRBLKSIZ) || entry->d_name[DIRECT_NAMLEN (entry)] || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", + fprintf (stderr, "Bad directory entry: inode: %Ld offset: %zd\n", dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } - + if (looking || countcopies) { int thisfree; - + /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) thisfree = read_disk_entry (entry->d_reclen); else - thisfree = (read_disk_entry (entry->d_reclen) + thisfree = (read_disk_entry (entry->d_reclen) - DIRSIZ (DIRECT_NAMLEN (entry))); /* If this isn't at the front of the block, then it will @@ -392,9 +400,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, number of bytes there too. */ if (countcopies && currentoff != blockaddr) nbytes += DIRSIZ (DIRECT_NAMLEN (entry)); - + if (ds->stat == COMPRESS && nbytes > ds->nbytes) - /* The previously found compress is better than + /* The previously found compress is better than this one, so don't bother counting any more. */ countcopies = 0; @@ -411,9 +419,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, nfree += thisfree; if (nfree >= needed) consider_compress = 1; - } + } } - + if (entry->d_ino) nentries++; @@ -424,7 +432,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, break; } - if (consider_compress + if (consider_compress && (ds->type == LOOKING || (ds->type == COMPRESS && ds->nbytes > nbytes))) { @@ -434,7 +442,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->idx = idx; ds->nbytes = nbytes; } - + if (currentoff >= blockaddr + DIRBLKSIZ) { int i; @@ -444,9 +452,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, down how many entries there were. */ if (!dp->dn->dirents) { - dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) * sizeof (int)); - for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; } /* Make sure the count is correct if there is one now. */ @@ -456,7 +464,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, return ENOENT; } - + /* We have found the required name. */ if (ds && type == CREATE) @@ -482,7 +490,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, the preceding lookup call, and only if that call returned ENOENT. */ error_t diskfs_direnter_hard(struct node *dp, - char *name, + const char *name, struct node *np, struct dirstat *ds, struct protid *cred) @@ -492,21 +500,21 @@ diskfs_direnter_hard(struct node *dp, int needed = DIRSIZ (namelen); int oldneeded; vm_address_t fromoff, tooff; - int totfreed; + int totfreed; error_t err; - off_t oldsize = 0; + size_t oldsize = 0; assert (ds->type == CREATE); - + dp->dn_set_mtime = 1; switch (ds->stat) { case TAKE: /* We are supposed to consume this slot. */ - assert (ds->entry->d_ino == 0 + assert (ds->entry->d_ino == 0 && read_disk_entry (ds->entry->d_reclen) >= needed); - + write_disk_entry (ds->entry->d_ino, np->dn->number); DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) @@ -514,27 +522,27 @@ diskfs_direnter_hard(struct node *dp, bcopy (name, ds->entry->d_name, namelen + 1); break; - + case SHRINK: /* We are supposed to take the extra space at the end of this slot. */ oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (read_disk_entry (ds->entry->d_reclen) - oldneeded >= needed); - + new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); write_disk_entry (new->d_ino, np->dn->number); - write_disk_entry (new->d_reclen, + write_disk_entry (new->d_reclen, read_disk_entry (ds->entry->d_reclen) - oldneeded); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); - + write_disk_entry (ds->entry->d_reclen, oldneeded); - + break; - + case COMPRESS: /* We are supposed to move all the entries to the front of the block, giving each the minimum @@ -562,7 +570,7 @@ diskfs_direnter_hard(struct node *dp, totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; assert (totfreed >= needed); - + new = (struct directory_entry *) tooff; write_disk_entry (new->d_ino, np->dn->number); write_disk_entry (new->d_reclen, totfreed); @@ -575,14 +583,20 @@ diskfs_direnter_hard(struct node *dp, case EXTEND: /* Extend the file. */ assert (needed <= DIRBLKSIZ); - + oldsize = dp->dn_stat.st_size; + if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size + DIRBLKSIZ) + { + /* We can't possibly map the whole directory in. */ + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + return EOVERFLOW; + } while (oldsize + DIRBLKSIZ > dp->allocsize) { err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); if (err) { - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); return err; } } @@ -599,18 +613,18 @@ diskfs_direnter_hard(struct node *dp, new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; - + default: assert (0); } dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + if (ds->stat != EXTEND) { - /* If we are keeping count of this block, then keep the count up + /* If we are keeping count of this block, then keep the count up to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]++; @@ -622,10 +636,10 @@ diskfs_direnter_hard(struct node *dp, anything at all. */ if (dp->dn->dirents) { - dp->dn->dirents = realloc (dp->dn->dirents, + dp->dn->dirents = realloc (dp->dn->dirents, (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int))); - for (i = oldsize / DIRBLKSIZ; + for (i = oldsize / DIRBLKSIZ; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; @@ -634,14 +648,14 @@ diskfs_direnter_hard(struct node *dp, } else { - dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ + dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int)); for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; dp->dn->dirents[ds->idx] = 1; } } - + diskfs_file_update (dp, 1); return 0; @@ -650,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, @@ -658,7 +672,7 @@ diskfs_dirremove_hard(struct node *dp, { assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; if (ds->preventry == 0) @@ -667,48 +681,48 @@ diskfs_dirremove_hard(struct node *dp, { assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry == read_disk_entry (ds->preventry->d_reclen)); - write_disk_entry (ds->preventry->d_reclen, + write_disk_entry (ds->preventry->d_reclen, (read_disk_entry (ds->preventry->d_reclen) + read_disk_entry (ds->entry->d_reclen))); } dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); /* If we are keeping count of this block, then keep the count up to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]--; - + diskfs_file_update (dp, 1); return 0; } - + /* Following a lookup call for RENAME, this changes the inode number - on a directory entry. DP is the directory being changed; NP is - the new node being linked in; DP is the cached information returned + on a directory entry. DP is the directory being changed; NP is + the new node being linked in; DP is the cached information returned by lookup. This call is only valid if the directory has been locked continuously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirrewrite_hard(struct node *dp, +diskfs_dirrewrite_hard(struct node *dp, struct node *np, struct dirstat *ds) { assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; write_disk_entry (ds->entry->d_ino, np->dn->number); if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + diskfs_file_update (dp, 1); return 0; @@ -721,23 +735,26 @@ diskfs_dirempty(struct node *dp, struct protid *cred) { struct directory_entry *entry; - int curoff; - vm_address_t buf; + vm_address_t buf, curoff; memory_object_t memobj; error_t err; memobj = diskfs_get_filemap (dp, VM_PROT_READ); + + if (memobj == MACH_PORT_NULL) + /* XXX should reflect error properly */ + return 0; + buf = 0; - + err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0); mach_port_deallocate (mach_task_self (), memobj); assert (!err); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); - for (curoff = buf; + for (curoff = buf; curoff < buf + dp->dn_stat.st_size; curoff += read_disk_entry (entry->d_reclen)) { @@ -749,19 +766,17 @@ diskfs_dirempty(struct node *dp, || (entry->d_name[1] != '.' && entry->d_name[1] != '\0'))) { - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + munmap ((caddr_t) buf, dp->dn_stat.st_size); + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); return 0; } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + munmap ((caddr_t) buf, dp->dn_stat.st_size); return 1; } @@ -772,7 +787,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) if (ds->type != LOOKUP) { assert (ds->mapbuf); - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); ds->type = LOOKUP; } return 0; @@ -785,7 +800,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) static error_t count_dirents (struct node *dp, int nb, char *buf) { - int amt; + size_t amt; char *offinblk; struct directory_entry *entry; int count = 0; @@ -793,12 +808,12 @@ count_dirents (struct node *dp, int nb, char *buf) assert (dp->dn->dirents); assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size); - + err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt); if (err) return err; assert (amt == DIRBLKSIZ); - + for (offinblk = buf; offinblk < buf + DIRBLKSIZ; offinblk += read_disk_entry (entry->d_reclen)) @@ -807,7 +822,7 @@ count_dirents (struct node *dp, int nb, char *buf) if (entry->d_ino) count++; } - + assert (dp->dn->dirents[nb] == -1 || dp->dn->dirents[nb] == count); dp->dn->dirents[nb] = count; return 0; @@ -816,11 +831,11 @@ count_dirents (struct node *dp, int nb, char *buf) /* Implement the disikfs_get_directs callback as described in <hurd/diskfs.h>. */ error_t -diskfs_get_directs (struct node *dp, - int entry, +diskfs_get_directs (struct node *dp, + int entry, int nentries, char **data, - u_int *datacnt, + size_t *datacnt, vm_size_t bufsiz, int *amt) { @@ -835,9 +850,9 @@ diskfs_get_directs (struct node *dp, char *datap; struct directory_entry *entryp; int allocsize; - int checklen; + size_t checklen; struct dirent *userp; - + nblks = dp->dn_stat.st_size/DIRBLKSIZ; if (!dp->dn->dirents) @@ -847,15 +862,6 @@ diskfs_get_directs (struct node *dp, dp->dn->dirents[i] = -1; } - /* Allocate enough space to hold the maximum we might return */ - if (!bufsiz || bufsiz > dp->dn_stat.st_size) - allocsize = round_page (dp->dn_stat.st_size); - else - allocsize = round_page (bufsiz); - - if (allocsize > *datacnt) - vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); - /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run off the end, ENTRY is too big. */ @@ -876,17 +882,29 @@ diskfs_get_directs (struct node *dp, break; curentry += dp->dn->dirents[blkno]; - + bufvalid = 0; } - + if (blkno == nblks) { + /* We reached the end of the directory without seeing ENTRY. + This is treated as an EOF condition, meaning we return + success with empty results. */ *datacnt = 0; *amt = 0; return 0; } + /* Allocate enough space to hold the maximum we might return */ + if (!bufsiz || bufsiz > dp->dn_stat.st_size) + allocsize = round_page (dp->dn_stat.st_size); + else + allocsize = round_page (bufsiz); + + if (allocsize > *datacnt) + *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + /* Set bufp appropriately */ bufp = buf; if (curentry != entry) @@ -902,15 +920,15 @@ diskfs_get_directs (struct node *dp, assert (checklen == DIRBLKSIZ); bufvalid = 1; } - for (i = 0, bufp = buf; - i < entry - curentry && bufp - buf < DIRBLKSIZ; + for (i = 0, bufp = buf; + i < entry - curentry && bufp - buf < DIRBLKSIZ; (bufp - += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), + += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); - } + } i = 0; datap = *data; @@ -922,7 +940,7 @@ diskfs_get_directs (struct node *dp, { if (!bufvalid) { - err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &checklen); if (err) return err; @@ -953,17 +971,16 @@ diskfs_get_directs (struct node *dp, bufvalid = 0; } } - + /* We've copied all we can. If we allocated our own array but didn't fill all of it, then free whatever memory we didn't use. */ if (allocsize > *datacnt) { if (round_page (datap - *data) < allocsize) - vm_deallocate (mach_task_self (), - (vm_address_t) (*data + round_page (datap - *data)), - allocsize - round_page (datap - *data)); + munmap (*data + round_page (datap - *data), + allocsize - round_page (datap - *data)); } - + /* Set variables for return */ *datacnt = datap - *data; *amt = i; @@ -70,6 +70,7 @@ * dp->d_ino set to 0. */ #define DIRBLKSIZ DEV_BSIZE +#undef MAXNAMLEN #define MAXNAMLEN 255 /* Don't call this struct DIRECT because the library defines that @@ -90,13 +91,13 @@ struct directory_entry { /* Return the namlen from a struct direct, paying attention to whether this filesystem supports the type extension */ #if (BYTE_ORDER == LITTLE_ENDIAN) -#define DIRECT_NAMLEN(dp) (direct_symlink_extension || swab_disk \ - ? (dp)->d_namlen \ - : (dp)->d_type) +#define DIRECT_NAMLEN(dp) (*(direct_symlink_extension || swab_disk \ + ? &(dp)->d_namlen \ + : &(dp)->d_type)) #else -#define DIRECT_NAMLEN(dp) (!direct_symlink_extension && swab_disk \ - ? (dp)->d_type \ - : (dp)->d_namlen) +#define DIRECT_NAMLEN(dp) (*(!direct_symlink_extension && swab_disk \ + ? &(dp)->d_type \ + : &(dp)->d_namlen)) #endif /* diff --git a/ufs/hyper.c b/ufs/hyper.c index 052bc220..ece327a2 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -34,7 +34,7 @@ void swab_sblock (struct fs *sblock) { int i, j; - + sblock->fs_sblkno = swab_long (sblock->fs_sblkno); sblock->fs_cblkno = swab_long (sblock->fs_cblkno); sblock->fs_iblkno = swab_long (sblock->fs_iblkno); @@ -108,24 +108,24 @@ swab_sblock (struct fs *sblock) else for (i = 0; i < sblock->fs_cpc; i++) for (j = 0; j < sblock->fs_nrpos; j++) - fs_postbl(sblock, j)[i] + fs_postbl(sblock, j)[i] = swab_short (fs_postbl (sblock, j)[i]); /* The rot table is all chars */ } - + void swab_csums (struct csum *csum) { int i; - + for (i = 0; i < sblock->fs_ncg; i++) { csum[i].cs_ndir = swab_long (csum[i].cs_ndir); csum[i].cs_nbfree = swab_long (csum[i].cs_nbfree); csum[i].cs_nifree = swab_long (csum[i].cs_nifree); csum[i].cs_nffree = swab_long (csum[i].cs_nffree); - } + } } void @@ -138,8 +138,7 @@ get_hypermetadata (void) /* Free previous values. */ if (zeroblock) - vm_deallocate (mach_task_self(), - (vm_address_t)zeroblock, sblock->fs_bsize); + munmap ((caddr_t) zeroblock, sblock->fs_bsize); if (csum) free (csum); @@ -252,14 +251,13 @@ get_hypermetadata (void) if (store->size < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size (%Zd) less than necessary " + "Disk size (%Ld) less than necessary " "(superblock says we need %ld)\n", store->size, sblock->fs_size * sblock->fs_fsize); exit (1); } - vm_allocate (mach_task_self (), - (vm_address_t *)&zeroblock, sblock->fs_bsize, 1); + zeroblock = mmap (0, sblock->fs_bsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); /* If the filesystem has new features in it, don't pay attention to the user's request not to use them. */ @@ -292,8 +290,10 @@ diskfs_set_hypermetadata (int wait, int clean) size_t read = 0; size_t bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - err = store_read (store, fsbtodb (sblock, sblock->fs_csaddr), bufsize, - &buf, &read); + err = store_read (store, + fsbtodb (sblock, sblock->fs_csaddr) + << log2_dev_blocks_per_dev_bsize, + bufsize, &buf, &read); if (err) return err; else if (read != bufsize) @@ -304,14 +304,16 @@ diskfs_set_hypermetadata (int wait, int clean) bcopy (csum, buf, sblock->fs_cssize); if (swab_disk) swab_csums ((struct csum *)buf); - err = store_write (store, fsbtodb (sblock, sblock->fs_csaddr), + err = store_write (store, + fsbtodb (sblock, sblock->fs_csaddr) + << log2_dev_blocks_per_dev_bsize, buf, bufsize, &wrote); if (!err && wrote != bufsize) err = EIO; } - vm_deallocate (mach_task_self (), (vm_address_t)buf, read); - + munmap (buf, read); + if (err) { spin_unlock (&alloclock); @@ -392,9 +394,9 @@ copy_sblock () void diskfs_readonly_changed (int readonly) { - vm_protect (mach_task_self (), - (vm_address_t)disk_image, store->size, - 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); + (*(readonly ? store_set_flags : store_clear_flags)) (store, STORE_READONLY); + + mprotect (disk_image, store->size, PROT_READ | (readonly ? 0 : PROT_WRITE)); if (readonly) { diff --git a/ufs/inode.c b/ufs/inode.c index 2965114f..77a45edb 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,7 @@ /* Inode management routines - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2007 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -44,10 +46,10 @@ inode_init () nodehash[n] = 0; } -/* Fetch inode INUM, set *NPP to the node structure; +/* Fetch inode INUM, set *NPP to the node structure; gain one user reference and lock the node. */ -error_t -diskfs_cached_lookup (int inum, struct node **npp) +error_t +diskfs_cached_lookup (ino_t inum, struct node **npp) { struct disknode *dn; struct node *np; @@ -88,7 +90,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np); - + if (!diskfs_check_readonly () && !np->dn_stat.st_gen) { spin_lock (&gennumberlock); @@ -98,7 +100,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&gennumberlock); np->dn_set_ctime = 1; } - + if (err) return err; else @@ -114,13 +116,13 @@ struct node * ifind (ino_t inum) { struct node *np; - + spin_lock (&diskfs_node_refcnt_lock); for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) { if (np->dn->number != inum) continue; - + assert (np->references); spin_unlock (&diskfs_node_refcnt_lock); return np; @@ -130,7 +132,7 @@ ifind (ino_t inum) /* The last reference to a node has gone away; drop it from the hash table and clean all state in the dn structure. */ -void +void diskfs_node_norefs (struct node *np) { *np->dn->hprevp = np->dn->hnext; @@ -158,7 +160,7 @@ diskfs_lost_hardrefs (struct node *np) #ifdef notanymore struct port_info *pi; struct pager *p; - + /* Check and see if there is a pager which has only one reference (ours). If so, then drop that reference, breaking the cycle. The complexity in this routine @@ -170,17 +172,17 @@ diskfs_lost_hardrefs (struct node *np) pi = (struct port_info *) np->dn->fileinfo->p; if (pi->refcnt == 1) { - + /* The only way to get a new reference to the pager in this state is to call diskfs_get_filemap; this can't happen as long as we hold NP locked. So we can safely unlock _libports_portrefcntlock for the following call. */ spin_unlock (&_libports_portrefcntlock); - + /* Right now the node is locked with no hard refs; - this is an anomolous situation. Before messing with - the reference count on the file pager, we have to + 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 unreference. */ @@ -212,48 +214,35 @@ diskfs_new_hardrefs (struct node *np) static error_t read_disknode (struct node *np) { - static int fsid, fsidset; struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - + err = diskfs_catch_exception (); if (err) return err; - if (! fsidset) - { - fsid = getpid (); - fsidset = 1; - } - st->st_fstype = FSTYPE_UFS; - st->st_fsid = fsid; + st->st_fsid = getpid (); /* This call is very cheap. */ st->st_ino = np->dn->number; st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); - st->st_mode = (((read_disk_entry (di->di_model) + st->st_mode = (((read_disk_entry (di->di_model) | (read_disk_entry (di->di_modeh) << 16)) & ~S_ITRANS) | (di->di_trans ? S_IPTRANS : 0)); st->st_nlink = read_disk_entry (di->di_nlink); st->st_size = read_disk_entry (di->di_size); -#ifdef notyet - st->st_atimespec = di->di_atime; - st->st_mtimespec = di->di_mtime; - st->st_ctimespec = di->di_ctime; -#else - st->st_atime = read_disk_entry (di->di_atime.tv_sec); - st->st_atime_usec = read_disk_entry (di->di_atime.tv_nsec) / 1000; - st->st_mtime = read_disk_entry (di->di_mtime.tv_sec); - st->st_mtime_usec = read_disk_entry (di->di_mtime.tv_nsec) / 1000; - st->st_ctime = read_disk_entry (di->di_ctime.tv_sec); - st->st_ctime_usec = read_disk_entry (di->di_ctime.tv_nsec) / 1000; -#endif + st->st_atim.tv_sec = read_disk_entry (di->di_atime.tv_sec); + st->st_atim.tv_nsec = read_disk_entry (di->di_atime.tv_nsec); + st->st_mtim.tv_sec = read_disk_entry (di->di_mtime.tv_sec); + st->st_mtim.tv_nsec = read_disk_entry (di->di_mtime.tv_nsec); + st->st_ctim.tv_sec = read_disk_entry (di->di_ctime.tv_sec); + st->st_ctim.tv_nsec = read_disk_entry (di->di_ctime.tv_nsec); st->st_blksize = sblock->fs_bsize; st->st_blocks = read_disk_entry (di->di_blocks); st->st_flags = read_disk_entry (di->di_flags); - + if (sblock->fs_inodefmt < FS_44INODEFMT) { st->st_uid = read_disk_entry (di->di_ouid); @@ -274,8 +263,8 @@ read_disknode (struct node *np) if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) st->st_rdev = 0; - if (S_ISLNK (st->st_mode) - && direct_symlink_extension + if (S_ISLNK (st->st_mode) + && direct_symlink_extension && st->st_size < sblock->fs_maxsymlinklen) np->allocsize = 0; else @@ -319,8 +308,7 @@ write_node (struct node *np) struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - - assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); + if (np->dn_stat_dirty) { assert (!diskfs_readonly); @@ -328,9 +316,9 @@ write_node (struct node *np) err = diskfs_catch_exception (); if (err) return; - + write_disk_entry (di->di_gen, st->st_gen); - + if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) write_disk_entry (di->di_rdev, st->st_rdev); @@ -343,7 +331,7 @@ write_node (struct node *np) write_disk_entry (di->di_model, mode & 0xffff); write_disk_entry (di->di_modeh, (mode >> 16) & 0xffff); } - else + else { write_disk_entry (di->di_model, st->st_mode & 0xffff & ~S_ITRANS); di->di_modeh = 0; @@ -354,7 +342,7 @@ write_node (struct node *np) write_disk_entry (di->di_uid, st->st_uid); write_disk_entry (di->di_gid, st->st_gid); } - + if (sblock->fs_inodefmt < FS_44INODEFMT) { write_disk_entry (di->di_ouid, st->st_uid & 0xffff); @@ -365,49 +353,43 @@ write_node (struct node *np) write_disk_entry (di->di_nlink, st->st_nlink); write_disk_entry (di->di_size, st->st_size); -#ifdef notyet - di->di_atime = st->st_atimespec; - di->di_mtime = st->st_mtimespec; - di->di_ctime = st->st_ctimespec; -#else - write_disk_entry (di->di_atime.tv_sec, st->st_atime); - write_disk_entry (di->di_atime.tv_nsec, st->st_atime_usec * 1000); - write_disk_entry (di->di_mtime.tv_sec, st->st_mtime); - write_disk_entry (di->di_mtime.tv_nsec, st->st_mtime_usec * 1000); - write_disk_entry (di->di_ctime.tv_sec, st->st_ctime); - write_disk_entry (di->di_ctime.tv_nsec, st->st_ctime_usec * 1000); -#endif + write_disk_entry (di->di_atime.tv_sec, st->st_atim.tv_sec); + write_disk_entry (di->di_atime.tv_nsec, st->st_atim.tv_nsec); + write_disk_entry (di->di_mtime.tv_sec, st->st_mtim.tv_sec); + write_disk_entry (di->di_mtime.tv_nsec, st->st_mtim.tv_nsec); + write_disk_entry (di->di_ctime.tv_sec, st->st_ctim.tv_sec); + write_disk_entry (di->di_ctime.tv_nsec, st->st_ctim.tv_nsec); write_disk_entry (di->di_blocks, st->st_blocks); write_disk_entry (di->di_flags, st->st_flags); - + diskfs_end_catch_exception (); np->dn_stat_dirty = 0; record_poke (di, sizeof (struct dinode)); } -} +} /* See if we should create a symlink by writing it directly into the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ static error_t -create_symlink_hook (struct node *np, char *target) +create_symlink_hook (struct node *np, const char *target) { int len = strlen (target); error_t err; struct dinode *di; - + if (!direct_symlink_extension) return EINVAL; - + assert (compat_mode != COMPAT_BSD42); if (len >= sblock->fs_maxsymlinklen) return EINVAL; - + err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); bcopy (target, di->di_shortlink, len); np->dn_stat.st_size = len; @@ -418,29 +400,28 @@ create_symlink_hook (struct node *np, char *target) diskfs_end_catch_exception (); return 0; } -error_t (*diskfs_create_symlink_hook)(struct node *, char *) +error_t (*diskfs_create_symlink_hook)(struct node *, const char *) = create_symlink_hook; /* Check if this symlink is stored directly in the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ -static error_t +static error_t read_symlink_hook (struct node *np, char *buf) { error_t err; - - if (!direct_symlink_extension + + if (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen) return EINVAL; err = diskfs_catch_exception (); if (err) return err; - + bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - if (! diskfs_check_readonly ()) - np->dn_set_atime = 1; + diskfs_set_node_atime (np); diskfs_end_catch_exception (); return 0; @@ -456,7 +437,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) struct item *i; error_t err; int n; - + /* Acquire a reference on all the nodes in the hash table and enter them into a list on the stack. */ spin_lock (&diskfs_node_refcnt_lock); @@ -496,10 +477,10 @@ write_all_disknodes () write_node (np); return 0; } - + diskfs_node_iterate (helper); } - + void diskfs_write_disknode (struct node *np, int wait) { @@ -520,17 +501,21 @@ diskfs_set_statfs (struct statfs *st) + sblock->fs_cstotal.cs_nffree); st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) - (sblock->fs_dsize - st->f_bfree)); + if (st->f_bfree < ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100))) + st->f_bavail = 0; st->f_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ st->f_ffree = sblock->fs_cstotal.cs_nifree; st->f_fsid = getpid (); st->f_namelen = 0; + st->f_favail = st->f_ffree; + st->f_frsize = sblock->fs_fsize; return 0; } /* Implement the diskfs_set_translator callback from the diskfs library; see <hurd/diskfs.h> for the interface description. */ error_t -diskfs_set_translator (struct node *np, char *name, u_int namelen, +diskfs_set_translator (struct node *np, const char *name, u_int namelen, struct protid *cred) { daddr_t blkno; @@ -547,10 +532,10 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); blkno = read_disk_entry (di->di_trans); - + if (namelen && !blkno) { /* Allocate block for translator */ @@ -574,7 +559,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, np->dn_stat.st_mode &= ~S_IPTRANS; np->dn_set_ctime = 1; } - + if (namelen) { bcopy (&namelen, buf, sizeof (u_int)); @@ -586,7 +571,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, np->dn_stat.st_mode |= S_IPTRANS; np->dn_set_ctime = 1; } - + diskfs_end_catch_exception (); return err; } @@ -599,7 +584,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) error_t err; daddr_t blkno; u_int datalen; - void *transloc; + const void *transloc; err = diskfs_catch_exception (); if (err) @@ -608,10 +593,17 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) blkno = read_disk_entry ((dino (np->dn->number))->di_trans); assert (blkno); transloc = disk_image + fsaddr (sblock, blkno); - + datalen = *(u_int *)transloc; - *namep = malloc (datalen); - bcopy (transloc + sizeof (u_int), *namep, datalen); + if (datalen > sblock->fs_bsize - sizeof (u_int)) + err = EFTYPE; + else + { + *namep = malloc (datalen); + if (*namep == NULL) + err = ENOMEM; + memcpy (*namep, transloc + sizeof (u_int), datalen); + } diskfs_end_catch_exception (); @@ -649,13 +641,13 @@ diskfs_S_file_get_storage_info (struct protid *cred, struct store *file_store; struct store_run runs[NDADDR]; size_t num_runs = 0; - + if (! cred) return EOPNOTSUPP; np = cred->po->np; mutex_lock (&np->lock); - + /* See if this file fits in the direct block pointers. If not, punt for now. (Reading indir blocks is a pain, and I'm postponing pain.) XXX */ @@ -678,11 +670,13 @@ diskfs_S_file_get_storage_info (struct protid *cred, for (i = 0; i < NDADDR; i++) { - off_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); - off_t length = + store_offset_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); + store_offset_t length = (((i + 1) * sblock->fs_bsize > np->allocsize) ? np->allocsize - i * sblock->fs_bsize : sblock->fs_bsize); + start <<= log2_dev_blocks_per_dev_bsize; + length <<= log2_dev_blocks_per_dev_bsize; if (num_runs == 0 || run->start + run->length != start) *run++ = (struct store_run){ start, length }; else @@ -692,7 +686,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, diskfs_end_catch_exception (); mutex_unlock (&np->lock); - + if (! err) err = store_clone (store, &file_store); if (! err) @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994,95,96,97,98,99,2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -36,6 +36,9 @@ struct store_parsed *store_parsed = 0; char *diskfs_disk_name = 0; +/* Number of device blocks per DEV_BSIZE block. */ +unsigned log2_dev_blocks_per_dev_bsize = 0; + /* Set diskfs_root_node to the root inode. */ static void warp_root (void) @@ -133,7 +136,7 @@ struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; /* Override the standard diskfs routine so we can add our own output. */ error_t -diskfs_append_args (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, size_t *argz_len) { error_t err; @@ -155,56 +158,28 @@ diskfs_append_args (char **argz, unsigned *argz_len) int main (int argc, char **argv) { - error_t err; mach_port_t bootstrap; - struct store_argp_params store_params = { 0 }; - - argp_parse (&startup_argp, argc, argv, 0, 0, &store_params); - store_parsed = store_params.result; - err = store_parsed_name (store_parsed, &diskfs_disk_name); - if (err) - error (2, err, "store_parsed_name"); + /* Initialize the diskfs library, parse arguments, and open the store. + This starts the first diskfs thread for us. */ + store = diskfs_init_main (&startup_argp, argc, argv, + &store_parsed, &bootstrap); - /* This must come after the args have been parsed, as this is where the - host priv ports are set for booting. */ - diskfs_console_stdio (); - - if (diskfs_boot_flags) - /* We are the bootstrap filesystem. */ - bootstrap = MACH_PORT_NULL; - else - { - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (2, 0, "Must be started as a translator"); - } - - /* Initialize the diskfs library. Must come before any other diskfs call. */ - err = diskfs_init_diskfs (); - if (err) - error (4, err, "init"); - - err = store_parsed_open (store_parsed, diskfs_readonly ? STORE_READONLY : 0, - &store); - if (err) - error (3, err, "%s", diskfs_disk_name); - - if (store->block_size != DEV_BSIZE) - error (4, err, "%s: Bad device record size %d (should be %d)", + if (store->block_size > DEV_BSIZE) + error (4, 0, "%s: Bad device block size %zd (should be <= %d)", diskfs_disk_name, store->block_size, DEV_BSIZE); - if (store->log2_block_size == 0) - error (4, err, "%s: Device block size (%d) not a power of 2", - diskfs_disk_name, store->block_size); + if (store->size < SBSIZE + SBOFF) + error (5, 0, "%s: Disk too small (%Ld bytes)", diskfs_disk_name, + store->size); - assert (store->size >= SBSIZE + SBOFF); + log2_dev_blocks_per_dev_bsize = 0; + while ((1 << log2_dev_blocks_per_dev_bsize) < DEV_BSIZE) + log2_dev_blocks_per_dev_bsize++; + log2_dev_blocks_per_dev_bsize -= store->log2_block_size; /* Map the entire disk. */ create_disk_pager (); - /* Start the first request thread, to handle RPCs and page requests. */ - diskfs_spawn_first_thread (); - get_hypermetadata (); inode_init (); @@ -217,6 +192,8 @@ main (int argc, char **argv) outside world. */ diskfs_startup_diskfs (bootstrap, 0); + /* SET HOST NAME */ + /* And this thread is done with its work. */ cthread_exit (0); diff --git a/ufs/mapbuf.c b/ufs/mapbuf.c deleted file mode 100644 index edf432a5..00000000 --- a/ufs/mapbuf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Cache mappings of the disk - Copyright (C) 1994 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include "ufs.h" - -struct mapbuf *mblist; -spin_lock_t mblistlock = SPIN_LOCK_INITIALIZER; - -struct mapbuf * -map_region (vm_offset_t diskloc, vm_size_t length) -{ - struct mapbuf *mb; - - /* Check to see if we are already mapping this region */ - spin_lock (&mblistlock); - for (mb = mblist; mb; mb = mb->next) - { - diff --git a/ufs/pager.c b/ufs/pager.c index 11d5eade..3038932d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -121,7 +121,14 @@ find_address (struct user_pager_info *upi, { if (*nplock) rwlock_reader_unlock (*nplock); - return EIO; + if (isread) + return EIO; + else + { + *addr = 0; + *disksize = 0; + return 0; + } } if (offset + __vm_page_size > np->allocsize) @@ -166,7 +173,8 @@ pager_read_page (struct user_pager_info *pager, if (addr) { size_t read = 0; - err = store_read (store, addr, disksize, (void **)buf, &read); + err = store_read (store, addr << log2_dev_blocks_per_dev_bsize, + disksize, (void **)buf, &read); if (read != disksize) err = EIO; if (!err && disksize != __vm_page_size) @@ -179,7 +187,8 @@ pager_read_page (struct user_pager_info *pager, printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page); fflush (stdout); #endif - vm_allocate (mach_task_self (), buf, __vm_page_size, 1); + *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); *writelock = 1; } @@ -208,18 +217,13 @@ pager_write_page (struct user_pager_info *pager, if (addr) { size_t wrote; - err = store_write (store, addr, (void *)buf, disksize, &wrote); + err = store_write (store, addr << log2_dev_blocks_per_dev_bsize, + (void *)buf, disksize, &wrote); if (wrote != disksize) err = EIO; } else - { - printf ("Attempt to write unallocated disk\n."); - printf ("Object %p\tOffset %#x\n", pager, page); - fflush (stdout); - err = 0; /* unallocated disk; - error would be pointless */ - } + err = 0; if (nplock) rwlock_reader_unlock (nplock); @@ -310,7 +314,9 @@ pager_unlock_page (struct user_pager_info *pager, goto out; assert (lblkno (sblock, address) < NDADDR); - err = store_write (store, fsbtodb (sblock, bno), + err = store_write (store, + fsbtodb (sblock, bno) + << log2_dev_blocks_per_dev_bsize, zeroblock, sblock->fs_bsize, &wrote); if (!err && wrote != sblock->fs_bsize) err = EIO; @@ -398,7 +404,9 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; - err = store_write (store, fsbtodb (sblock, bno), + err = store_write (store, + fsbtodb (sblock, bno) + << log2_dev_blocks_per_dev_bsize, zeroblock, sblock->fs_bsize, &wrote); if (!err && wrote != sblock->fs_bsize) err = EIO; @@ -563,6 +571,13 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + if (upi->p == 0) + { + diskfs_nrele_light (np); + free (upi); + spin_unlock (&node2pagelock); + return MACH_PORT_NULL; + } np->dn->fileinfo = upi; right = pager_get_port (np->dn->fileinfo->p); ports_port_deref (np->dn->fileinfo->p); diff --git a/ufs/sizes.c b/ufs/sizes.c index 84c2493d..58cbfc98 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999 Free Software Foundation This file is part of the GNU Hurd. @@ -104,10 +104,14 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); - poke_pages (obj, round_page (length), round_page (np->allocsize)); - mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (upi->p, round_page (length), - np->allocsize - length, 1); + if (obj != MACH_PORT_NULL) + { + /* XXX should cope with errors from diskfs_get_filemap */ + poke_pages (obj, round_page (length), round_page (np->allocsize)); + mach_port_deallocate (mach_task_self (), obj); + pager_flush_some (upi->p, round_page (length), + np->allocsize - length, 1); + } ports_port_deref (upi->p); } @@ -400,6 +404,11 @@ block_extended (struct node *np, /* Map in this part of the file */ mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + + /* XXX Should cope with errors from diskfs_get_filemap and back + out the operation here. */ + assert (mapobj); + err = vm_map (mach_task_self (), &mapaddr, round_page (old_size), 0, 1, mapobj, lbn * sblock->fs_bsize, 0, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); @@ -430,7 +439,7 @@ block_extended (struct node *np, /* Undo mapping */ mach_port_deallocate (mach_task_self (), mapobj); - vm_deallocate (mach_task_self (), mapaddr, round_page (old_size)); + munmap ((caddr_t) mapaddr, round_page (old_size)); /* Now it's OK to free the old block */ ffs_blkfree (np, old_pbn, old_size); @@ -477,6 +486,9 @@ diskfs_grow (struct node *np, /* This reference will ensure that NP->dn->fileinfo stays allocated. */ pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + if (pagerpt == MACH_PORT_NULL) + return errno; + /* The new last block of the file. */ lbn = lblkno (sblock, end - 1); @@ -699,7 +711,7 @@ poke_pages (memory_object_t obj, { for (poke = addr; poke < addr + len; poke += vm_page_size) *(volatile int *)poke = *(volatile int *)poke; - vm_deallocate (mach_task_self (), addr, len); + munmap ((caddr_t) addr, len); } start += len; } @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -17,15 +17,24 @@ #include <mach.h> #include <hurd.h> +#include <sys/mman.h> #include <hurd/ports.h> #include <hurd/pager.h> #include <hurd/fshelp.h> #include <hurd/iohelp.h> #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. */ @@ -81,7 +90,7 @@ struct user_pager_info } type; struct pager *p; vm_prot_t max_prot; - + vm_offset_t allow_unlocked_pagein; vm_size_t unlocked_pagein_length; }; @@ -130,6 +139,8 @@ int direct_symlink_extension; /* If this is set, then the disk is byteswapped from native order. */ int swab_disk; +/* Number of device blocks per DEV_BSIZE block. */ +unsigned log2_dev_blocks_per_dev_bsize; /* Handy macros */ #define DEV_BSIZE 512 @@ -146,8 +157,18 @@ int swab_disk; /* 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 *) @@ -157,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); @@ -186,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)); + | swab_long ((arg & 0xffffffff00000000LL) >> 32)); } +#endif /* Use extern inlines. */ /* Return ENTRY, after byteswapping it if necessary */ #define read_disk_entry(entry) \ @@ -221,7 +243,7 @@ swab_long_long (long long arg) abort (); \ ret; \ }) - + /* Execute A = B, but byteswap it along the way if necessary */ #define write_disk_entry(a,b) \ ({ \ 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" diff --git a/version.h b/version.h deleted file mode 100644 index ab6c5b2b..00000000 --- a/version.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Hurd version - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - Written by Thomas Bushnell, n/BSG. - - 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. */ - -/* See sh-version.sed for duplicates of this information. */ - -#ifndef HURD_VERSION -#define HURD_VERSION "0.2" -#endif - -/* The standard way to print versions for --version. */ -#define _SHV_SEP "; " -#define STANDARD_HURD_VERSION(s, extra...) \ - #s " (GNU Hurd" _SHV_SEP ##extra ") " HURD_VERSION - - |