diff options
Diffstat (limited to 'ext2fs/ext2fs.c')
-rw-r--r-- | ext2fs/ext2fs.c | 196 |
1 files changed, 88 insertions, 108 deletions
diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c index a1bbc22c..0857a749 100644 --- a/ext2fs/ext2fs.c +++ b/ext2fs/ext2fs.c @@ -1,6 +1,6 @@ /* Main entry point for the ext2 file system translator - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99,2002 Free Software Foundation, Inc. Converted for ext2fs by Miles Bader <miles@gnu.ai.mit.edu> @@ -27,11 +27,15 @@ #include <string.h> #include <error.h> #include <argz.h> +#include <argp.h> +#include <hurd/store.h> +#include <version.h> #include "ext2fs.h" /* ---------------------------------------------------------------- */ int diskfs_link_max = EXT2_LINK_MAX; +int diskfs_name_max = EXT2_NAME_LEN; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; int diskfs_shortcut_chrdev = 1; @@ -40,24 +44,33 @@ int diskfs_shortcut_fifo = 1; int diskfs_shortcut_ifsock = 1; char *diskfs_server_name = "ext2fs"; -int diskfs_major_version = 0; -int diskfs_minor_version = 0; -int diskfs_edit_version = 0; +char *diskfs_server_version = HURD_VERSION; +char *diskfs_extra_version = "GNU Hurd; ext2 " EXT2FS_VERSION; -int diskfs_synchronous = 0; -int diskfs_readonly = 0; +int diskfs_synchronous; struct node *diskfs_root_node; + +struct store *store; +struct store_parsed *store_parsed; + +char *diskfs_disk_name; #ifdef EXT2FS_DEBUG - -int ext2_debug_flag = 0; +int ext2_debug_flag; +#endif /* Ext2fs-specific options. */ static const struct argp_option options[] = { - {"debug", 'D', 0, 0, "Toggle debugging output" }, + {"debug", 'D', 0, 0, "Toggle debugging output" +#ifndef EXT2FS_DEBUG + " (not compiled in)" +#endif + }, + {"sblock", 'S', "BLOCKNO", 0, + "Use alternate superblock location (1kb blocks)"}, {0} }; @@ -65,19 +78,50 @@ options[] = static error_t parse_opt (int key, char *arg, struct argp_state *state) { + /* We save our parsed values in this structure, hung off STATE->hook. + Only after parsing all options successfully will we use these values. */ + struct + { + int debug_flag; + unsigned int sb_block; + } *values = state->hook; + switch (key) { case 'D': - state->hook = (void *)1; /* Do it at the end */ + values->debug_flag = 1; + break; + case 'S': + values->sb_block = strtoul (arg, &arg, 0); + if (!arg || *arg != '\0') + { + argp_error (state, "invalid number for --sblock"); + return EINVAL; + } break; case ARGP_KEY_INIT: - state->hook = 0; + state->child_inputs[0] = state->input; + values = malloc (sizeof *values); + if (values == 0) + return ENOMEM; + state->hook = values; + bzero (values, sizeof *values); + values->sb_block = SBLOCK_BLOCK; break; + case ARGP_KEY_SUCCESS: /* All options parse successfully, so implement ours if possible. */ - if (state->hook) - ext2_debug_flag = !ext2_debug_flag; + if (values->debug_flag) + { +#ifdef EXT2FS_DEBUG + ext2_debug_flag = !ext2_debug_flag; +#else + argp_failure (state, 2, 0, "debugging support not compiled in"); + return EINVAL; +#endif + } + break; default: @@ -85,89 +129,59 @@ parse_opt (int key, char *arg, struct argp_state *state) } return 0; } - -/* Add our startup arguments to the standard diskfs set. */ -static const struct argp *startup_parents[] = { &diskfs_std_device_startup_argp, 0}; -static struct argp startup_argp = {options, parse_opt, 0, 0, startup_parents}; - -/* Similarly at runtime. */ -static const struct argp *runtime_parents[] = {&diskfs_std_runtime_argp, 0}; -static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_parents}; - -struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; /* Override the standard diskfs routine so we can add our own output. */ error_t -diskfs_get_options (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, size_t *argz_len) { error_t err; - *argz = 0; - *argz_len = 0; - /* Get the standard things. */ err = diskfs_append_std_options (argz, argz_len); +#ifdef EXT2FS_DEBUG if (!err && ext2_debug_flag) - { - err = argz_add (argz, argz_len, "--debug"); - if (err) - free (argz); /* Deallocate what diskfs returned. */ - } + err = argz_add (argz, argz_len, "--debug"); +#endif + if (! err) + err = store_parsed_append_args (store_parsed, argz, argz_len); return err; } + +/* Add our startup arguments to the standard diskfs set. */ +static const struct argp_child startup_children[] = + {{&diskfs_store_startup_argp}, {0}}; +static struct argp startup_argp = {options, parse_opt, 0, 0, startup_children}; -#else /* !EXT2FS_DEBUG */ - -#define startup_argp diskfs_std_device_startup_argp +/* Similarly at runtime. */ +static const struct argp_child runtime_children[] = + {{&diskfs_std_runtime_argp}, {0}}; +static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_children}; -#endif /* EXT2FS_DEBUG */ +struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; -void +int main (int argc, char **argv) { error_t err; - mach_port_t bootstrap = MACH_PORT_NULL; - - argp_parse (&startup_argp, argc, argv, 0, 0, 0); + mach_port_t bootstrap; - diskfs_console_stdio (); + /* 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); - if (! diskfs_boot_flags) - { - 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. This must come before - any other diskfs call. */ - err = diskfs_init_diskfs (); - if (err) - error (4, err, "init"); - - err = diskfs_device_open (); - if (err) - error (3, err, "%s", diskfs_device_arg); - - if ((diskfs_device_size << diskfs_log2_device_block_size) - < SBLOCK_OFFS + SBLOCK_SIZE) - ext2_panic ("superblock won't fit on the device!"); - if (diskfs_log2_device_block_size == 0) - ext2_panic ("device block size (%u) not a power of two", - diskfs_device_block_size); - if (diskfs_log2_device_blocks_per_page < 0) - ext2_panic ("device block size (%u) greater than page size (%d)", - diskfs_device_block_size, vm_page_size); + if (store->size < SBLOCK_OFFS + SBLOCK_SIZE) + ext2_panic ("device too small for superblock (%Ld bytes)", store->size); + if (store->log2_blocks_per_page < 0) + ext2_panic ("device block size (%zu) greater than page size (%zd)", + store->block_size, vm_page_size); /* Map the entire disk. */ create_disk_pager (); - /* Start the first request thread, to handle RPCs and page requests. */ - diskfs_spawn_first_thread (); - - pokel_init (&global_pokel, disk_pager, disk_image); + pokel_init (&global_pokel, diskfs_disk_pager, disk_image); get_hypermetadata(); @@ -188,49 +202,15 @@ main (int argc, char **argv) /* and so we die, leaving others to do the real work. */ cthread_exit (0); + /* NOTREACHED */ + return 0; } error_t diskfs_reload_global_state () { pokel_flush (&global_pokel); - pager_flush (disk_pager, 1); + pager_flush (diskfs_disk_pager, 1); get_hypermetadata (); return 0; } - -/* ---------------------------------------------------------------- */ - -static spin_lock_t free_page_bufs_lock = SPIN_LOCK_INITIALIZER; -static vm_address_t free_page_bufs = 0; - -/* Returns a single page page-aligned buffer. */ -vm_address_t get_page_buf () -{ - vm_address_t buf; - - spin_lock (&free_page_bufs_lock); - - buf = free_page_bufs; - if (buf == 0) - { - spin_unlock (&free_page_bufs_lock); - vm_allocate (mach_task_self (), &buf, vm_page_size, 1); - } - else - { - free_page_bufs = *(vm_address_t *)buf; - spin_unlock (&free_page_bufs_lock); - } - - return buf; -} - -/* Frees a block returned by get_page_buf. */ -void free_page_buf (vm_address_t buf) -{ - spin_lock (&free_page_bufs_lock); - *(vm_address_t *)buf = free_page_bufs; - free_page_bufs = buf; - spin_unlock (&free_page_bufs_lock); -} |