/* Main entry point for the ext2 file system translator Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. Converted for ext2fs by Miles Bader 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 #include #include #include #include #include #include #include #include "ext2fs.h" /* ---------------------------------------------------------------- */ int diskfs_link_max = EXT2_LINK_MAX; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; int diskfs_shortcut_chrdev = 1; int diskfs_shortcut_blkdev = 1; 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; int diskfs_synchronous = 0; int diskfs_readonly = 0; struct node *diskfs_root_node; void main (int argc, char **argv) { error_t err; mach_port_t bootstrap = MACH_PORT_NULL; argp_parse (diskfs_std_device_startup_argp, argc, argv, 0, 0, 0); diskfs_console_stdio (); 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); /* 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); get_hypermetadata(); inode_init (); /* Set diskfs_root_node to the root inode. */ err = diskfs_cached_lookup (EXT2_ROOT_INO, &diskfs_root_node); if (err) ext2_panic ("can't get root: %s", strerror (err)); else if ((diskfs_root_node->dn_stat.st_mode & S_IFMT) == 0) ext2_panic ("no root node!"); mutex_unlock (&diskfs_root_node->lock); /* Now that we are all set up to handle requests, and diskfs_root_node is set properly, it is safe to export our fsys control port to the outside world. */ diskfs_startup_diskfs (bootstrap, 0); /* and so we die, leaving others to do the real work. */ cthread_exit (0); } error_t diskfs_reload_global_state () { pokel_flush (&global_pokel); pager_flush (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); }