aboutsummaryrefslogtreecommitdiff
path: root/ext2fs/ext2fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext2fs/ext2fs.c')
-rw-r--r--ext2fs/ext2fs.c196
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);
-}