aboutsummaryrefslogtreecommitdiff
path: root/libdiskfs
diff options
context:
space:
mode:
Diffstat (limited to 'libdiskfs')
-rw-r--r--libdiskfs/=exc.c141
-rw-r--r--libdiskfs/ChangeLog2492
-rw-r--r--libdiskfs/Makefile44
-rw-r--r--libdiskfs/boot-parse.c193
-rw-r--r--libdiskfs/boot-start.c384
-rw-r--r--libdiskfs/conch-fetch.c4
-rw-r--r--libdiskfs/console.c30
-rw-r--r--libdiskfs/dev-globals.c46
-rw-r--r--libdiskfs/dev-io.c54
-rw-r--r--libdiskfs/dev-open.c66
-rw-r--r--libdiskfs/dir-chg.c50
-rw-r--r--libdiskfs/dir-clear.c2
-rw-r--r--libdiskfs/dir-init.c10
-rw-r--r--libdiskfs/dir-link.c30
-rw-r--r--libdiskfs/dir-lookup.c246
-rw-r--r--libdiskfs/dir-mkdir.c7
-rw-r--r--libdiskfs/dir-mkfile.c35
-rw-r--r--libdiskfs/dir-readdir.c10
-rw-r--r--libdiskfs/dir-rename.c24
-rw-r--r--libdiskfs/dir-renamed.c62
-rw-r--r--libdiskfs/dir-rmdir.c60
-rw-r--r--libdiskfs/dir-unlink.c18
-rw-r--r--libdiskfs/direnter.c9
-rw-r--r--libdiskfs/dirremove.c17
-rw-r--r--libdiskfs/dirrewrite.c13
-rw-r--r--libdiskfs/disk-pager.c68
-rw-r--r--libdiskfs/diskfs-pager.h20
-rw-r--r--libdiskfs/diskfs.h600
-rw-r--r--libdiskfs/extern-inline.c (renamed from libdiskfs/ports-consts.c)8
-rw-r--r--libdiskfs/extra-version.c (renamed from libdiskfs/ports-noports.c)21
-rw-r--r--libdiskfs/fhandle.h36
-rw-r--r--libdiskfs/file-access.c6
-rw-r--r--libdiskfs/file-chauthor.c5
-rw-r--r--libdiskfs/file-chflags.c12
-rw-r--r--libdiskfs/file-chg.c50
-rw-r--r--libdiskfs/file-chmod.c56
-rw-r--r--libdiskfs/file-chown.c36
-rw-r--r--libdiskfs/file-exec.c152
-rw-r--r--libdiskfs/file-get-fs-opts.c22
-rw-r--r--libdiskfs/file-get-trans.c42
-rw-r--r--libdiskfs/file-get-transcntl.c9
-rw-r--r--libdiskfs/file-getcontrol.c40
-rw-r--r--libdiskfs/file-getfh.c68
-rw-r--r--libdiskfs/file-inv-trans.c160
-rw-r--r--libdiskfs/file-reparent.c70
-rw-r--r--libdiskfs/file-set-size.c12
-rw-r--r--libdiskfs/file-set-trans.c16
-rw-r--r--libdiskfs/file-statfs.c22
-rw-r--r--libdiskfs/file-utimes.c30
-rw-r--r--libdiskfs/filedev.c135
-rw-r--r--libdiskfs/fsmutations.h10
-rw-r--r--libdiskfs/fsys-getfile.c126
-rw-r--r--libdiskfs/fsys-getroot.c101
-rw-r--r--libdiskfs/fsys-options.c16
-rw-r--r--libdiskfs/ifsock.c2
-rw-r--r--libdiskfs/init-completed.c32
-rw-r--r--libdiskfs/init-first.c22
-rw-r--r--libdiskfs/init-init.c21
-rw-r--r--libdiskfs/init-loop.c28
-rw-r--r--libdiskfs/init-main.c78
-rw-r--r--libdiskfs/init-startup.c116
-rw-r--r--libdiskfs/interrupt.c39
-rw-r--r--libdiskfs/io-duplicate.c3
-rw-r--r--libdiskfs/io-identity.c34
-rw-r--r--libdiskfs/io-map-cntl.c6
-rw-r--r--libdiskfs/io-map.c13
-rw-r--r--libdiskfs/io-pathconf.c56
-rw-r--r--libdiskfs/io-prenotify.c6
-rw-r--r--libdiskfs/io-read.c44
-rw-r--r--libdiskfs/io-reauthenticate.c63
-rw-r--r--libdiskfs/io-restrict-auth.c43
-rw-r--r--libdiskfs/io-revoke.c (renamed from libdiskfs/io-interrupt.c)42
-rw-r--r--libdiskfs/io-seek.c64
-rw-r--r--libdiskfs/io-stat.c17
-rw-r--r--libdiskfs/io-version.c10
-rw-r--r--libdiskfs/io-write.c13
-rw-r--r--libdiskfs/lithp.h3
-rw-r--r--libdiskfs/lookup.c191
-rw-r--r--libdiskfs/machdev.c92
-rw-r--r--libdiskfs/name-cache.c128
-rw-r--r--libdiskfs/node-create.c68
-rw-r--r--libdiskfs/node-drop.c28
-rw-r--r--libdiskfs/node-make.c17
-rw-r--r--libdiskfs/node-nput.c75
-rw-r--r--libdiskfs/node-nputl.c38
-rw-r--r--libdiskfs/node-nref.c40
-rw-r--r--libdiskfs/node-nrefl.c (renamed from libdiskfs/opts-runtime-parse.c)20
-rw-r--r--libdiskfs/node-nrele.c65
-rw-r--r--libdiskfs/node-nrelel.c39
-rw-r--r--libdiskfs/node-rdwr.c2
-rw-r--r--libdiskfs/node-times.c64
-rw-r--r--libdiskfs/notify-nosenders.c39
-rw-r--r--libdiskfs/notify-stubs.c71
-rw-r--r--libdiskfs/opts-append-std.c42
-rw-r--r--libdiskfs/opts-common.c28
-rw-r--r--libdiskfs/opts-get.c9
-rw-r--r--libdiskfs/opts-runtime.c3
-rw-r--r--libdiskfs/opts-set.c4
-rw-r--r--libdiskfs/opts-std-runtime.c47
-rw-r--r--libdiskfs/opts-std-startup.c125
-rw-r--r--libdiskfs/opts-version.c17
-rw-r--r--libdiskfs/ourfs_notify.defs5
-rw-r--r--libdiskfs/peropen-make.c44
-rw-r--r--libdiskfs/peropen-rele.c22
-rw-r--r--libdiskfs/ports-clean.c29
-rw-r--r--libdiskfs/ports-idle.c36
-rw-r--r--libdiskfs/ports-soft.c25
-rw-r--r--libdiskfs/priv.h68
-rw-r--r--libdiskfs/protid-make.c46
-rw-r--r--libdiskfs/protid-rele.c8
-rw-r--r--libdiskfs/rdwr-internal.c13
-rw-r--r--libdiskfs/readonly-changed.c31
-rw-r--r--libdiskfs/readonly.c30
-rw-r--r--libdiskfs/shutdown.c25
-rw-r--r--libdiskfs/sync-default.c6
-rw-r--r--libdiskfs/sync-interval.c19
-rw-r--r--libdiskfs/trans-callback.c37
117 files changed, 3144 insertions, 5303 deletions
diff --git a/libdiskfs/=exc.c b/libdiskfs/=exc.c
deleted file mode 100644
index ced9c5b9..00000000
--- a/libdiskfs/=exc.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- Copyright (C) 1994, 1995 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. */
-
-#include "priv.h"
-
-/* List of preempters that are around. */
-struct preempt_record
-{
- struct preempt_record *next;
- struct hurd_signal_preempt preempter1, preempter2;
- struct pager *p;
- vm_address_t off;
- void *addr;
- long len;
-};
-
-static struct preempt_record *preempt_list;
-static spin_lock_t preempt_list_lock = SPIN_LOCK_INITIALIZER;
-
-/* This special signal handler is run anytime we have taken a fault on
- a page that we map (registered through
- diskfs_register_memory_fault_area). What we do is just longjmp to the
- context saved on the stack by diskfs_catch_exception. */
-static void
-special_segv_handler (int code, int subcode, int error)
-{
- struct preempt_record *rec;
- struct thread_stuff *stack_record;
-
- /* SUBCODE is the address and ERROR is the error returned by the
- pager through the kernel. But because there is an annoying
- kernel bug (or rather unimplemented feature) the errors are not
- actually passed back. So we have to scan the list of preempt
- records and find the one that got us here, and then query the
- pager to find out what error it gave the kernel. */
- spin_lock (&preempt_list_lock);
- for (rec = preempt_list; rec; rec = rec->next)
- if ((void *)subcode >= rec->addr
- && (void *)subcode < rec->addr + rec->len)
- break;
- assert (rec);
- spin_unlock (&preempt_list_lock);
- error = pager_get_error (rec->p, rec->off + (void *)subcode - rec->addr);
-
- /* Now look up the stack record left by diskfs_catch_exception, consuming it
- on the way */
- stack_record = (struct thread_stuff *) cthread_data (cthread_self ());
- assert (stack_record);
- cthread_set_data (cthread_self (), (any_t)stack_record->link);
-
- /* And return to it... */
- longjmp (&stack_record->buf, error);
-
- abort ();
-}
-
-/* Return a signal handler for a thread which has faulted inside a
- region registered as expecting such faults. This routine runs
- inside the library's signal thread, and accordingly must be
- careful. */
-static sighandler_t
-segv_preempter (thread_t thread, int signo,
- long int sigcode, int sigerror)
-{
- /* Just assume that everything is cool (how could it not be?)
- and return our special handler above. */
- return special_segv_handler;
-}
-
-/* Mark the memory at ADDR continuing for LEN bytes as mapped from pager P
- at offset OFF. Call when vm_map-ing part of the disk. */
-void
-diskfs_register_memory_fault_area (struct pager *p,
- vm_address_t off,
- void *addr,
- long len)
-{
- struct preempt_record *rec = malloc (sizeof (struct preempt_record));
-
- hurd_preempt_signals (&rec->preempter1, SIGSEGV, addr, addr + len,
- segv_preempter);
- hurd_preempt_signals (&rec->preempter2, SIGBUS, addr, addr + len,
- segv_preempter);
- rec->p = p;
- rec->off = off;
- rec->addr = addr;
- rec->len = len;
-
- spin_lock (&preempt_list_lock);
- rec->next = preempt_list;
- preempt_list = rec;
- spin_unlock (&preempt_list_lock);
-}
-
-/* Mark the memory at ADDR continuing for LEN bytes as no longer
- mapped from the disk. Call when vm_unmap-ing part of the disk. */
-void
-diskfs_unregister_memory_fault_area (void *addr,
- long len)
-{
- struct preempt_record *rec, **prevp;
-
- spin_lock (&preempt_list_lock);
- for (rec = preempt_list, prevp = &preempt_list;
- rec;
- rec = rec->next, prevp = &rec->next)
- if (rec->addr == addr && rec->len == len)
- {
- /* This is it, make it go away. */
- *prevp = rec->next;
- spin_unlock (&preempt_list_lock);
- hurd_unpreempt_signals (&rec->preempter1, SIGSEGV);
- hurd_unpreempt_signals (&rec->preempter2, SIGBUS);
- free (rec);
- return;
- }
- spin_unlock (&preempt_list_lock);
-
- /* Not found */
- assert (0);
-}
-
-/* Set up the exception handling system. */
-void
-init_exceptions ()
-{
-}
diff --git a/libdiskfs/ChangeLog b/libdiskfs/ChangeLog
deleted file mode 100644
index 6d0fa719..00000000
--- a/libdiskfs/ChangeLog
+++ /dev/null
@@ -1,2492 +0,0 @@
-Thu Aug 1 17:24:08 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
-
- * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): Don't
- diskfs_nput NP; we've never created a reference. Just unlock it.
- (And bother to lock it in the first place.)
-
-Sat Jul 27 20:05:17 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * lookup.c (diskfs_lookup): Don't nput *NP if we didn't find a file.
-
- * init-startup.c (diskfs_S_startup_dosync): Clean up after ourselves.
- Don't sync if DISKFS_READONLY.
- * file-syncfs.c (diskfs_S_file_syncfs): Don't sync if DISKFS_READONLY.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs): Likewise.
- * sync-interval.c (periodic_sync): Likewise.
- * shutdown.c (diskfs_shutdown): Likewise.
-
-Fri Jul 26 14:52:23 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Unlock NP before we attempt to
- do setuid/setgid (which otherwise can deadlock during port reauth).
- Pay attention to the error code returned by fshelp_exec_reauth,
- and don't make NEWPI if it's an error.
- Initialize ERR.
-
-Tue Jul 23 16:05:55 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-version.c (_print_version): Make return type void.
-
-Fri Jul 19 21:19:42 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * filedev.c (diskfs_get_file_device): INTS[3] contains the number
- of runs, not the number of offsets (which is 2*NUM_RUNS).
- Don't deallocate the device port we've fetched.
-
- * opts-std-startup.c (startup_options, parse_startup_opt): Remove
- the --version option, which is handled elsewhere now.
-
-Thu Jul 18 23:05:56 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * protid-make.c (diskfs_start_protid): Use noinstall version of
- ports_create_port.
- (diskfs_finish_protid): Install port right into port set here.
-
-Mon Jul 15 21:37:12 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_checkdirmod): diskfs_isowner returns error or
- zero, so invert sense of tests.
-
- * lookup.c (diskfs_lookup): If we get an error from
- diskfs_checkdirmod, diskfs_nput the node we picked up; the caller
- won't want it.
-
- * dir-renamed.c (diskfs_rename_dir): When unlocking FDP, only do
- it if we FDP != TDP. Also, only do step two (changing .. in the
- directory being moved) if FDP != TDP.
-
-Sat Jul 13 20:05:27 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Repeat
- diskfs_start_protid and auth_server_authenticate for as we get
- EINTR.
-
-Sun Jul 7 21:07:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_S_fsys_init): Don't use unsafe MOVE_SEND in
- call to exec_init.
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Don't use
- unsafe MOVE_SEND in auth_server_authenticate.
-
-Sun Jul 7 10:27:37 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-version.c (_print_version): Include HURD_RELEASE in default.
-
-Sat Jul 6 16:27:01 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-version.c: New file.
- * Makefile (OTHERSRCS): Add opts-version.c.
-
-Sat Jul 6 13:32:58 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * node-drop.c (diskfs_drop_node): If this might be a special
- symlink, then truncate it even though NP->allocsize might be
- clear.
-
-Wed Jul 3 11:22:58 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * io-identity.c (diskfs_S_io_identity): Fetch identity using
- fshelp_get_identity rather than creating it ourselves.
- * diskfs.h (struct node): Remove member `identity'.
- * node-drop.c (diskfs_drop_node): Don't deallocate NP->identity.
- * node-make.c (diskfs_make_node): Don't initialize NP->identity.
-
-Thu Jun 27 10:07:03 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * init-startup.c (diskfs_startup_diskfs): Don't call
- diskfs_readonly_changed here anymore.
-
- * disk-pager.c (disk_pager_setup): Check diskfs_readonly variable
- instead of calling diskfs_check_readonly.
-
- * Makefile (LCLHDRS): Add diskfs-pager.h.
-
-Tue Jun 25 21:55:24 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-std-runtime.c (parse_opt): Add hair to share arg parsing
- state between two parsers that use the same parse_opt function at
- the same time.
-
-Mon Jun 24 14:55:50 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * init-startup.c (diskfs_S_startup_dosync): Don't crash the
- filesystem, just do a clean sync.
- * node-drop.c (diskfs_drop_node): Call diskfs_check_readonly
- before making mods.
- * priv.h (_diskfs_diskdirty): New variable.
- * diskfs.h (diskfs_check_readonly): New function.
- * readonly.c (_diskfs_diskdirty): New var.
- (diskfs_check_readonly): New function.
- (diskfs_set_readonly): After clean sync, clear _diskfs_diskdirty.
- * rdwr-internal.c (_diskfs_rdwr_internal): Use
- diskfs_check_readonly instead of diskfs_readonly.
- * node-create.c (diskfs_create_node): Likewise.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
- * file-set-trans.c (diskfs_S_file_set_translator): Likewise.
- * disk-pager.c (disk_pager_setup): Likewise.
- * dir-unlink.c (diskfs_S_dir_unlink): Likewise.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise.
- * dir-rename.c (diskfs_S_dir_rename): Likewise.
- * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise.
- * dir-mkdir.c (diskfs_S_dir_mkdir): Likewise.
- * dir-lookup.c (diskfs_S_dir_lookup): Likewise.
- * dir-link.c (diskfs_S_dir_link): Likewise.
- * conch-fetch.c (iohelp_fetch_shared_data): Likewise.
- * remount.c (diskfs_remount): Likewise.
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): If
- auth_server_authenticate fails, then fill with empty IDs. We
- can't permit interruption, because this is a simpleroutine.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Validate rdev
- change before making it.
- * file-chflags.c (diskfs_S_file_chflags): Validate flags change
- before making it.
- * lithp.h (dithkfth_validate_author_change): New macro.
- * file-chauthor.c (dithkfth_TH_file_chauthor): Validate new author
- before changing it.
- * node-create.c (diskfs_create_node): Validate group change before
- making it.
- * file-chown.c (diskfs_S_file_chown): Likewise.
- * node-create.c (diskfs_create_node): Validate mode change before
- making it.
- * file-set-trans.c (diskfs_S_file_set_translator): Likewise
- * file-chmod.c (diskfs_S_file_chmod): Likewise.
- * node-create.c (diskfs_creade_node): Validate owner change before
- making it.
- * file-chown.c (diskfs_S_file_chown): Likewise.
- * Makefile (OTHERSRCS): Add validate-mode.c, validate-group.c,
- validate-author.c, validate-flags.c, validate-rdev.c, and
- validate-owner.c.
- * validate-mode.c, validate-group.c, validate-author.c,
- validate-flags.c, validate-rdev.c, validate-owner.c: New files.
- * diskfs.h (diskfs_validate_mode_change,
- diskfs_validate_owner_change, diskfs_validate_group_change,
- diskfs_validate_author_change, diskfs_validate_flags_change,
- diskfs_validate_rdev_change): New decls.
-
-Fri Jun 21 00:18:16 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * fsys-options.c (diskfs_S_fsys_get_options): Use
- fshelp_return_malloced_buffer to setup the return data.
- * file-get-fs-opts.c (diskfs_S_file_get_fs_options): Likewise.
- * opts-set.c (diskfs_set_options): Supply INPUT arg to
- fshelp_set_options.
-
- * opts-append-std.c (diskfs_append_std_options): Use argz_add
- instead of rolling our own. Deal with errors.
- <argz.h>: New include.
-
-Wed Jun 19 21:57:46 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * init-startup.c (diskfs_S_startup_dosync): Pass HANDLE to
- ports_lookup_port. Declare ERR.
-
- * opts-get.c (diskfs_get_options): Call diskfs_append_std_options to
- do most of the work.
- * opts-append-std.c: New file.
- * opts-set.c: New file (old version renamed).
- * opts-std-runtime.c: Renamed from opts-set.c.
- (diskfs_set_options): Function removed.
- (struct parse_hook): New type.
- (set_opts, parse_opt): New functions.
- (common_argp, parents, diskfs_std_runtime_argp): New variables.
- * diskfs.h (diskfs_parse_runtime_options): Decl removed.
- (diskfs_std_startup_argp): Renamed from diskfs_startup_argp, now a
- structure decl, not a pointer decl.
- (diskfs_std_device_startup_argp): Renamed from
- diskfs_device_startup_argp, now a structure decl, not a pointer
- decl.
- (diskfs_set_options): Update decl (now takes argz & argz_len).
- (diskfs_runtime_arg): New declaration.
- (diskfs_std_runtime_argp, diskfs_append_std_options): New declarations.
- * opts-runtime-parse.c, opts-runtime-unparse.c: Files removed.
- * opts-std-startup.c (parse_dev_startup_opt): Use argp_error.
- (diskfs_startup_arg, diskfs_device_startup_arg): Variables removed.
- (diskfs_std_startup_argp): Renamed from startup_argp, exported.
- (diskfs_std_device_startup_argp): Renamed from dev_startup_argp,
- exported.
- * fsys-options.c (diskfs_S_fsys_set_options): Don't split
- arguments, just call diskfs_set_options with what we got.
- * opts-runtime.c: New file.
- * Makefile (OTHERSRCS): Add opts-std-runtime.c, opts-append-std.c,
- opts-runtime.c. Remove opts-runtime-parse.c, opts-runtime-unparse.c
-
-Thu Jun 13 10:05:51 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * Makefile (MIGSTUBS): Add startup_notifyServer.o.
- * init-startup.c (diskfs_S_startup_dosync): Uncomment function.
- * demuxer.c (diskfs_demuxer): Call diskfs_startup_notify_server.
- * init-startup.c (_diskfs_init_completed): NOTIFY doesn't need
- deallocation.
-
- * boot-start.c (diskfs_S_fsys_init): Build version string
- correctly.
-
-Tue May 14 11:14:12 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * Makefile (OTHERSRCS): Remove init-completed.c.
-
- * node-drop.c (diskfs_drop_node): Fix typo.
-
-Sat May 11 01:11:19 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-std-startup.c (parse_dev_startup_opt, parse_startup_opt):
- Use ARGP_ERR_UNKNOWN instead of EINVAL.
- * opts-set.c (diskfs_set_options): Likewise.
-
-Fri May 10 17:15:51 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * io-identity.c: New file.
- * Makefile (IOSRCS): Add io-identity.c.
- * diskfs.h (diskfs_fsys_identity): New variable.
- (struct node): New member `identity'.
- * init-init.c (diskfs_fsys_identity): New variable.
- (diskfs_init_diskfs): Initialize diskfs_fsys_identity.
- * node-make.c (diskfs_make_node): Initialize NP->identity.
- * node-drop.c (diskfs_drop_node): Free NP->identity if it's been
- allocated.
-
-Thu May 9 11:52:52 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * protid-make.c (diskfs_make_protid): Delete function.
- * diskfs.h (diskfs_make_protid): Delete declaration.
-
- * init-startup.c (_diskfs_init_completed): Don't need to insert
- right any more now that it's a poly arg.
- Provide helpful name to init.
-
- * fsys-options.c (diskfs_S_fsys_get_options): Accept and ignore
- replyport parameters.
-
- * file-sync.c (diskfs_S_file_sync): Accept and ignore new parm
- OMITMETADATA.
-
- * priv.h: ioserver.h -> iohelp.h.
- * diskfs.h: Likewise.
- * file-sync.c (diskfs_S_file_sync): s/ioserver/iohelp/g
- * io-prenotify.c (diskfs_S_io_prenotify): Likewise.
- * io-get-conch.c (diskfs_S_io_get_conch): Likewise.
- * io-modes-off.c (diskfs_S_io_clear_some_openmodes): Likewise.
- * io-modes-on.c (diskfs_S_io_set_some_openmodes): Likewise.
- * io-modes-set.c (diskfs_S_io_set_all_openmodes): Likewise.
- * io-read.c (diskfs_S_io_read): Likewise.
- * io-readable.c (diskfs_S_io_readable): Likewise.
- * io-rel-conch.c (diskfs_S_io_release_conch): Likewise.
- * io-seek.c (diskfs_S_io_seek): Likewise.
- * io-stat.c (diskfs_S_io_stat): Likewise.
- * io-write.c (diskfs_S_io_write): Likewise.
- * conch-fetch.c (iohelp_fetch_shared_data): Likewise.
- * conch-set.c (iohelp_put_shared_data): Likewise.
- * node-make.c (diskfs_make_node): Likewise.
- * node-rdwr.c (diskfs_node_rdwr): Likewise.
- * Makefile (libdiskfs.so): Likewise.
-
- * dir-rename.c (diskfs_S_dir_rename): Understand new parm EXCL and
- do the right thing with it.
- * dir-link.c (diskfs_S_dir_link): Likewise.
-
-Thu May 9 12:12:41 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Don't pass CRED
- port in auth_server_authenticate.
-
- * io-select.c (diskfs_S_io_select): Removed TAG arg.
-
-Thu May 9 11:42:53 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * filedev.c (diskfs_get_file_device): Deallocate most things we
- got back from file_get_storage_info even if we didn't get an error.
-
- * filedev.c (diskfs_get_file_device): Fix type of DATA & _DATA.
- BLOCKSIZE -> BLOCK_SIZE. Copy name from DATA, not DEV_NAME_BUF.
-
-Mon May 6 20:12:34 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * filedev.c (diskfs_get_file_device): Enable new version.
-
-Fri May 3 15:55:44 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * filedev.c [0] (diskfs_get_file_device): Rewrite to use new interface.
-
-Tue Apr 30 14:39:06 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * init-startup.c: Include <string.h> and <hurd/startup.h>.
- (diskfs_startup_diskfs): If not bootstrap filesystem, call
- _diskfs_init_completed here.
- (diskfs_S_startup_dosync): New function (commented out).
- (_diskfs_init_completed): New function.
- * init-completed.c: Delete file.
- * init-init.c (diskfs_shutdown_notification_class): New variable.
- (diskfs_init_diskfs): Initialize diskfs_shutdown_notification_class.
- * diskfs.h (diskfs_shutdown_notification_class): New variable.
- * boot-start.c (diskfs_S_fsys_init): diskfs_init_completed ->
- _diskfs_init_completed.
- * priv.h (_diskfs_init_completed): New declaration.
- * diskfs.h (diskfs_init_completed): Delete function.
-
-Mon Apr 29 15:42:23 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * name-cache.c (struct lookup_cache): Add HDR, remove NEXT & PREV.
- (lookup_cache): Change type to struct cacheq.
- (mru_cache, lru_cache): Variables removed.
- (make_mru, make_lru, init_lookup_cache): Functions removed.
- (find_cache, diskfs_purge_lookup_cache,
- diskfs_check_lookup_cache): Use cacheq functions.
-
-Sun Apr 28 15:22:30 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-
- * protid-make.c: Add obsolescence link warning.
-
-Tue Apr 23 11:05:04 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * node-drop.c (diskfs_drop_node): Don't do anything special for
- socket naming points.
- * Makefile (OTHERSRCS): Add dead-name.c.
- * dead-name.c: New file.
- * ifsock.c (diskfs_S_ifsock_getsockaddr): Request notification for
- new SOCKADDR; count that notification as a reference.
-
-Fri Apr 12 15:56:48 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * name-cache.c (diskfs_enter_lookup_cache): Never cache . or ..
-
-Thu Apr 11 17:59:18 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * console.c: Include <hurd.h>.
-
- * Makefile (fsys-MIGSFLAGS, fs-MIGSFLAGS, io-MIGSFLAGS,
- ifsock-MIGSFLAGS): Reference fsmutations.h in $(srcdir).
-
- * boot-start.c (diskfs_start_bootstrap): Print helpful message
- before doing anything else.
-
-Wed Apr 10 16:47:21 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * name-cache.c (struct lookup_cache): Add NEXT & PREV fields.
- Rename LEN back to NAME_LEN.
- (lru_cache, mru_cache): New variables.
- (first_cache, last_cache): Variables removed.
- (make_mru, make_lru, find_cache, init_lookup_cache): New functions.
- (diskfs_enter_lookup_cache, diskfs_purge_lookup_cache,
- diskfs_check_lookup_cache): Rewrite to use the linked list. Deal
- with negative entries.
-
-Tue Apr 9 12:59:02 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * lookup.c (diskfs_lookup): Deal with DS or NP being 0.
- * name-cache.c (diskfs_check_lookup_cache): Correctly handle the
- case where the lookup returns DIR itself.
-
- * diskfs.h (diskfs_enter_lookup_cache, diskfs_purge_lookup_cache,
- diskfs_check_lookup_cache): Renamed from versions without `lookup_'.
- * name-cache.c (diskfs_enter_lookup_cache, diskfs_purge_lookup_cache,
- diskfs_check_lookup_cache): Likewise.
- * direnter.c (diskfs_direnter): Similarly, rename use.
- * dirrewrite.c (diskfs_dirrewrite): Likewise.
- * dirremove.c (diskfs_dirremove): Likewise.
- * lookup.c (diskfs_lookup): Likewise.
-
-Sun Apr 7 15:29:02 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * name-cache.c (diskfs_check_cache): Declare I.
- (struct lookup_cache, diskfs_enter_cache): Change NAMELEN field to LEN.
-
-Wed Apr 3 16:02:45 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * node-drop.c (diskfs_drop_node): Don't call
- _diskfs_purge_cache_deletion.
- * name-cache.c (_diskfs_purge_cache_deletion): Delete function.
-
- * diskfs.h (diskfs_cached_lookup): New declaration.
- (struct node): New member `cache_id'.
-
-Tue Apr 2 12:50:31 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * name-cache.c (diskfs_enter_cache): Don't set LC->next->prev if
- LC->next is null.
- (diskfs_purge_cache): If freeing node at LOOKUP_CACHE_TAIL, bump
- LOOKUP_CACHE_TAIL back itself too.
- (_diskfs_purge_cache_deletion): Likewise.
-
- * lookup.c (diskfs_lookup): When doing diskfs_checkdirmod check,
- don't return success when we should return ENOENT, just because
- checkdirmod won. Also enter successful lookups for CREATE or
- LOOKUP in the name cache.
-
-Fri Mar 29 13:57:37 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
-
- * io-map-cntl.c: Initialize shared page magic number.
-
-Mon Mar 25 09:30:31 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * name-cache.c (statistics): New variable.
- (diskfs_check_cache): Keep statistics on cache performance.
-
-Fri Mar 22 17:51:51 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-runtime-parse.c (diskfs_parse_runtime_options): Supply new
- argument to argp_parse.
-
-Fri Mar 22 15:44:10 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * lookup.c (diskfs_lookup): Dereference NP in call to
- diskfs_checkdirmod.
- * direnter.c (diskfs_direnter): Don't fall off end.
- * diskfs.h (diskfs_enter_cache, diskfs_purge_cache,
- diskfs_check_cache): Add declarations.
- * dir-rename.c (diskfs_S_dir_rename): Use new args for
- diskfs_dirrewrite and diskfs_dirremove.
- * dir-renamed.c (diskfs_rename_dir): Likewise.
- * dir-clear.c (diskfs_clear_directory): Use new diskfs_dirremove
- args.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise.
- * dir-unlink.c (diskfs_S_dir_unlink): Likewise.
-
- * Makefile (OTHERSRCS): Add direnter.c, dirrewrite.c, dirremove.c,
- and lookup.c.
-
-Wed Mar 20 14:34:22 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_lookup_hard): Remove mention of ENOTDIR and
- EACCES errors.
- * diskfs.h (diskfs_null_dirstat): New function.
- * dir-lookup.c (diskfs_S_dir_lookup): Don't check cache here.
- * dir-unlink.c (diskfs_S_dir_unlink): Don't frob cache here.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise.
- * dir-clear.c (diskfs_clear_directory): Likewise.
- * node-create.c (diskfs_create_node): Likewise.
- * dir-renamed.c (diskfs_rename_dir): Likewise.
- * dir-rename.c (diskfs_S_dir_rename): Likewise.
- * dir-link.c (diskfs_S_dir_link): Likewise.
- * direnter.c: New file.
- * dirrewrite.c: Likewise.
- * dirremove.c: Likewise.
- * lookup.c: Likewise.
- * diskfs.h (diskfs_lookup): Renamed to be diskfs_lookup_hard.
- (diskfs_direnter): Renamed to be diskfs_direnter_hard.
- (diskfs_dirrewrite): Renamed to be diskfs_dirrewrite_hard.
- (diskfs_dirremove): Renamed to be diskfs_dirremove_hard.
- (diskfs_lookup, diskfs_direnter, diskfs_dirrewrite, diskfs_dirremove):
-
-Tue Mar 19 14:55:46 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * name-cache.c: New file.
- * Makefile (OTHERSRCS): Add name-cache.c.
- * dir-lookup.c (diskfs_S_dir_lookup): Check cache before normal
- diskfs_lookup call.
- * node-drop.c (diskfs_drop_node): Call
- _diskfs_purge_cache_deletion before releasing node structure with
- diskfs_node_norefs.
- * dir-clear.c (diskfs_clear_directory): Call
- diskfs_purge_cache_node before diskfs_dirremove.
- * dir-rename.c (diskfs_S_dir_rename): Likewise.
- * dir-renamed.c (diskfs_rename_dir): Likewise.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise.
- * dir-unlink.c (diskfs_S_dir_unlink): Likewise.
- * dir-init.c (diskfs_init_dir): Doc fix.
- * dir-rename.c (diskfs_S_dir_rename): Call diskfs_purge_cache
- before diskfs_dirrewrite for old node.
- * dir-renamed.c (diskfs_rename_dir): Likewise.
- * node-create.c (diskfs_create_node): Call diskfs_enter_cache if
- diskfs_direnter is successful.
- * dir-link.c (diskfs_S_dir_link): Likewise.
- * dir-rename.c (diskfs_S_dir_rename): Call diskfs_enter_cache if
- diskfs_direnter/diskfs_dirrewrite is successful.
- * dir-renamed.c (diskfs_rename_dir): Likewise.
-
-Fri Mar 15 23:10:57 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Don't leak a send right to
- the anonymous handle on DNP when calling fetch_root.
-
-Tue Mar 12 14:36:10 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * file-set-trans.c (diskfs_S_file_set_translator): Deallocate ref
- on CONTROL when we are done with it.
-
-Thu Mar 7 16:45:02 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * readonly.c (diskfs_set_readonly): Don't sleep(1) after syncing.
-
-Thu Feb 29 14:29:20 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * Makefile (OTHERSRCS): Change `opts-runtime-def.c' to
- `opts-runtime-parse.c'. Add `opts-runtime-unparse.c'.
-
-Wed Feb 21 06:10:05 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
-
- * file-set-trans.c (diskfs_S_file_set_translator): Add EROFS check.
-
-Sun Feb 18 00:08:27 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * init-init.c (diskfs_init_diskfs): Use maptime_map.
- * node-times.c (diskfs_set_node_times): Use maptime_read.
-
-Fri Feb 16 13:48:08 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-runtime-def.c (diskfs_parse_runtime_options): STANDARD_ARGP
- is const.
-
-Thu Feb 15 16:59:04 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_nput): It's not valid to touch *NP (by
- `mutex_unlock (&np->lock);') after we have called
- diskfs_drop_node. So don't do it in that case.
-
-Wed Feb 7 22:42:22 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_nput): Before bumping NP->references (which
- precedes diskfs_try_dropping_softrefs), *lock*
- diskfs_node_refcnt_lock, not mutant unlock.
- (diskfs_nrele): Likewise.
-
-Wed Feb 7 16:22:31 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_parse_runtime_options): Make STANDARD_ARGP const.
- (diskfs_startup_argp, diskfs_device_startup_argp): Make const.
- * opts-common.c (diskfs_common_options): Make const.
- * opts-std-startup.c (startup_options, dev_startup_options,
- dev_start_argp_parents, dev_startup_argp, startup_common_argp,
- startup_argp_parents, startup_argp, diskfs_startup_argp): Make const.
- * opts-set.c (std_runtime_options): Make const.
- (diskfs_set_options): Make argp structures const.
-
-Wed Feb 7 13:39:09 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Revert last change.
-
-Tue Feb 6 15:56:04 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Make the new peropen we'll
- pass as dotdot to the fetch_root with the same flags as DIRCRED->po.
-
-Wed Jan 31 00:27:10 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * node-rdwr.c (diskfs_node_rdwr): Handle null AMTREAD.
-
-Tue Jan 30 21:20:13 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * fsys-options.c (diskfs_S_fsys_set_options): Use
- rwlock_writer_lock instead of rwlock_reader_lock in DO_CHILDREN case.
-
-Tue Jan 30 15:03:35 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * peropen-rele.c (diskfs_release_peropen): Free dotdotport when
- deallocating peropen.
-
-Wed Jan 24 18:14:28 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Use diskfs_create_protid instead
- of diskfs_make_protid, and deal with an error return.
- * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise.
- * file-exec.c (diskfs_S_file_exec): Likewise.
- * file-inv-trans.c (diskfs_S_file_invoke_translator): Likewise.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
- * io-duplicate.c (diskfs_S_io_duplicate): Likewise.
- * io-restrict-auth.c (diskfs_S_io_restrict_auth): Likewise.
- * trans-callback.c (_diskfs_translator_callback2_fn): Likewise.
- * boot-start.c (diskfs_start_bootstrap, diskfs_S_exec_startup_get_info,
- diskfs_execboot_fsys_startup, diskfs_S_fsys_init): Likewise.
- * protid-make.c (diskfs_start_protid): Return an error now, and use
- ports_create_port instead of ports_allocate_port.
- (diskfs_create_protid): New function.
- (diskfs_make_protid): Call diskfs_create_protid.
- * diskfs.h (diskfs_start_protid): Update declaration.
- (diskfs_create_protid): New declaration.
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Use new version of
- diskfs_start_protid.
- * file-getcontrol.c (diskfs_S_file_getcontrol): Use ports_create_port
- instead of ports_allocate_port.
- * boot-start.c (start_execserver, diskfs_start_bootstrap): Likewise.
- * init-startup.c (diskfs_startup_diskfs): Likewise.
- * sync-interval.c (diskfs_set_sync_interval): Likewise.
- (periodic_sync): Pass in the MSG_ID arg to ports_begin_rpc, and
- deal with any error returned.
-
- * readonly.c (diskfs_set_readonly): Deal with ports_inhibit_class_rpcs
- returning an error.
- * remount.c (diskfs_remount): Likewise.
- * shutdown.c (diskfs_shutdown): Likewise.
- * sync-interval.c (diskfs_set_sync_interval): Likewise.
-
- * dir-readdir.c: Include <fcntl.h>.
-
-Tue Jan 23 16:28:47 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * opts-std-startup.c (startup_options): Put boot options in a
- separate group with a header.
-
-Thu Jan 18 14:05:51 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * dir-readdir.c (diskfs_S_dir_readdir): Require read permission
- before succeeding.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Deallocate ref to dotdot
- after diskfs_make_peropen, because the latter does not eat a
- reference.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): In symlink case, use
- MOVE_SEND to return the dotdot port to the user.
-
-Thu Jan 11 22:09:05 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-
- * diskfs-pager.h (struct disk_image_user): New type.
- (diskfs_catch_exception, diskfs_end_catch_exception): Use it to
- maintain a linked list of catchers instead of just one.
-
-Sat Jan 6 11:49:02 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (installhdrs): Add diskfs-pager.h.
- (OTHERSRCS): Add disk-pager.c.
-
-Fri Jan 5 17:06:42 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * io-write.c: Return errors regardless of *AMT--writes are all or
- nothing.
- * io-read.c: Return errors regardless of *DATALEN--reads are all or
- nothing.
-
-Thu Jan 4 16:11:35 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * disk-pager.c, diskfs-pager.h: New files.
- * exc.c: File removed.
- * Makefile (OTHERSRCS): Remove exc.c.
- * diskfs.h (diskfs_catch_exception, diskfs_end_catch_exception):
- Macros removed.
- (diskfs_register_memory_fault_area,
- diskfs_unregister_memory_fault_area): Decls removed.
-
- * diskfs.h: Use size_t instead of int for amounts in
- diskfs_node_rdwr prototype.
- * node-rdwr.c (diskfs_node_rdwr): Pass AMTREAD read/write to
- _diskfs_rdwr_internal, instead of assuming it wrote the whole amount.
- Update the node if anything was transferred, regardless of ERR.
- * rdwr-internal.c (_diskfs_rdwr_internal): Rewritten using
- pager_memcpy.
- Fix types of args: OFFSET to off_t, make AMT read/write size_t *.
- * priv.h: Fix args in _diskfs_rdwr_internal prototype.
- * io-write.c: Pass AMT read/write to _diskfs_rdwr_internal, and
- return success if any bytes were written.
- * io-read.c: Likewise.
-
-Mon Jan 1 15:45:33 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Use fshelp_exec_reauth().
- (setid, scan_ids): Functions deleted.
-
-Thu Dec 28 14:21:42 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Always reauth the proc port,
- as exec does not do it, even in the secure case. Set the proc's
- owner too.
-
- * file-exec.c (setid): Don't touch the return params unless we succeed.
- Add SETID parameter, and just copy old into new unless it's set.
- Handle the NOLDGENIDS == 0 case correctly.
- (diskfs_S_file_exec): Use the new setid() properly. Make sure that
- {GEN,AUX}{UIDS,GIDS} are always in a state where they can be freed.
-
-Thu Dec 28 00:24:29 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * priv.h (end_using_protid_port): Don't calls ports_port_deref if
- CRED is null.
-
-Wed Dec 27 17:32:21 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * file-exec.c (setid): New function.
- (scan_ids): Moved out of diskfs_S_file_exec.
- (diskfs_S_file_exec): Move duplicated code into setid(). Make the
- bogus auth port case work correctly. Deleted old ifdefed-out code.
- Enable setuid code.
-
- * exc.c (diskfs_register_memory_fault_area): Register both
- preempter1 and preempter2 in REC instead of preempter1 twice.
-
-Sat Dec 23 14:49:22 1995 Michael I. Bushnell p/BSG <mib@gnu.ai.mit.edu>
-
- * exc.c: Entire file rewritten to use libc signal preemption
- facility.
-
-Wed Dec 20 14:49:29 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_S_fsys_init): Call proc_mark_exec on
- EXECPROCESS.
-
-Tue Dec 19 13:19:19 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Better attempt at
- setuid/setgid execution; still not entirely right, but mostly so.
- Will move this code to libfshelp before turning it on.
-
-Thu Dec 14 15:51:19 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_checkdirmod): Correctly return error code for
- failure, not 1.
-
-Mon Dec 4 17:07:20 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * dir-unlink.c (diskfs_S_dir_unlink): Don't call fsys_goaway until
- we've released our lock.
-
-Mon Dec 4 16:57:28 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * dir-unlink.c (diskfs_S_dir_unlink): Delete vestigial fetch_control.
-
-Tue Nov 21 13:54:14 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * rdwr-internal.c (_diskfs_rdwr_internal): Declare PROT volatile.
-
- * init-first.c (master_thread_function): Declare to be `static
- any_t'.
-
- * fsys-options.c: Include <string.h>.
-
- * diskfs.h (diskfs_get_options): Bother providing declaration.
-
- * file-get-fs-opts.c: Include <string.h>.
- (diskfs_S_file_get_fs_options): Dereference DATA_LEN in call to
- vm_allocate.
-
-Sat Nov 18 09:01:28 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_S_exec_startup_get_info): Renamed from
- diskfs_S_exec_startup, slightly different protocol. Unused exec
- server stubs removed.
- * Makefile (MIGSTUBS): Replaced execServer.o with exec_startupServer.o.
-
-Mon Nov 13 17:13:40 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * demuxer.c (diskfs_demuxer):
- diskfs_exec_server --> diskfs_exec_startup_server.
-
-Mon Nov 13 16:28:27 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * file-lock-stat.c (diskfs_S_file_lock_stat): Lock around reads to
- make sure they are mutually consistent.
-
- * io-readable.c (diskfs_S_io_readable): Set *AMOUNT to zero if
- filepointer is past the end of the file.
-
-Thu Nov 9 12:33:53 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * dir-link.c (diskfs_S_dir_link): Now that args are swapped,
- deallocate port ref on FILECRED instead of DIRCRED.
-
-Sun Nov 5 10:49:26 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * Makefile (OTHERSRCS): Add opts-get.c.
- (FSSRCS): Add file-get-fs-opts.c.
- * file-get-fs-opts.c (diskfs_S_file_get_fs_options): New function.
- * fsys-options.c (diskfs_S_fsys_get_options): New function.
- * opts-get.c (diskfs_get_options): New function.
-
- * sync-interval.c (diskfs_sync_interval): New variable.
- (diskfs_set_sync_interval): Set DISKFS_SYNC_INTERVAL.
-
-Sat Nov 4 23:17:50 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * file-get-trans.c (diskfs_S_file_get_translator): Initialize ERROR.
-
- * trans-callback.c (_diskfs_translator_callback2_fn):
- UNDERLYING_TYPE should be a pointer. As should the UIDS & GIDS
- args to diskfs_make_protid.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Pass both callback args
- to fshelp_fetch_root.
-
- * filedev.c (diskfs_get_file_device): Give FLAGS argument to
- file_get_storage_info.
-
- * dir-lookup.c (diskfs_S_dir_lookup): Fix various typos.
- (short_circuited_callback1): Dereference ARGZ & ARGZ_LEN.
- Include <hurd/paths.h>
-
-Wed Nov 1 15:56:45 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Add new callback arg to
- fshelp_fetch_root call. Change short_circuited_callback1 to
- reflect the split into two callbacks (we use the global diskfs
- callback for the other_).
- * trans-callback.c (_diskfs_translator_callback1_fn,
- _diskfs_translator_callback2_fn): New functions, replacing the
- single original.
- (_diskfs_translator_callback1, _diskfs_translator_callback2):
- New variables, replacing the single original.
- * priv.h (_diskfs_translator_callback1, _diskfs_translator_callback2):
- Declare.
-
- * boot-start.c (diskfs_execboot_fsys_startup): Add FLAGS arg; use.
- * fsys-startup.c (diskfs_S_fsys_startup): Ditto.
- * init-startup.c (diskfs_startup_diskfs): Ditto.
- * diskfs.h (diskfs_startup_diskfs, diskfs_execboot_fsys_startup):
- Add FLAGS arg.
-
-Mon Oct 30 13:20:12 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Move code for starting
- short-circuited translators here, from _diskfs_translator_callback_fn.
- Inline code from node_is_translated.
- (node_is_translated): Function removed.
- (major, minor): New macros -- temporarily here until libc exports them.
-
-Thu Oct 26 18:41:23 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * trans-callback.c (_diskfs_translator_callback_fn): Deal with
- short-circuited translators.
- * dir-lookup.c (node_is_translated): New function.
- (diskfs_S_dir_lookup): Use node_is_translated() instead of
- np->istranslated to see whether NP has a passive translator.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Add missing else.
- Use makedev macro instead of doing it by hand.
- (makedev): New macro -- temporarily here until libc exports one.
-
-Thu Oct 19 12:43:47 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * fsys-options.c (diskfs_S_fsys_set_options): Only hold
- DISKFS_FSYS_LOCK for writing while setting our own options; we
- hold it for reading while setting our children's.
-
- * rdwr-internal.c (_diskfs_rdwr_internal): Get rid of CRED argument.
- * priv.h (_diskfs_rdwr_internal): Ditto.
- * node-rdwr.c (diskfs_node_rdwr): Ditto.
- * io-write.c (diskfs_S_io_write): Ditto.
- * io-read.c (diskfs_S_io_read): Ditto.
-
-Wed Oct 18 15:52:53 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_get_filemap): Add prot parameter.
- (diskfs_max_user_pager_prot): New declaration.
- * rdwr-internal.c (_diskfs_rdwr_internal): Add argument CRED, and
- use it to decide how to setup the mapped i/o.
- * io-write.c (diskfs_S_io_write): Pass CRED to _diskfs_rdwr_internal.
- * io-read.c (diskfs_S_io_read): Ditto.
- * node-rdwr.c (diskfs_node_rdwr): Ditto.
- * io-map.c (diskfs_S_io_map): Pass the appropiate vm protection to
- diskfs_get_filemap. If this node isn't O_RDWR, only return the
- appropiate memobj.
- Include <fcntl.h>.
- * priv.h (_diskfs_rdwr_internal): Add cred parameter.
-
- * boot-start.c (diskfs_execboot_fsys_startup): Open exec's
- realnode read-only for now, since we know it doesn't matter and
- having gratuitously writable nodes around prevents us from
- starting up or going read-only.
- (diskfs_S_fsys_init): Don't make the cwdir/crdir right with O_WRITE.
- * trans-callback.c (_diskfs_translator_callback_fn): Ditto for
- other translators. The fsys_startup interface should change very
- soon and make this irrelevant.
-
- * readonly.c (diskfs_set_readonly): Return EBUSY if necessary.
- Add hack to try and work around pagers-can't-wait bug.
-
- * opts-common.c (diskfs_common_options): New variable.
- * priv.h (diskfs_common_options): New declaration.
- * opts-std-startup.c (startup_options): Remove options common to
- both runtime and startup.
- (startup_common_argp, startup_argp_parents): New variables.
- (startup_argp): Include parents.
- * opts-set.c (std_runtime_options): Remove options common to
- both runtime and startup.
- (diskfs_set_options): Use the common options.
- * Makefile (OTHERSRCS): Add opts-common.c.
-
- * diskfs.h (diskfs_fsys_lock): Change to a struct rwlock.
- Include <rwlock.h>
- * shutdown.c (diskfs_fsys_lock): Now a rwlock.
- (diskfs_shutdown): Lock DISKFS_FSYS_LOCK for writing.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Hold DISKFS_FSYS_LOCK
- for reading.
- * sync-interval.c (periodic_sync): Hold DISKFS_FSYS_LOCK for
- reading while syncing.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs): Ditto.
- * fsys-options.c (diskfs_S_fsys_set_options): Hold DISKS_FSYS_LOCK
- for writing.
- Dereference PT even when a child filesystem returns an error.
- * opts-set.c (diskfs_set_options): Don't hold DISKS_FSYS_LOCK (our
- caller should).
-
- * machdev.c (diskfs_get_mach_device): SIZE is in blocks.
-
-Wed Oct 18 14:00:58 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Return EACCES for attempts to
- execute a directory. Dike out totally bogus set[ug]id code.
- Bother to lock NP around critical section.
-
-Tue Oct 17 14:32:41 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * init-startup.c (diskfs_startup_diskfs): Call diskfs_readonly_changed
- if we're starting up writable.
- * diskfs.h (diskfs_readonly_changed, diskfs_reload_global_state,
- diskfs_node_reload, diskfs_set_readonly, diskfs_remount): New
- declarations.
- (diskfs_main_request_loop): Declaration removed.
- * Makefile (OTHERSRCS): Add readonly.c, remount.c.
- * readonly.c (diskfs_set_readonly): New function.
- * remount.c (diskfs_remount): New function.
-
- * opts-set.c (diskfs_set_options): Rework readonly transition &
- remounting. Hold diskfs_fsys_lock.
-
- * diskfs.h (diskfs_fsys_lock): Renamed from diskfs_shutdown_lock.
- * shutdown.c (diskfs_shutdown): diskfs_shutdown_lock -->
- diskfs_fsys_lock.
-
-Fri Oct 13 14:51:42 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_start_bootstrap): Get rid of ARGV argument.
- (diskfs_argv): New declaration.
- * boot-start.c (saved_argv): Variable removed.
- (diskfs_argv): New variable. Should get set by default arg parser.
- (diskfs_start_bootstrap): Get rid of ARGV argument.
- (diskfs_S_fsys_init): Use DISKFS_ARGV instead of SAVED_ARGV.
- * opts-std-startup.c (parse_startup_opt): Set DISKFS_ARGV.
- * init-startup.c (diskfs_startup_diskfs): Call diskfs_start_bootstrap
- if we're the bootstrap file system.
-
- * dev-globals.c (diskfs_device, diskfs_device_name,
- diskfs_device_start, diskfs_device_size, diskfs_device_block_size,
- diskfs_log2_device_block_size, diskfs_log2_device_blocks_per_page):
- New variables.
- * dev-io.c (diskfs_device_write_sync, diskfs_device_write_sync):
- New functions.
- * dev-open.c (diskfs_device_open): New function, new file.
- * diskfs.h (diskfs_device, diskfs_device_name,
- diskfs_device_start, diskfs_device_size, diskfs_device_block_size,
- diskfs_log2_device_block_size, diskfs_log2_device_blocks_per_page,
- diskfs_device_write_sync, diskfs_device_write_sync,
- diskfs_device_open, diskfs_console_stdio): New declarations.
- * console.c (diskfs_console_stdio): New function.
- * Makefile (OTHERSRCS): Add dev-open.c, dev-io.c, dev-globals.c,
- console.c.
- * opts-std-startup.c (diskfs_use_mach_device, diskfs_device_arg,
- dev_startup_options, dev_startup_argp_parents, dev_startup_argp,
- diskfs_device_startup_argp): New variables.
- (parse_dev_startup_opt): New function.
-
-Thu Oct 12 16:11:22 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_execboot_fsys_startup): Fix args to dir_lookup.
- Declare PATHBUF and RETRY.
-
- * boot-start.c (diskfs_S_fsys_init): Put the contents of
- diskfs_init_completed in here, freeing that routine for user-use.
-
- * init-completed.c (diskfs_init_completed): Now empty.
-
- * opts-set.c (std_runtime_options): Renamed from long_options,
- convert to argp format.
- (SHORT_OPTIONS): Removed.
- (diskfs_set_options): Converted to use argp.
- * diskfs.h (diskfs_parse_runtime_options,
- diskfs_standard_startup_argp): Use argp, not options.
- Include <argp.h> instead of <options.h>.
- * opts-runtime-def.c (diskfs_parse_runtime_options): Use argp
- instead of options.
- * opts-std-startup.c (std_startup_options): Renamed from
- std_long_options; converted to argp format.
- (std_startup_argp): Renamed from std_startp_argp, converted argp fmt.
- (diskfs_standard_startup_argp): Renamed from
- diskfs_standard_startup_options.
-
-Thu Oct 12 03:25:09 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_execboot_fsys_startup): Use dir_lookup
- instead of hurd_file_name_lookup to open /servers/exec.
-
-Mon Oct 9 03:42:49 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_execboot_fsys_startup): Pass back a port to
- /servers/exec in *REAL.
-
-Sat Oct 7 20:51:06 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * init-completed.c (diskfs_init_completed): New function.
- * diskfs.h (diskfs_init_completed): must --> may.
- Add necessary includes.
-
- * Makefile (OTHERSRCS): Add init-completed.c.
-
-Sat Oct 7 05:07:42 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (libdiskfs.so): Depend on libpager, libioserver,
- libfshelp, libthreads.
-
-Fri Oct 6 17:26:51 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_get_file_device, diskfs_get_mach_device): New funcs.
- (diskfs_boot_flags): New variable.
- (diskfs_bootflags, diskfs_bootflagarg): Variables deleted.
-
- * boot-start.c (diskfs_S_fsys_getpriv): Add the port type parameters.
-
- * Makefile (MIGSFLAGS): Variable deleted.
- (fs-MIGSFLAGS, io-MIGSFLAGS, ifsock-MIGSFLAGS): New variables.
- (fsys-MIGSFLAGS): Also import fsmutations.h.
-
- * dir-link.c (diskfs_S_dir_link): Swap first two arguments.
-
- * filedev.c (diskfs_get_file_device): Use new block_size return
- value from file_get_storage_info.
-
-Thu Oct 5 15:10:34 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * Makefile (OTHERSRCS): Remove boot-parse.c; add filedev.c & machdev.c.
- * diskfs.h (diskfs_host_priv, diskfs_master_device): Variables deleted.
- (diskfs_parse_bootargs): Function deleted.
- (diskfs_init_diskfs): Now returns error_t.
- * init-init.c (diskfs_init_diskfs): Always use get_privileged_ports.
- Now return error_t.
- * machdev.c (diskfs_get_mach_device): Use get_privileged_ports
- instead of diskfs_master_device.
- * boot-start.c (diskfs_S_fsys_getpriv): Use get_privileged_ports
- to get the privileged ports.
- (diskfs_start_bootstrap): Use diskfs_boot_flags instead of
- diskfs_bootflagarg.
- (diskfs_start_bootstrap, start_execserver): Look for flags
- directly in diskfs_boot_flags, instead of using the old
- diskfs_bootflags.
- * boot-start.c (diskfs_S_exec_startup): Use get_console to get the
- console device.
- (get_console): New function.
- * opts-std-startup.c (OPT_BOOTFLAGS, OPT_EXEC_SERVER_TASK,
- OPT_HOST_PRIV_PORT, OPT_DEVICE_MASTER_PORT): New defines.
- (std_long_opts, parse_std_startup_opt): Add the
- --device-master-port, --host-priv-port, --exec-server-task, and
- --bootflags options.
-
-Thu Oct 5 00:46:09 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * sync-interval.c (periodic_sync_lock): Variable removed.
- (diskfs_set_sync_interval): Use ports_inhibit_port_rpcs on `pi'
- instead of the spin lock.
- (periodic_sync): Don't use the lock.
- Put ports_begin_rpc before check of periodic_sync_thread.
-
-Wed Sep 27 20:11:09 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * filedev.c (diskfs_get_file_device): New file, new function.
- * machdev.c (diskfs_get_mach_device): New file, new function.
-
-Mon Sep 18 14:21:29 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * io-pathconf.c (diskfs_S_io_pathconf): Renamed from
- file_pathconf.c:diskfs_S_file_pathconf.
- * Makefile (FSSRCS): Deleted file-pathconf.c.
- (IOSRCS): Added io-pathconf.c.
-
-Sun Sep 17 18:04:10 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_S_exec_startup): Don't pass an argument
- string. Set *FLAGS to EXEC_STACK_ARGS.
-
- * file-set-size.c: Renamed from file-trunate.c.
- (diskfs_S_file_set_size): Renamed from diskfs_s_file_truncate.
- If SIZE exceeds the file size, extend the file.
- * Makefile (FSSRCS): Rename file-truncate.c to file-set-size.c.
-
-Sat Sep 16 13:10:21 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * ourfs_notify.defs: New file.
- * Makefile (DIST_FILES): Added ourfs_notify.defs.
- (ourfs_notify_U.h ourfs_notifyUser.c, ourfs_notify.defs): Targets
- removed.
-
-Wed Sep 13 12:36:26 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_lookup): Doc fix.
- * dir-clear.c (diskfs_clear_directory): Set the fourth arg in
- REMOVE lookup calls in accord with change in rules for the lookup
- call.
-
-Wed Sep 6 11:30:24 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * demuxer.c (diskfs_demuxer): Use ports_notify_server and
- ports_interrupt_server instead of our own versions.
- * Makefile (SRCS): Removed $(NOTIFYSRCS) and $(INTSRCS).
- (NOTIFYSRCS, INTSRCS, notify-MIGSFLAGS): Removed.
- (MIGSTUBS): Removed notifyServer.o and interruptServer.o.
- * interrupt.c: File deleted.
-
-Tue Aug 29 14:22:58 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu>
-
- * io-select.c (diskfs_S_io_select): Don't check open modes or
- return EBADF.
-
-Fri Aug 25 15:02:19 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * Makefile (FSYSSRCS): Add fsys-forward.c.
-
-Fri Aug 25 09:44:43 1995 Michael I. Bushnell, p/BSG <mib@mole.gnu.ai.mit.edu>
-
- * file-truncate.c (diskfs_S_file_truncate): Bother to check the
- return value of diskfs_truncate.
-
-Wed Aug 23 14:39:07 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * Makefile (REMHDRS): Removed.
- Rules dealing with ../lib removed.
-
-Sat Jul 29 10:34:38 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * ifsock.c (diskfs_S_ifsock_getsockaddr): Don't loop infinitely if
- we fail to get a reasonable PF_LOCAL server.
-
-Fri Jul 28 14:59:45 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * ifsock.c (diskfs_S_ifsock_getsockaddr): Try to restart the
- PF_LOCAL server if it dies.
-
- * node-drop.c (diskfs_drop_node): Don't actually drop the node if
- it is a socket naming point, unless it also has no links.
-
-Sat Jul 22 13:54:48 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-getcontrol.c (diskfs_S_file_getcontrol): Fix typo.
- * boot-start.c (start_execserver): Likewise.
-
-Fri Jul 21 12:37:36 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * trans-callback.c (_diskfs_translator_callback_fn): Use correct
- sense of diskfs_readonly flag.
-
- * boot-start.c (diskfs_start_bootstrap): Free initial reference
- created by diskfs_make_protid.
- (diskfs_S_exec_startup): Likewise.
- (diskfs_S_fsys_init): Likewise.
- * dir-lookup.c (diskfs_S_dir_lookup): Likewise. (Two places.)
- * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise.
- * file-exec.c (diskfs_S_file_exec): Likewise.
- * file-inv-trans.c (diskfs_S_file_invoke_translator): Likewise.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
- * io-duplicate.c (diskfs_S_io_duplicate): Likewise.
- * io-restrict-auth.c (diskfs_S_io_restrict_auth): Likewise.
- * trans-callback.c (_diskfs_translator_callback_fn): Likewise.
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Free initial
- reference created by diskfs_start_protid.
-
- * boot-start.c (diskfs_start_bootstrap): Free initial reference
- created by ports_allocate_port.
- (start_execserver): Likewise.
- * file-getcontrol.c (diskfs_S_file_getcontrol): Likewise.
- * init-startup.c (diskfs_startup_diskfs): Likewise.
-
- * dir-lookup.c (diskfs_S_dir_lookup): Examine the active
- translator on NP, not on diskfs_root_node, to see if translator
- usage is necessary.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Only validate
- PASSIVELEN if PASSIVE is set.
-
-Tue Jul 18 16:12:20 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * init-first.c (thread_timeout, server_timeout): New vars.
- (THREAD_TIMEOUT, SERVER_TIMEOUT): Delete macros.
- (master_thread_function): Use vars instead of macros.
-
- * file-get-trans.c (diskfs_S_file_get_translator): Conform to new
- memory semantic of diskfs_get_translator.
-
-Wed Jul 12 16:39:24 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * shutdown.c (diskfs_shutdown): Call ports_resume_class_rpcs for
- diskfs_protid_class before return EBUSY.
-
-Thu Jul 6 15:34:59 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * Makefile (ourfs_notify_U.h ourfs_notifyUser.c): Use
- ourfs_notify.defs instead of directly out of the include
- directory.
- (ourfs_notify.defs): New target.
-
- * Makefile: Removed dependencies that are now automatically
- generated.
-
-Mon Jun 26 15:38:07 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * fsys-goaway.c (diskfs_S_fsys_goaway): Include "fsys_S.h" and
- "fsys_reply_U.h". New parms REPLY and REPLY_TYPE. Send
- fsys_goaway reply message before exit.
- * Makefile (fsys-MIGSFLAGS): New variable.
- * fsys-startup.c (diskfs_S_fsys_startup): New parms REPLY and
- REPLYTYPE.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
- * fsys-options.c (diskfs_S_fsys_set_options): Likewise.
- * boot-start.c (diskfs_S_fsys_getpriv): Likewise.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs): Likewise.
- * fsys-getfile.c (diskfs_S_fsys_getfile): Include "fsys_S.h". New
- parms REPLY and REPLYTYPE.
-
- * sync-interval.c (periodic_sync_thread, periodic_sync_lock):
- Declare static.
- (control): Delete var.
- (pi): New var.
- (diskfs_set_sync_interval): Set PI instead of CONTROL.
- (periodic_sync): Do sync by hand; use ports routines around it
- properly.
-
- * shutdown.c (diskfs_shutdown): Fix parentheses on bitwise tests.
-
- * fsys-goaway.c (diskfs_S_fsys_goaway): If diskfs_shutdown returns
- zero, then exit here.
- * shutdown.c (diskfs_shutdown): Don't actually exit; return zero
- instead.
- * init-first.c (master_thread_function): Exit when shutdown
- returns zero.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Ignore harmless
- errors from fsys_goaway.
- * shutdown.c (diskfs_shutdown): Ignore harmless errors from
- fsys_goaway.
- * fsys-options.c (diskfs_S_fsys_set_options/helper): Ignore
- harmless errors from fsys_set_options.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Fix parentheses
- on first active EXCL check.
-
-Fri Jun 23 15:43:55 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * fsys-options.c (diskfs_S_fsys_set_options) [helper]: Unlock NP
- around fsys call.
- * file-syncfs.c (diskfs_S_file_syncfs) [helper]: Likewise.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs) [helper]: Likewise.
- * shutdown.c (diskfs_shutdown) [helper]: Likewise.
-
-Thu Jun 22 14:48:46 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * priv.h (_diskfs_translator_callback): Must be extern to force
- inclusion of trans-callback.c.
-
- * dir-lookup.c (diskfs_S_dir_lookup): Correctly parethenize
- O_NOTRANS flags test.
-
-Tue Jun 20 11:52:24 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * node-make.c (diskfs_make_node): Fix function name
- fshelp_init_transbox -> fshelp_transbox_init.
-
- * file-syncfs.c: Include <hurd/fsys.h>.
- * fsys-syncfs.c: Likewise.
-
- * file-syncfs.c (diskfs_S_file_syncfs) [helper]: First arg to
- fshelp_fetch_control should be &NP->transbox, not NP.
- * fsys-options.c (diskfs_S_fsys_set_options) [helper]: Likewise.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs) [helper]: Likewise.
- * shutdown.c (diskfs_shutdown) [helper]: Likewise.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Remove
- assignment from if test.
- * node-rdwr.c (diskfs_node_rdwr): Likewise.
-
-Mon Jun 19 16:32:12 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_node_iterate): New (user-provided) function.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs): Use diskfs_node_iterate
- instead of diskfs_sync_translators.
- * file-syncfs.c (diskfs_S_file_syncfs): Likewise.
- * shutdown.c (diskfs_shutdown): Likewise.
- * fsys-options.c (diskfs_S_fsys_set_options): Likewise.
-
- * dir-rmdir.c (diskfs_S_dir_rmdir): Don't attempt anything for
- translated directories here; just return EBUSY.
- * dir-unlink.c (diskfs_S_dir_unlink): Don't do massively
- complicated fsys_goaway. Instead, call it at the end (but only if
- this was the last link) and ignore errors.
-
- * fsys-startup.c (diskfs_S_fsys_startup): Strip out support for
- translators; fshelp now does that itself.
-
- * file-set-trans.c: Include <hurd/fsys.h>.
-
- * file-set-trans.c (diskfs_S_file_set_translator): Use new
- translator interface throughout.
- * dir-lookup.c (diskfs_S_dir_lookup): Use new translator startup
- interface.
-
-Fri Jun 16 17:42:44 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): Use
- fshelp_fetch_control instead of old interface.
-
-Wed Jun 14 15:52:30 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * node-drop.c (diskfs_drop_node): Call fshelp_drop_transbox
- instead of fshelp_kill_translator; do it *after* the truncate.
- * node-make.c (diskfs_make_node): Initialize TRANSBOX member using
- new function. Drop initialization of TRANSLATOR member.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Use new translator
- startup interface.
- * Makefile (OTHERSRCS): Removed trans-start.c, trans-destroy.c,
- and trans-sync.c. Added trans-callback.c.
- * trans-start.c, trans-destroy,c, trans-sync.c: Deleted files.
- * trans-callback.c: New file.
- * priv.h (_diskfs_translator_callback): New declaration.
- * diskfs.h (diskfs_start_translator, diskfs_destroy_translator,
- diskfs_sync_translators):
- Delete declarations.
- (struct node): Replace TRANSLATOR member with new TRANSBOX member.
- (diskfs_get_translator): Specify new calling interface.
-
-Fri Jun 9 15:48:30 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * rdwr-internal.c (_diskfs_rdwr_internal): Cast __VM_PAGE_SIZE in
- comparisen.
- * io-write.c (diskfs_S_io_write): Cast DATALEN to off_t in
- comparisons.
- * io-read.c (diskfs_S_io_read): Cast MAKREAD to off_t in
- comparison.
- * io-prenotify.c (diskfs_S_io_prenotify): Cast END to off_t in
- comparison.
- * file-get-trans.c (diskfs_S_file_get_translator): Declare
- variable `buflen' and various variables `len' to be unsigned.
- * file-exec.c (diskfs_S_file_exec): Declare both variables `i' to
- be unsigned int.
-
- * io-async-icky.c (diskfs_S_io_get_icky_async_id): Validate CRED.
-
- * interrupt.c (diskfs_S_interrupt_operation): Bother to implement.
-
- * init-init.c (diskfs_init_diskfs): Pass null second argument in
- calls to ports_create_class.
-
- * fsys-options.c (diskfs_S_fsys_set_options): Bother validating
- FSYS and implementing DO_CHILDREN.
-
- * dir-lookup.c (diskfs_S_dir_lookup): Initialize GIDS, NUIDS, and
- NGIDS to avoid warning.
-
- * boot-start.c: Provide unused attributes where appropriate.
- * file-chg.c (diskfs_S_file_notice_changes): Mark parameters as
- unused.
- * file-getfh.c (diskfs_S_file_getfh): Likewise.
- * file-inv-trans.c (diskfs_S_file_invoke_translator): Likewise.
- * fsys-getfile.c (diskfs_S_fsys_getfile): Likewise.
- * init-init.c (_diskfs_control_clean): Likewise.
- * io-async.c (diskfs_S_io_async): Likewise.
- * notify-stubs.c: Likewise.
- * file-pathconf.c (diskfs_S_file_pathconf): Declare NAME to be
- unused.
- * io-select.c (diskfs_S_io_select): Declare ATTRIBUTE unused.
- * io-stubs.c (diskfs_S_io_postnotify): Declare parms START and END
- unused.
- * io-prenotify.c (diskfs_S_io_prenotify): Declare parm START
- unused.
-
- * diskfs.h (diskfs_transboot_class): Delete var.
- * init-init.c (diskfs_transboot_class): Delete var.
- (diskfs_init_diskfs): Don't initialize it.
-
- * dir-rename.c (diskfs_S_dir_rename): After renaming directory,
- synchronize relevant state if DISKFS_SYNCHRONOUS.
-
-Thu Jun 8 19:01:25 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_pager_users): New function.
- * shutdown.c (diskfs_shutdown): Rewrote to use new ports interface
- adequately.
-
-Tue Jun 6 13:50:13 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * init-first.c (diskfs_spawn_first_thread): Call our own
- thread function instead of the ports one directly.
- (master_thread_function): New function.
-
- * notify-nosenders.c (diskfs_do_seqnos_mach_notify_no_senders):
- Don't help support pagers here at all.
- * demuxer.c (diskfs_demuxer): Don't call pager_demuxer.
-
- * boot-start.c (diskfs_start_bootstrap): Use new args for
- ports_allocate_port.
- (start_execserver): Likewise.
- * init-startup.c (diskfs_startup_diskfs): Likewise.
- * protid-make.c (diskfs_start_protid): Likewise.
- * file-getcontrol.c (diskfs_S_file_getcontrol): Likewise.
- * sync-interval.c (diskfs_set_sync_interval): Likewise.
-
- * boot-start.c (diskfs_S_exec_startup): Use ports_lookup_port and
- ports_port_deref instead of ports_check_port_type and
- ports_done_with_port.
- (diskfs_execboot_fsys_startup): Likewise.
- (diskfs_S_fsys_init): Likewise.
- (diskfs_S_fsys_getpriv): Likewise.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
- * fsys-goaway.c (diskfs_S_fsys_goaway): Likewise
- * fsys-startup.c (diskfs_S_fsys_startup): Likewise.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs): Likewise.
- * notify-nosenders.c (diskfs_do_seqnos_mach_notify_no_senders):
- Likewise.
- * priv.h (begin_using_protid_port): Use ports_lookup_port.
- (end_using_protid_port): Use ports_port_deref.
-
- * trans-start.c (fshelp_transboot_port_type): Deleted var.
- * priv.h (enum porttype): Delete.
- * demuxer.c: Renamed from ports-demuxer.c.
- (diskfs_demuxer): Renamed from ports_demuxer.
- * init-init.c (diskfs_protid_class, diskfs_transboot_class,
- diskfs_control_class, diskfs_initboot_class,
- diskfs_execboot_class, diskfs_port_bucket): New vars.
- (diskfs_init_diskfs): Don't call libports_initialize.
- Initialize diskfs_protid_class, diskfs_transboot_class,
- diskfs_control_class, diskfs_initboot_class,
- diskfs_execboot_class, and diskfs_port_bucket.
- * diskfs.h: (diskfs_shutdown_soft_ports): Deleted decl.
- (ports_demuxer): Deleted decl.
- (diskfs_demuxer): New decl.
- (diskfs_protid_class, diskfs_transboot_class, diskfs_control_class,
- diskfs_initboot_class,diskfs_execboot_class, diskfs_port_bucket):
- New decls.
- * ports-noports.c, ports-clean.c, ports-soft.c, ports-idle.c,
- ports-consts.c, pager-consts.c, init-loop.c: Deleted files.
- * Makefile (OTHERSRCS): Deleted ports-noports.c, ports-clean.c,
- ports-soft.c, ports-consts, pager-consts.c, init-loop.c, and
- ports-idle.c.
- Replace ports-demuxer.c with demuxer.c.
-
-Mon May 22 13:52:16 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * opts-set.c (diskfs_set_options): Don't fall through to the error
- case from the 's' one!
- Use ARG instead of the global OPTARG.
-
-Sat May 20 01:11:05 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * file-getcontrol.c (diskfs_S_file_getcontrol): Unlock
- _diskfs_control_lock lock instead of locking it again!
-
-Fri May 19 21:22:14 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * opts-set.c (diskfs_set_options): New function in new file.
- * opts-runtime-def.c (diskfs_parse_runtime_options): Ditto.
- * opts-std-startup.c (diskfs_standard_startup_options): New
- exported variable in new file.
- * fsys-options.c (diskfs_S_fsys_set_options): Extract the argument
- vector and call diskfs_set_options.
- * diskfs.h: (diskfs_standard_startup_options): Declare new variable.
- (diskfs_set_options): Declare new function.
- (diskfs_parse_runtime_options): Ditto.
- Include <options.h> (currently in ../lib).
- * Makefile (OTHERSRCS): Add opts-set.c, opts-std-startup.c, and
- opts-runtime-def.c.
- (OBJS): Add argz.o & options.o.
- (REMHDRS): Add argz.h & options.h.
-
-Tue May 16 17:36:46 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * init-first.c (diskfs_spawn_first_thread): Don't start syncing here.
- * init-startup.c (diskfs_startup_diskfs): Do it here instead.
-
-Mon May 15 15:18:25 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_set_options): Declare.
- * fsys-options.c (diskfs_S_fsys_set_options): Extract argc & argv,
- and call diskfs_set_options.
- * def-set-options.c: New file (contains a default diskfs_set_options).
-
- * Makefile (OBJS): Add argz.o (from ../lib). It shouldn't hurt to
- have this in libdiskfs, since we need it...
- (CPPFLAGS): Add -I../lib, to get argz.h, + $(CPPFLAGS-$(notdir $<))
- Set the vpath for %.c to ../lib, so we get argz.c.
- (OTHERSRCS): Add def-set-options.c.
-
-Sat May 13 03:08:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-parse.c (diskfs_execserver_task): New variable.
- (diskfs_parse_bootargs): Take a third integer arg before the
- device name, our name for the task port of the exec server, which
- is loaded and ready to run but suspended.
- * boot-start.c (start_execserver): Don't create and load a task;
- the exec server file is no longer linked into the filesystem.
- Just set the bootstrap port of diskfs_execserver_task and resume
- it.
-
-Fri May 12 16:22:33 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * fsys-readonly.c (diskfs_S_fsys_set_options,
- diskfs_S_fsys_mod_readonly): Change from mod_readonly to
- set_options. This file is now actually called fsys-options.c.
- * Makefile (FSYSSRCS): Rename fsys-readonly.c to fsys-options.c.
-
- * sync-interval.c (diskfs_set_sync_interval): New function (in a
- new file) that establishes a thread to periodically sync the
- filesystem.
- * Makefile (OTHERSRCS): Add sync-interval.c and sync-default.c.
- * diskfs.h: Add declarations of diskfs_set_sync_interval and
- diskfs_default_sync_interval.
-
- * init-first.c (diskfs_spawn_first_thread): Start background syncing.
- * sync-default.c (diskfs_default_sync_interval): A new variable
- that defines a default initial sync interval.
-
-Fri May 12 15:45:43 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * io-read.c (diskfs_S_io_read): If the offset is past the end of
- the file, then return EOF.
-
-Thu Apr 27 20:01:16 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * node-drop.c (diskfs_drop_node): Deal cleanly with errors in
- diskfs_truncate.
-
- * diskfs.h (diskfs_nrele, diskfs_nput): We need to hold a real
- reference around the call to diskfs_try_dropping_softrefs, because
- that's a user-supplied routine that might itself rely on the
- reference counting system.
-
-Thu Apr 20 18:54:26 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * node-create.c (diskfs_create_node): Return EROFS if diskfs_readonly.
-
-Tue Apr 4 20:20:40 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * dir-unlink.c (diskfs_S_dir_unlink): Do fsys_goaway for
- translated nodes being unlinked.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise.
-
-Tue Apr 4 18:33:35 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): However, replacing *MAKE_SEND*
- with COPY_SEND just doesn't work...
-
-Tue Apr 4 14:31:51 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Using MOVE_SEND in call to
- exec_exec loses, because it consumes a reference, which will be
- consumed again by mach_msg_server if we return an error. So use
- COPY_SEND instead, and deallocate the rights ourselves only when
- we are to return success.
-
-Fri Mar 31 12:25:57 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-set-trans.c (diskfs_S_file_set_translator): Only destroy
- existing active translator if ACTIVE_FLAGS will change it. If the
- existing active translator is provided then don't do anything.
-
-Fri Mar 17 11:36:40 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * io-stat.c (diskfs_S_io_stat): Typo.
-
- * diskfs.h: Back out changes to protid and associated permission
- checking functions.
- * file-chmod.c (diskfs_S_file_chmod): Likewise.
- * file-chown.c (diskfs_S_file_chown): Likewise.
- * file-getcontrol.c (diskfs_S_file_getcontrol): Likewise.
-
- * dir-link.c (diskfs_S_dir_link): Fix typo.
-
- * diskfs.h (_diskfs_idcheckdirmod): `diskfs_hasuid' ->
- diskfs_idhasuid.
- * priv.h (CHANGE_NODE_FIELD): Remove trailing space on backslashed
- line.
-
- * diskfs.h (_diskfs_idcheckdirmod): `cred' -> `id'.
- (diskfs_idhasgid): Likewise.
-
- * dir-clear.c (diskfs_clear_directory): Don't do
- diskfs_synchronous here.
- * dir-init.c (diskfs_init_dir): Likewise.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Repair implementation of
- diskfs_syncronous.
- * dir-renamed.c (diskfs_rename_dir): If we are synchronous,
- sync the one node our parent doesn't have access to.
- * dir-mkdir.c (diskfs_S_dir_mkdir): Implement diskfs_synchronous.
- * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise.
- * dir-lookup.c (diskfs_S_dir_lookup): Likewise.
- * io-read.c (diskfs_S_io_read): Likewise.
- * fsys-syncfs.c (diskfs_S_fsys_syncfs): Likewise.
- * node-drop.c (diskfs_drop_node): Likewise.
- * node-rdwr.c (diskfs_node_rdwr): Likewise.
-
-Wed Mar 15 11:54:12 1995 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * conch-fetch.c (ioserver_fetch_shared_data): Implement
- diskfs_synchronous.
- * dir-clear.c (diskfs_clear_directory): Likewise.
- * dir-init.c (diskfs_init_dir): Likewise.
- * dir-renamed.c (diskfs_rename_dir): Likewise.
-
-Wed Mar 8 16:36:04 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_synchronous): New variable.
- * priv.h (CHANGE_NODE_FIELD): If DISKFS_SYNCHRONOUS, then sync
- node after possibly changing it.
- * io-seek.c: Prevent diskfs_synchronous from having its usual
- effect here.
- * dir-link.c (diskfs_S_dir_link): Implement diskfs_synchronous.
- * dir-rename.c (diskfs_S_dir_rename): Likewise.
- * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise
- * dir-unlink.c (diskfs_S_dir_unlink): Likewise.
- * file-sync.c (diskfs_S_file_sync): Likewise.
- * file-syncfs.c (diskfs_S_file_syncfs): Likewise.
- * io-prenotify.c (diskfs_S_io_prenotify): Likewise.
- * io-stat.c (diskfs_S_io_stat): Likewise.
- * io-write.c (diskfs_S_io_write): Likewise.
- * io-sigio.c (diskfs_S_io_sigio): Likewise.
-
-Tue Mar 7 15:21:09 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * diskfs.h (struct userid): New type.
- (struct protid): Replace UIDS, GIDS, NUIDS, and NGIDS with ID.
- (diskfs_isuid): Replace with new function diskfs_idhasuid.
- (diskfs_groupmember): Replace with new function diskfs_idhasgid.
- (_diskfs_idisowner, _diskfs_idaccess, _diskfs_idcheckdirmod):
- New functions.
- (diskfs_isowner): Check each ID in the chain with
- _diskfs_idisowner.
- (diskfs_access): Check each ID in the chain with _diskfs_idaccess.
- (diskfs_checkdirmod): Check each ID in the chain with
- _diskfs_idcheckdirmod.
- * file-chmod.c (diskfs_S_file_chmod): Perform the permission
- check for each ID in the chain.
- * file-chown.c (diskfs_S_file_chown): Likewise.
- * file-getcontrol.c (diskfs_S_file_getcontrol): Likewise.
-
- * boot-parse.c (diskfs_parse_bootargs): Use assert_perror instead
- of assert where appropriate.
- * boot-start.c (diskfs_start_bootstrap): Likewise.
- (diskfs_S_fsys_init): Likewise.
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Likewise.
- * rdwr-internal.c (_diskfs_rdwr_internal): Likewise.
-
-Thu Jan 19 02:04:34 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (ourfs_notify_U.h ourfs_notifyUser.c): Make this
- instead of ourmsg_U.h. All references changed.
- * dir-chg.c: Undo renaming. Includ ourfs_notify_U.h instead of
- ourmsg_U.h.
-
- * io-select.c: Updated to new io_select protocol.
-
- * dir-chg.c (diskfs_S_dir_notice_changes): Call
- nowait_msg_dir_changed instead of nowait_dir_changed.
-
-Sat Dec 10 20:03:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (start_execserver): When aligning bss size for
- vm_allocate, don't include bss start alignment fixup offset.
-
-Fri Dec 9 02:06:35 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * io-read.c (diskfs_S_io_read): Don't check for MAXREAD<0.
-
- * io-write.c: Use mach_msg_type_number_t in place of unsigned int
- and int.
- * io-readable.c: Likewise.
- * io-read.c: Likewise.
-
-Wed Nov 23 00:26:48 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * ports-demuxer.c (ports_demuxer): Call
- diskfs_seqnos_notify_server, not seqnos_notify_server.
-
-Fri Nov 11 13:11:35 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * io-read.c (diskfs_S_io_read): If OFF is past the end of the
- file, don't set MAXREAD to a negative number; that will crash
- rdwr_internal.
-
-Wed Nov 9 01:46:18 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-exec.c: Include <hurd/paths.h>.
- (diskfs_S_file_exec): If diskfs_exec isn't already
- set, try to open it here. (Later, we should also deal if
- exec_exec returns that the previous server died.)
-
-Tue Nov 8 00:06:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * file-get-trans.c: Include <stdio.h> for asprintf decl.
-
-Wed Nov 2 16:16:57 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * priv.h (CHANGE_NODE_FIELD): Don't call diskfs_node_update here.
-
-Fri Oct 28 18:26:15 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-parse.c (diskfs_parse_bootargs): Make stdout line buffered.
- (diskfs_parse_bootargs): Use getline instead of scanf.
- * boot-start.c (diskfs_start_bootstrap): Likewise.
- (diskfs_S_fsys_init): Create a root port with two send right refs
- and install it as crdir and cwdir.
-
-Tue Oct 25 14:16:50 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_start_bootstrap): Renamed variable ARGV
- to be EXEC_ARGV and ARGVLEN to be EXEC_ARGVLEN.
-
-Fri Oct 7 01:30:12 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-parse.c (diskfs_parse_bootargs): Open console for reading too.
-
- * boot-start.c (saved_argv): New static variable.
- (diskfs_start_bootstrap): Take arg ARGV; store it in saved_argv.
- (diskfs_S_fsys_init): Construct a portarray and call _hurd_init.
- Or, if _hurd_ports is already allocated, call _hurd_proc_init.
- * diskfs.h (diskfs_start_bootstrap): Update prototype.
-
-Thu Oct 6 17:47:42 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot-start.c (diskfs_S_fsys_init): Allocate a reference on
- authhandle before allowing the library to consume one.
-
-Wed Oct 5 13:00:46 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * node-drop.c (diskfs_drop_node): Clear passive translator
- if we are releasing the inode.
-
-Thu Sep 29 18:12:31 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-parse.c (diskfs_parse_bootargs): If we have a bootstrap
- port, talk to the CMU default pager on it, then clear it.
-
-Fri Sep 23 00:15:52 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * diskfs.h (diskfs_lost_hardrefs): Doc fix.
- (diskfs_try_dropping_softrefs): New declaration.
- (diskfs_nput): Always call diskfs_lost_hardrefs if the last
- hardref goes away; call diskfs_try_dropping_softrefs if the
- link count has vanished too.
- (diskfs_nrele): Likewise.
- (diskfs_nref): Lock node during call to diskfs_new_hardrefs.
-
-Thu Sep 22 21:20:40 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * diskfs.h (struct node): New member `istranslated'.
- (diskfs_node_translated): Deleted function.
- * dir-lookup.c (diskfs_S_dir_lookup): Use istranslated field
- instead of diskfs_node_translated.
- * file-get-trans.c (diskfs_S_file_get_translator): Likewise.
- * file-inv-trans.c (diskfs_S_file_invoke_translator): Likewise.
- * file-set-trans.c (diskfs_S_file_set_translator): Likewise.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
-Fri Sep 16 11:53:04 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * file-set-trans.c (diskfs_S_file_set_translator): Use new
- lock on translator fields; don't hold it and the NP lock
- simultaneously.
- * trans-destroy.c (diskfs_destroy_translator): Doc fix.
-
- * dir-lookup.c (diskfs_S_dir_lookup): Turn off *all* flags
- in call to getroot if we aren't the last component.
-
-Thu Sep 15 13:01:21 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * init-init.c (diskfs_init_diskfs): Restore commented-out
- initialization of diskfs_auth_server_port.
-
-Mon Sep 12 14:38:54 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Clear translator
- port if we get MIG_SERVER_DIED, as with MACH_SEND_INVALID_DEST.
-
-Sun Sep 11 23:30:13 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Copy PATHBUF into RETRYNAME
- properly when symlink target begins with a slash.
-
-Sat Sep 10 08:36:08 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (OTHERSRCS): Add init-startup.c.
- * init-init.c (_diskfs_dotdot_file): Variable removed.
- (diskfs_init_diskfs): Take no args; return void.
- Don't do fsys_startup here.
- * init-startup.c (diskfs_startup_diskfs): New file, new function.
- Do fsys_startup here instead.
- * diskfs.h (diskfs_init_diskfs): Update prototype.
- (diskfs_startup_diskfs): Declare it.
-
- * dir-lookup.c (diskfs_S_dir_lookup): Use error_t for ERROR.
- Retry when fsys_getroot returns MIG_SERVER_DIED, as with
- MACH_SEND_INVALID_DEST.
-
-Fri Sep 9 13:04:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup) [EAGAIN]: Only copy
- into RETRYNAME if this isn't the last component.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Set *RETRY
- and *RETRYNAME properly on normal return.
-
- * init-init.c (diskfs_init_diskfs): Don't attempt to continue
- if fsys_startup fails. Deallocate BOOTSTRAP after using it.
-
-Wed Sep 7 09:52:52 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * trans-start.c (diskfs_start_translator): Don't give write
- access to underlying node if it's not IFREG.
-
- * dir-lookup.c (diskfs_S_dir_lookup): When returning a port
- passed back from fsys_getroot, use MACH_MSG_TYPE_MOVE_SEND,
- not the local default of MAKE_SEND.
-
- * trans-start.c (diskfs_start_translator): Removed assert.
-
-Tue Sep 6 15:30:59 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * dir-lookup.c (diskfs_S_dir_lookup): Translator startup code
- rewritted to be more robust and use new locking protocol
- on translink structures.
- * trans-start.c (diskfs_start_translator): Don't pass LOCK arg
- to diskfs_start_translator. Unlock NP around call to
- diskfs_start_translator. Don't expect DIR to be deallocated.
-
-Thu Sep 1 12:28:03 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * trans-start.c (diskfs_start_translator): Expect right
- on DIR and NPPORT to be consumed by fshelp_start_translator.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Allocate additional
- send-right for DOTDOT to be consumed by diskfs_start_translator.
- Be careful to deallocate DOTDOT when appropriate.
- * dir-lookup.c (diskfs_S_dir_lookup): Create DIRFILE from
- DNP, not NP. Create local reference for dirfile to use
- in call to fsys_getroot.
-
- * boot-start.c (diskfs_start_bootstrap): Give the
- library values for current working and root directories.
-
- * trans-start.c (diskfs_start_translator): Fix and enable.
- * diskfs.h (diskfs_start_translator): Add new third arg to
- prototype.
- * dir-lookup.c (diskfs_S_dir_lookup): Provide third arg to
- diskfs_start_translator.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
-Wed Aug 31 12:04:51 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec) [reauth]: Destroy REF after
- using it.
-
- * file-get-trans.c (diskfs_S_file_get_translator)
- [S_ISCHR || S_ISBLK]: Correct cast of second arg to vm_allocate.
-
- * Makefile (FSYSSRCS): Added fsys-readonly.c and fsys-syncfs.c.
- * fsys-readonly.c, fsys-syncfs.c: New files.
-
-Wed Aug 31 01:50:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot-parse.c (diskfs_parse_bootargs): Fix scanf format for
- bootstrap filesystem device name.
-
- * file-exec.c (diskfs_S_file_exec): For S_ISUID|S_ISGID, create
- new auth handle and reauthenticate passed ports properly.
-
-Tue Aug 30 13:44:29 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-exec.c (diskfs_S_file_exec): Don't bother setting
- EXEC_NEWTASK for non-readable execs; it doesn't really work
- anyhow.
-
- * init-init.c: Call ports_get_right with the result of
- ports_allocate_port in call to fsys_startup.
-
- * trans-sync.c (diskfs_sync_translators): Use fsys_syncfs
- instead of old ugly method.
-
- * init-init.c: Include <hurd/fsys.h>.
-
- * boot-start.c (diskfs_start_bootstrap): Check to make sure return
- from fsys_getroot and dir_lookup is FS_RETRY_NORMAL with empty
- retry_name instead of old FS_RETRY_NONE.
- * dir-lookup.c (diskfs_S_dir_lookup): Initialize return values with
- FS_RETRY_NORMAL and empty retryname instead of old FS_RETRY_NONE.
-
- * Makefile (FSSRCS): Remove dir-pathtrans.c; add dir-lookup.c.
- * dir-lookup.c: Renamed from dir-pathtrans.c.
- * dir-pathtrans.c (diskfs_S_dir_lookup): Renamed from
- diskfs_S_dir_pathtrans.
- * boot-start.c (diskfs_start_bootstrap): Call dir_lookup instead
- of dir_pathtrans.
- * ifsock.c (diskfs_S_ifsock_getsockaddr): Call file_name_lookup
- instead of path_lookup.
-
-Mon Aug 29 12:51:42 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Use new
- protocol for auth_server_authenticate.
-
-Fri Aug 26 12:49:09 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * file-set-trans.c (diskfs_S_file_set_translator): Rename args;
- split flags arg into two. Interpret flags according to new
- scheme.
-
-Thu Aug 18 12:58:44 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot-parse.c (diskfs_parse_bootargs): Print informative
- bootstrap message.
- * boot-start.c (diskfs_start_bootstrap): Likewise.
- (start_execserver): Likewise.
-
- * boot-start.c (diskfs_start_bootstrap): Only do `pausing'
- hack if RB_KDB was in bootstrap args.
- (start_execserver): Likewise.
-
- * io-select.c (diskfs_S_io_select): Add new `porttype' arg.
-
-Thu Aug 11 13:05:40 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Set retry stuff
- correctly if there are more components after translator
- fsys_getroot.
-
-Sat Jul 23 02:25:54 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (notify-MIGSFLAGS): New variable: -DSEQNOS.
-
- * ports-demuxer.c (ports_demuxer): Prepend diskfs_ to Hurd
- interface server functions.
-
-Fri Jul 22 10:54:23 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * Makefile: Changed to use new scheme.
- * boot-start.c: Include "fsys_reply_U.h" instead of "fsys_reply.h".
- * dir-chg.c: Include "ourmsg_U.h" instead of "msg.h".
- * fsmutations.h SERVERPREFIX): Delete macro.
-
- * diskfs.h (struct thread_stuff, diskfs_catch_exception,
- diskfs_end_catch_exception): Moved here from diskfs_machdep.
- Delete inclusion of diskfs_machdep.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Skip leading
- slashes instead of returning an error.
-
-Tue Jul 19 22:12:29 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Fix fsys_getroot call:
- MACH_MSG_TYPE_MOVE_SEND instead of MACH_PORT_RIGHT_MOVE_SEND.
-
-Tue Jul 19 18:37:52 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * boot-start.c (diskfs_start_bootstrap): Create root port
- before calling fsys_getroot on exec server. Pass root port
- as exec server's dotdot node.
- (diskfs_execboot_fsys_startup): Deleted dotdot args.
- * diskfs.h (diskfs_execboot_fsys_startup): Deleted dotdot args.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans) [translator startup]:
- Set dirfile always, not just when invoking the passive translator.
- Pass dirfile to fsys_getroot. Clean up deallocate of dirfile.
- * file-inv-trans.c (diskfs_S_file_invoke_translator): Comment
- out code; this function should vanish.
- * priv.h (_diskfs_dotdot_file): Deleted variable.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Use new arg `dotdot'
- in place of _diskfs_dotdot_file. Pass dotdot in call to
- fsys_getroot.
- * trans-sync.c (diskfs_sync_translators): Pass grunge as dotdot
- arg in call to fsys_getroot.
- * fsys-startup.c (diskfs_S_fsys_startup): Deleted dotdot args;
- don't pass them in calls to helper functions.
- * init-init.c (diskfs_init_diskfs): Don't expect dotdot arg
- from fsys_getroot; don't set _diskfs_dotdot_file.
-
-Mon Jul 18 15:24:30 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * file-inv-trans.c: New file.
- * Makefile (FSSRCS): Added file-inv-trans.c.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Dereference
- returned_port in check for null.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Likewise.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): After
- diskfs_start_translator, set var `control'.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): After getting
- MACH_SEND_INVALID_DEST from the translator, set error to zero
- so that the user's open completes normally. Do other fixes
- from Jul 7 that were made in dir-pathtrans.c for translator
- startup.
-
- * ports-idle.c (ports_notice_idle): New file.
- * Makefile (OTHERSRCS): Added ports-idle.c.
-
- * node-times.c (diskfs_set_node_times): Set old stat structure
- times until the header file gets changed.
-
- * ifsock.c (diskfs_S_ifsock_getsockaddr): Provide type argument
- in call to socket_fabricate_address.
-
-Fri Jul 15 12:00:38 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Use
- DIRCRED->po->dotdotport instead of diskfs_dotdot_file.
-
- * diskfs.h (diskfs_read_symlink_hook): New variable.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Don't permit symlinks
- to be opened for reading or writing (just like other special file
- types). Try using diskfs_read_symlink_hook before reading
- from file data.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Try using
- diskfs_read_symlink_hook before reading from file data.
- * file-get-trans.c (diskfs_S_file_get_translator): Likewise.
-
-Thu Jul 14 14:39:08 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * diskfs.h (diskfs_create_symlink_hook): New variable.
- (diskfs_truncate): Doc fix.
- * file-set-trans.c (diskfs_S_file_set_translator): Try
- diskfs_create_symlink_hook first, before writing ourselves.
- Return errors to user properly.
-
- * node-times.c (diskfs_set_node_times): Use new stat structures
- with struct timespec instead of old definitions.
-
-Wed Jul 13 14:26:37 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * shutdown.c (diskfs_shutdown): Check UNLINK bit first to avoid
- dumping translators if we end up returning an error.
-
- * ports-noports.c: New file.
- * ports-soft.c: New file.
- * diskfs.h (diskfs_shutdown_soft_ports): New declaration.
- * Makefile (OTHERSRCS): Added ports-noports.c and ports-soft.c.
-
- * diskfs.h (diskfs_init_diskfs): New arg `bootstrap'; add return
- value. Call fsys_getroot if bootstrap is set.
-
- * diskfs.h (diskfs_dotdot_file): Deleted variable.
- (struct peropen): New member `dotdotnode'.
- (diskfs_make_peropen): New arg DOTDOTPORT.
- * peropen-make.c (diskfs_make_peropen): Set PO->dotdotport;
- allocate reference if necessary.
- * priv.h (_diskfs_dotdot_file): New variable.
- * init-init.c (_diskfs_dotdot_file): New definition.
- * boot-start.c (diskfs_start_bootstrap): dotdot for created
- peropen to root should be null (we are *the* root directory in this
- case).
- (diskfs_S_exec_startup): Likewise.
- * dir-mkfile.c (diskfs_S_dir_mkfile): Inherit dotdot for
- new peropen from CRED->po.
- * file-exec.c (diskfs_S_file_exec): Likewise.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Inherit dotdot for
- new peropens from DIRCRED->po.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Set dotdot
- from _diskfs_dotdot_file.
-
- * diskfs.h (diskfs_control_port): Deleted variable.
- * priv.h (_diskfs_control_lock, _diskfs_ncontrol_ports): New vars.
- (_diskfs_control_clean): New declaration.
- * ports-clean.c (ports_cleanroutines[PT_CTL]): Use
- _diskfs_control_clean.
- * init-init.c (diskfs_init_diskfs): Don't create control port here.
- (_diskfs_control_lock, _diskfs_ncontrol_ports): New declarations.
- * file-getcontrol.c (diskfs_S_file_getcontrol): Always create
- a new control port structure.
-
- * io-write.c (diskfs_S_io_write): Honor O_FSYNC bit.
- * conch-set.c (ioserver_put_shared_data): Set do_sigio if
- user set O_FSYNC.
- * io-stubs.c (diskfs_S_io_sigio): Removed function.
- * io-sigio.c: New file.
- * Makefile (IOSRCS): Added io-sigio.c
-
- * io-write.c (diskfs_S_io_write): Eliminate pointless test for
- !err before _diskfs_rdwr_internal; only increment filepointer if
- there was no error.
-
- * priv.h (_diskfs_rdwr_internal): New arg NOTIME.
- * rdwr-internal.c (_diskfs_rdwr_internal): New arg NOTIME.
- * io-read.c (diskfs_S_io_read): Don't set atime if O_NOATIME is on.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Don't allow non-owner
- to set O_NOATIME.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
- * priv.h (HONORED_STATE_MODES): Add O_NOATIME.
- (OPENONLY_STATE_MODES): New macro.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Use
- OPENONLY_STATE_MODES to turn off appropriate bits.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): At start, turn
- off all the bits not in O_HURD; we ignore all those and don't
- keep track of them in any way.
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
- * file-get-trans.c (diskfs_S_file_get_translator): Return
- shortcircuited translators for IFCHR, IFBLK, IFIFO, and IFSOCK.
-
- * file-set-trans.c (diskfs_S_file_set_translator): In computing
- rdev, 377 should be *octal*, not hex.
-
- * dir-rename.c (diskfs_S_dir_rename): Deallocate received
- send-right for TOCRED any time we return success.
-
- * dir-link.c (diskfs_S_dir_link): Don't assume that NP is a
- non-directory before checking it.
-
- * boot-start.c (diskfs_start_bootstrap): New variable
- `initnamebuf' which is allocated and then not changed; free
- it rather than freeing `initname'.
-
-Mon Jul 11 18:16:25 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Symlinks to pathnames
- beginning with `/' sholud return FS_RERTY_MAGICAL (but the
- retry name is stils the same).
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
-Fri Jul 8 13:34:25 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): After getting
- MACH_SEND_INVALID_DEST from the translator, set error to zero
- so that the user's open completes normally.
- (diskfs_S_dir_pathtrans): Call mach_port_mod_refs correctly.
- (diskfs_S_dir_pathtrans): In call to fsys_getroot, turn off
- O_NOLINK for !lastcomp, not for lastcomp.
-
-Thu Jul 7 14:46:46 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Deal correctly
- with the sendright on the translator control port avoiding
- races while the node is unlocked.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): At translator
- lookup time, if there is an active translator, release the
- lock on DNP just like we do in the start-passive case. Also
- after fsys_getroot, release reference and clear DNP so that
- code at out: doesn't get it wrong.
- (diskfs_S_dir_pathtrans): Call fshelp_translator_drop instead
- of setting it to null ourselves.
- * trans-destroy.c (diskfs_destroy_translator): Likewise.
-
-Wed Jul 6 14:43:55 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * ports-demuxer.c (ports_demuxer): Only call ifsock_server
- if diskfs_shortcut_ifsock is set.
-
-Tue Jul 5 14:15:32 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * Makefile (TAGSHDRS): New variable.
-
-Thu Jun 30 11:35:43 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * fsmutations.h (IFSOCK_IMPORTS): New macro.
-
- * ports-demuxer.c (ports_demuxer): Call ifsock_server.
-
-Wed Jun 29 17:07:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * diskfs.h (struct node): New member `sockaddr'.
- * node-make.c (diskfs_make_node): Initialize NP->sockaddr.
- * node-drop.c (diskfs_drop_node): Deallocate NP->sockaddr
- if it's been set.
- * ifsock.c: New file.
- * Makefile (IFSOCKSRCS): New variable.
- (SRCS): Added $(IFSOCKSRCS).
- (MIGSTUBS): Added ifsockServer.o.
- (ifsock_S.h ifsockServer.c): New rule.
- (ifsock_S.h): Depended on by IFSOCKSRCS generated objects.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Detect the case
- where the server has died by looking for MACH_SEND_INVALID_DEST
- as a return from fsys_getroot. Rearrange lock/unlock and
- reference counting of NP and DNP because we may need them back
- if we have to repeat the call.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise.
-
-Fri Jun 24 15:52:52 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-link.c (diskfs_S_dir_link): The port_info struct member
- is `port_right', not `port'.
-
-Tue Jun 21 13:25:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-link.c (diskfs_S_dir_link): Deallocate received send
- right for DIRCRED anytime we return success.
-
- * dir-chg.c (diskfs_S_dir_notice_changes): New var `np'. Return
- ENOTDIR if call is made on a non-directory.
-
-Mon Jun 20 16:40:37 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * node-drop.c (diskfs_drop_node): Free structures holding
- dirmod requests.
- * node-make.c (diskfs_make_node): Initialize NP->dirmod_reqs
- to zero.
-
-Fri Jun 17 13:16:18 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Initialize ERROR.
-
-Fri Jun 17 11:21:25 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * trans-sync.c: Include <fcntl.h>.
-
- * Makefile (boot-start.o): Depend on fsys_reply.h.
-
-Thu Jun 16 11:31:46 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * Makefile (msg.h, msgUser.c): New rules.
- (MIGSTUBS): Added msgUser.o.
- (dir-chg.o): Depends on msg.h.
- * dir-chg.c: Include "msg.h".
-
- * diskfs.h (diskfs_start_translator): Second arg DIR is now
- file_t. Changed locking rules.
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Call
- diskfs_start_translator the new way; clean up lock releases.
-
- * fshelp-dropnode.c: Deleted file.
- * fshelp-getnode.c: Deleted file.
- * Makefile (OTHERSRCS): Removed fshelp-dropnode.c and fshelp-getnode.c.
-
- * boot-start.c (diskfs_start_bootstrap): Use new fsys_getroot
- interface.
-
- * fsys-getroot.c: Include <fcntl.h> for O_ bits. Include
- <hurd/fsys.h> for fsys_startup prototype.
-
- * boot-start.c (diskfs_start_bootstrap, diskfs_S_exec_startup):
- Delete obsolete assignments to INIT_PORT_LOGINCOLL.
-
- * diskfs.h (struct node) [dirmod_reqs]: New member.
- (struct dirmod): New type.
- (diskfs_dirrewrite, diskfs_dirremove, diskfs_direnter): Doc fix.
- (diskfs_notice_dirchange): New prototype.
- * dir-chg.c (diskfs_S_dir_notice_changes): Implement call.
- (diskfs_notice_dirchange): New function.
-
- * diskfs.h (diskfs_get_directs): Doc fix.
-
- * file-access.c (diskfs_S_file_check_access): Renamed from
- diskfs_S_file_access. Return allowable operations in *TYPE
- rather than checking those explicitly asked for. Use O_ bits
- instead of _OK bits. Include <fcntl.h>.
-
-Wed Jun 15 21:26:14 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Require lookup of
- empty pathname to fail if not made on a directory.
-
- * fsys-getroot.c (diskfs_S_fsys_getroot): Rewritten to implement
- the new fsys_getroot interface.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Don't implement
- O_TRUNC here anymore.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Use the new
- fsys_getroot interface for translator startup.
-
- * io-modes-set.c (diskfs_S_io_set_all_openmodes): Only let
- the user set the user-setable bits.
-
- * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): New
- arg CTLTYPE; set appropriately.
-
-Wed Jun 15 12:18:16 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * file-chg.c (diskfs_S_file_notice_changes): Declare return type.
-
- * file-access.c: New file.
- * Makefile (FSSRCS): Added file-access.c.
-
-Tue Jun 14 14:06:36 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * diskfs.h (diskfs_get_dirents): New declaration.
- * dir-readdir.c (diskfs_S_dir_readdir): Implement new
- interface using diskfs_get_directs.
-
- * dir-chg.c, file-chg.c: New files.
- * Makefile (FSSRCS): Added dir-chg.c and file-chg.c.
-
-Thu Jun 9 13:39:25 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Release lock on NP
- during call to fsys_getroot; stash control port and uid info in
- new local variables. Reacquire lock before return (because
- common code at label OUT expects NP to be locked).
-
-Mon Jun 6 18:54:50 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): In translator
- startup check, test O_NOTRANS in flags correctly.
-
- * dir-renamed.c (diskfs_rename_dir): Don't call diskfs_nrele on
- TMPNP after SPEC_DOTDOT calls; the spec says that SPEC_DOTDOT
- with RENAME does not allocate a new reference.
-
-Sun Jun 5 05:51:11 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Fix
- initialization of {GEN,AUX}_{UIDS,GIDS}.
-
-Fri Jun 3 18:19:22 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * file-set-trans.c (diskfs_S_file_set_translator): Use
- fshelp_set_control instead of doing it ourselves.
-
-Thu Jun 2 12:00:51 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * diskfs.h (struct node): New member `light_references'.
- (diskfs_nref, diskfs_nput, diskfs_nrele, diskfs_make_node): Doc fix.
- (diskfs_nref_light, diskfs_nput_light, diskfs_nrele_light):
- New functions.
- (diskfs_nrele, diskfs_nput): Only call diskfs_drop_node if both
- NP->references *and* NP->light_references are zero.
- (diskfs_new_hardrefs, diskfs_lost_hardrefs): New declarations.
- (diskfs_nref): Call diskfs_new_hardrefs when appropriate.
- (diskfs_nput, diskfs_nrele): Call diskfs_lost_hardrefs when
- appropriate.
-
- * node-make.c (diskfs_make_node): Initialize NP->light_references.
- Doc fix.
-
-Wed Jun 1 18:24:11 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Skip over multiple
- slashes in pathnames by incrementing NEXTNAME after setting it.
- Also, if after we do this we discover that there is no last
- component, then set LASTCOMP and clear NEXTNAME and CREATE
- entirely, and set (new variable) MUSTBEDIR. Then check for
- MUSTBEDIR after the node has been fetched. Make var TYPE
- function-global and set it always, not just when NEWNODE is unset.
-
-Fri May 27 08:47:46 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * boot-start.c (diskfs_S_exec_exec, diskfs_S_exec_setexecdata):
- Add missing args.
- (diskfs_S_exec_startup): Don't point *ARGVP to EXEC_DATA local
- storage. Instead, copy EXEC_DATA to *ARGVP if *ARGVLEN allows;
- otherwise vm_allocate new space and copy into there.
-
-Thu May 26 15:33:57 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * diskfs.h (diskfs_nrele): Acquire lock if we are releasing
- the last reference.
-
- * node-drop.c (diskfs_drop_node): If we are truncating, then
- go back to normal user state and do the truncate; the next
- time through we will do the dealloc for real.
- Semantics change: now this routine is responsible for
- unlocking diskfs_node_refcnt_lock. All callers changed.
-
-Wed May 25 20:34:17 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * io-write.c (diskfs_S_io_write): Don't check for *AMT < 0; AMT is
- an out-only parameter.
-
-Wed May 25 12:23:25 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * ports-consts.c (ports_use_multiple_threads): Deleted definition.
- * init-first.c (diskfs_spawn_first_thread): Fork
- ports_manage_port_operations_multithread instead of
- ports_maange_port_operations.
- * init-loop.c (diskfs_main_request_loop): Likewise.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Reference node in
- lookup of empty path case so that common code at the out: label
- doesn't free an extra one.
-
-Mon May 23 23:13:51 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * boot-start.c (diskfs_S_fsys_init): Start exec_init after
- proc_child.
-
-Thu May 19 12:48:53 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * io-reauthenticate.c (diskfs_S_io_reauthenticate): Unlock
- node after calling diskfs_finish_protid.
-
-Thu May 12 14:23:29 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * Makefile (clean): Add fsys_reply.h and *User.c.
-
-Thu May 12 03:45:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * Makefile (fsys_reply.h fsys_replyUser.c): New rule.
- (MIGSTUBS): Add fsys_replyUser.o.
- * boot-start.c: Include fsys_reply.h.
- (diskfs_S_fsys_init): Take new reply port args.
- Send reply msg as soon as verified, before doing anything.
-
-Mon May 9 16:58:24 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * diskfs.h (diskfs_init_completed): New function declaration.
- * boot-start.c (diskfs_S_fsys_init): Don't call _hurd_proc_init.
- Do call diskfs_init_completed.
-
-Thu May 5 13:04:43 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Behave properly
- if nextname is null. Copy nextname to the end of the symlink
- target rather than vice versa. Don't punt to the caller before
- doing the append.
- (diskfs_S_dir_pathtrans): O_NOTRANS should prevent symlink
- interpretation.
- (diskfs_S_dir_pathtrans): If a symlink traversal was the last
- component, then clear CREATE (symlinks to nothing don't honor
- O_CREAT) and clear LASTCOMP (because it isn't true any longer).
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Fix mangled check
- for O_NOLINK.
- (diskfs_S_dir_pathtrans): Repair furtherly mangled check for
- O_NOLINK.
-
- * conch-set.c (ioserver_put_shared_data): Set
- optimal_transfer_size from the same thing we return in stat.
-
- * io-async.c (diskfs_S_io_async): Just return EOPNOTSUPP without
- doing anything more at all.
-
-Thu May 5 06:32:10 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * io-prenotify.c (diskfs_S_io_prenotify): Make START and END args
- type vm_offset_t.
-
- * io-map-cntl.c (diskfs_S_io_map_cntl): Take 3rd result arg
- for msg type of *CTLOBJ; set it to copy-send.
-
- * io-async.c (diskfs_S_io_async): Take 3rd result arg for msg type
- of *IDPORT; set it to copy-send. Return 0 instead of EOPNOTSUPP;
- should not be deallocating NOTIFY if returning an error.
-
- * io-async-icky.c (diskfs_S_io_get_icky_async_id): Take 3rd result arg
- for msg type of *IDPORT; set it to copy-send.
-
- * conch-set.c (ioserver_put_shared_data): Temporarily #if 0
- setting of optimal_transfer_size from bogus undeclared variable.
-
- * protid-make.c: Include <string.h> to get bcopy declared.
-
- * {file,dir,io,fsys}-*.c: Changed return type of all RPC server
- functions to kern_return_t. error_t is not compatible with the
- declarations in the mig-generated header files.
-
- * Makefile: Change uses of $(headers) to $(includedir).
-
- * file-exec.c (diskfs_S_file_exec): Fix msg type arg in exec_exec call.
-
- * dir-pathtrans.c (diskfs_S_dir_pathtrans): Add missing close paren.
-
- * boot-start.c (diskfs_start_bootstrap): Pass msg type arg for
- FILE arg to exec_exec.
- (diskfs_S_fsys_getpriv): Change return type to kern_return_t.
- error_t is not compatible with the declarations in the
- mig-generated header files.
- (diskfs_S_fsys_init): Likewise.
- (exec_stack_base, exec_stack_size): New variables.
- (diskfs_S_exec_startup): Use those for stack values in reply.
- (start_execserver): Pass them to mach_setup_thread to be initialized.
-
-Mon May 2 16:32:22 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * dir-pathtrans.c: Test for O_NOLINK flag was mangled.
-
-Fri Apr 29 16:44:08 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * io-stubs.c (diskfs_S_io_readnotify): New function.
-
- * conch-set.c (ioserver_put_shared_data): Set new fields
- optimal_transfer_size (to sblock->fs_bsize) and
- use_readnotify_size (to zero).
-
- * file-exec.c (diskfs_S_file_exec): Change call to exec_exec in
- accord with interface change in exec.defs.
-
-Mon Feb 14 11:26:26 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * boot-start.c: #include <hurd.h>.
- (start_execserver): Call _hurd_setup_thread in place of start_thread.
diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile
index bf355c47..73686889 100644
--- a/libdiskfs/Makefile
+++ b/libdiskfs/Makefile
@@ -1,5 +1,6 @@
#
-# Copyright (C) 1994, 1995, 1996 Free Software Foundation
+# Copyright (C) 1994,95,96,97,98,99,2000,01,2006
+# 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
@@ -19,16 +20,16 @@ dir := libdiskfs
makemode := library
libname = libdiskfs
-FSSRCS= dir-link.c dir-mkdir.c dir-mkfile.c dir-lookup.c dir-rename.c \
- dir-rmdir.c dir-unlink.c file-chauthor.c file-chflags.c file-chown.c \
- file-get-trans.c file-get-transcntl.c file-getfh.c file-getlinknode.c \
- file-get-fs-opts.c \
- file-set-trans.c file-statfs.c file-sync.c file-syncfs.c \
- file-set-size.c file-utimes.c file-getcontrol.c file-lock.c \
- file-chmod.c dir-readdir.c file-lock-stat.c file-exec.c dir-chg.c \
- file-chg.c file-access.c file-inv-trans.c
-IOSRCS= io-async-icky.c io-async.c io-duplicate.c io-get-conch.c \
- io-interrupt.c io-map-cntl.c io-map.c io-modes-get.c io-modes-off.c \
+FSSRCS= dir-chg.c dir-link.c dir-lookup.c dir-mkdir.c dir-mkfile.c \
+ dir-readdir.c dir-rename.c dir-rmdir.c dir-unlink.c \
+ file-access.c file-chauthor.c file-chflags.c file-chg.c \
+ file-chmod.c file-chown.c file-exec.c file-get-fs-opts.c \
+ file-get-trans.c file-get-transcntl.c file-getcontrol.c \
+ file-getfh.c file-getlinknode.c file-lock-stat.c \
+ file-lock.c file-set-size.c file-set-trans.c file-statfs.c \
+ file-sync.c file-syncfs.c file-utimes.c file-reparent.c
+IOSRCS= io-async-icky.c io-async.c io-duplicate.c io-get-conch.c io-revoke.c \
+ io-map-cntl.c io-map.c io-modes-get.c io-modes-off.c \
io-modes-on.c io-modes-set.c io-owner-mod.c io-owner-get.c \
io-pathconf.c io-prenotify.c io-read.c io-readable.c io-identity.c \
io-reauthenticate.c io-rel-conch.c io-restrict-auth.c io-seek.c \
@@ -37,28 +38,32 @@ FSYSSRCS=fsys-getroot.c fsys-goaway.c fsys-startup.c fsys-getfile.c \
fsys-options.c fsys-syncfs.c fsys-forward.c
IFSOCKSRCS=ifsock.c
OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \
+ extern-inline.c \
node-create.c node-drop.c node-make.c node-rdwr.c node-update.c \
+ node-nref.c node-nput.c node-nrele.c node-nrefl.c node-nputl.c \
+ node-nrelel.c \
peropen-make.c peropen-rele.c protid-make.c protid-rele.c \
- init-init.c init-startup.c init-first.c \
+ init-init.c init-startup.c init-first.c init-main.c \
rdwr-internal.c boot-start.c demuxer.c node-times.c shutdown.c \
sync-interval.c sync-default.c \
opts-set.c opts-get.c opts-std-startup.c opts-std-runtime.c \
opts-append-std.c opts-common.c opts-runtime.c opts-version.c \
- trans-callback.c readonly.c remount.c filedev.c machdev.c \
- dev-open.c dev-io.c dev-globals.c console.c disk-pager.c \
+ trans-callback.c readonly.c readonly-changed.c \
+ remount.c console.c disk-pager.c \
name-cache.c direnter.c dirrewrite.c dirremove.c lookup.c dead-name.c \
validate-mode.c validate-group.c validate-author.c validate-flags.c \
- validate-rdev.c validate-owner.c
+ validate-rdev.c validate-owner.c extra-version.c
SRCS = $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS)
-LCLHDRS = diskfs.h priv.h lithp.h fsmutations.h diskfs-pager.h
+LCLHDRS = diskfs.h priv.h lithp.h fsmutations.h diskfs-pager.h fhandle.h
installhdrs = diskfs.h diskfs-pager.h
-DIST_FILES = ourfs_notify.defs
MIGSTUBS = fsServer.o ioServer.o fsysServer.o exec_startupServer.o \
- fsys_replyUser.o ourfs_notifyUser.o ifsockServer.o \
+ fsys_replyUser.o fs_notifyUser.o ifsockServer.o \
startup_notifyServer.o
OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS))
+HURDLIBS = fshelp iohelp store threads ports shouldbeinlibc pager
+
fsys-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h -DREPLY_PORTS
fs-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
io-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
@@ -66,6 +71,3 @@ ifsock-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
MIGCOMSFLAGS = -prefix diskfs_
include ../Makeconf
-
-libdiskfs.so: $(foreach lib,threads ports fshelp shouldbeinlibc iohelp,\
- ../lib$(lib)/lib$(lib).so)
diff --git a/libdiskfs/boot-parse.c b/libdiskfs/boot-parse.c
deleted file mode 100644
index cb4ffca2..00000000
--- a/libdiskfs/boot-parse.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- Copyright (C) 1993, 1994, 1995 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. */
-
-#include "priv.h"
-#include <stdio.h>
-#include <device/device.h>
-#include <string.h>
-#include <sys/reboot.h>
-#include <mach/mig_support.h>
-
-int diskfs_bootflags;
-char *diskfs_bootflagarg;
-task_t diskfs_execserver_task;
-
-/* Call this if the bootstrap port is null and you want to support
- being a bootstrap filesystem. ARGC and ARGV should be as passed
- to main. If the arguments are not in the proper format, an
- error message will be printed on stderr and exit called. Otherwise,
- diskfs_priv_host, diskfs_master_device, and diskfs_bootflags will be
- set and the Mach kernel name of the bootstrap device will be
- returned. */
-char *
-diskfs_parse_bootargs (int argc, char **argv)
-{
- char *devname;
- device_t con;
- mach_port_t bootstrap;
-
- task_get_bootstrap_port (mach_task_self (), &bootstrap);
- if (bootstrap != MACH_PORT_NULL)
- {
- /* We were started not by the kernel, but by the CMU default_pager.
- It passes us args: -<flags> root_name server_dir_name. We ignore
- the last one. An RPC on our bootstrap port fetches the privileged
- ports. */
-
- struct
- {
- mach_msg_header_t Head;
- mach_msg_type_t priv_hostType;
- mach_port_t priv_host;
- mach_msg_type_t priv_deviceType;
- mach_port_t priv_device;
- } msg;
- mach_msg_return_t msg_result;
-
- static const mach_msg_type_t portCheck = {
- /* msgt_name = */ MACH_MSG_TYPE_MOVE_SEND,
- /* msgt_size = */ 32,
- /* msgt_number = */ 1,
- /* msgt_inline = */ TRUE,
- /* msgt_longform = */ FALSE,
- /* msgt_deallocate = */ FALSE,
- /* msgt_unused = */ 0
- };
-
- msg.Head.msgh_bits =
- MACH_MSGH_BITS (MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
- /* msgh_size passed as argument */
- msg.Head.msgh_remote_port = bootstrap;
- msg.Head.msgh_local_port = mig_get_reply_port ();
- msg.Head.msgh_seqno = 0;
- msg.Head.msgh_id = 999999;
-
- msg_result = mach_msg (&msg.Head, MACH_SEND_MSG|MACH_RCV_MSG,
- sizeof msg.Head, sizeof msg,
- msg.Head.msgh_local_port,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (msg_result != MACH_MSG_SUCCESS)
- {
- if ((msg_result == MACH_SEND_INVALID_REPLY) ||
- (msg_result == MACH_SEND_INVALID_MEMORY) ||
- (msg_result == MACH_SEND_INVALID_RIGHT) ||
- (msg_result == MACH_SEND_INVALID_TYPE) ||
- (msg_result == MACH_SEND_MSG_TOO_SMALL) ||
- (msg_result == MACH_RCV_INVALID_NAME))
- mig_dealloc_reply_port (msg.Head.msgh_local_port);
- else
- mig_put_reply_port (msg.Head.msgh_local_port);
- assert_perror (msg_result);
- }
- mig_put_reply_port (msg.Head.msgh_local_port);
-
- assert (msg.Head.msgh_id == 999999 + 100);
- assert (msg.Head.msgh_size == sizeof msg);
- assert (msg.Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
- assert (*(int *) &msg.priv_hostType == *(int *) &portCheck);
- assert (*(int *) &msg.priv_deviceType == *(int *) &portCheck);
- diskfs_host_priv = msg.priv_host;
- diskfs_master_device = msg.priv_device;
-
- /* bootstrap_privileged_ports (bootstrap,
- &diskfs_host_priv,
- &diskfs_master_device); */
-
- /* Clear our bootstrap port, to appear as if run by the kernel. */
- task_set_bootstrap_port (mach_task_self (), MACH_PORT_NULL);
-
- devname = argv[2];
- }
- else
- {
- /* The arguments, as passed by the kernel, are as follows:
- -<flags> hostport deviceport rootname */
-
- if (argc != 6 || argv[1][0] != '-')
- {
- fprintf (stderr, "\
-Usage: %s: -[qsdnx] hostport deviceport exectaskport rootname\n",
- program_invocation_name);
- exit (1);
- }
- diskfs_host_priv = atoi (argv[2]);
- diskfs_master_device = atoi (argv[3]);
- diskfs_execserver_task = atoi (argv[4]);
- devname = argv[5];
- }
-
- (void) device_open (diskfs_master_device, D_READ|D_WRITE, "console", &con);
- stderr = stdout = mach_open_devstream (con, "w");
- setlinebuf (stdout);
- stdin = mach_open_devstream (con, "r");
-
- /* For now... */
- /* readonly = 1; */
-
- /* The possible flags are
- q -- RB_ASKNAME
- s -- RB_SINGLE
- d -- RB_KDB
- n -- RB_INITNAME */
- /* q tells us to ask about what device to use, n
- about what to run as init. */
-
- diskfs_bootflags = 0;
- if (index (argv[1], 'q'))
- diskfs_bootflags |= RB_ASKNAME;
- if (index (argv[1], 's'))
- diskfs_bootflags |= RB_SINGLE;
- if (index (argv[1], 'd'))
- diskfs_bootflags |= RB_KDB;
- if (index (argv[1], 'n'))
- diskfs_bootflags |= RB_INITNAME;
-
- if (diskfs_bootflags & RB_ASKNAME)
- {
- char *line = NULL;
- size_t linesz = 0;
- ssize_t len;
- printf ("Bootstrap filesystem device name [%s]: ", devname);
- switch (len = getline (&line, &linesz, stdin))
- {
- case -1:
- perror ("getline");
- printf ("Using default of `%s'.\n", devname);
- case 0: /* Hmm. */
- case 1: /* Empty line, just a newline. */
- /* Use default. */
- free (line);
- break;
- default:
- line[len - 1] = '\0'; /* Remove the newline. */
- devname = line;
- break;
- }
- }
-
- printf ("\nInitial bootstrap: %s", argv[0]);
- fflush (stdout);
-
- diskfs_bootflagarg = argv[1];
-
- return devname;
-}
-
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index 9c0e0f79..15563bdb 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,10,11
+ Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -30,17 +31,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <device/device.h>
#include <sys/reboot.h>
#include <string.h>
+#include <argz.h>
+#include <error.h>
#include "fsys_S.h"
#include "fsys_reply_U.h"
-mach_port_t diskfs_exec_ctl;
-mach_port_t diskfs_exec;
+static mach_port_t diskfs_exec_ctl;
extern task_t diskfs_exec_server_task;
+static task_t parent_task = MACH_PORT_NULL;
static struct mutex execstartlock;
static struct condition execstarted;
-static char *default_init = "hurd/init";
+const char *diskfs_boot_init_program = _HURD_INIT;
static void start_execserver ();
@@ -62,6 +65,25 @@ get_console ()
return console;
}
+/* Make sure we have the privileged ports. */
+void
+_diskfs_boot_privports (void)
+{
+ assert (diskfs_boot_filesystem ());
+ if (_hurd_host_priv == MACH_PORT_NULL)
+ {
+ /* We are the boot command run by the real bootstrap filesystem.
+ We get the privileged ports from it as init would. */
+ mach_port_t bootstrap;
+ error_t err = task_get_bootstrap_port (mach_task_self (), &bootstrap);
+ assert_perror (err);
+ err = fsys_getpriv (bootstrap, &_hurd_host_priv, &_hurd_device_master,
+ &parent_task);
+ mach_port_deallocate (mach_task_self (), bootstrap);
+ assert_perror (err);
+ }
+}
+
/* Once diskfs_root_node is set, call this if we are a bootstrap
filesystem. */
void
@@ -71,95 +93,164 @@ diskfs_start_bootstrap ()
retry_type retry;
char pathbuf[1024];
string_t retry_name;
- uid_t idlist[] = {0, 0, 0};
mach_port_t portarray[INIT_PORT_MAX];
mach_port_t fdarray[3]; /* XXX */
task_t newt;
error_t err;
- char *initname, *initnamebuf;
- char *exec_argv;
- int exec_argvlen;
+ char *exec_argv, *exec_env;
+ const char *initname;
+ size_t exec_argvlen, exec_envlen;
struct port_info *bootinfo;
struct protid *rootpi;
-
- printf ("Hurd server bootstrap: %s", program_invocation_short_name);
- fflush (stdout);
-
- /* Get the execserver going and wait for its fsys_startup */
- mutex_init (&execstartlock);
- condition_init (&execstarted);
- mutex_lock (&execstartlock);
- start_execserver ();
- condition_wait (&execstarted, &execstartlock);
- mutex_unlock (&execstartlock);
- assert (diskfs_exec_ctl);
+ struct peropen *rootpo;
+ mach_port_t diskfs_exec;
+ unsigned int init_lookups = 0;
/* Create the port for current and root directory. */
- err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node,
- O_READ | O_EXEC,
- MACH_PORT_NULL),
- 0,0,0,0, &rootpi);
+ err = diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, 0,
+ &rootpo);
assert_perror (err);
- root_pt = ports_get_right (rootpi);
- /* Get us a send right to copy around. */
- mach_port_insert_right (mach_task_self (), root_pt, root_pt,
- MACH_MSG_TYPE_MAKE_SEND);
+ err = diskfs_create_protid (rootpo, 0, &rootpi);
+ assert_perror (err);
+ /* Get us a send right to copy around. */
+ root_pt = ports_get_send_right (rootpi);
ports_port_deref (rootpi);
- /* Contact the exec server. */
- err = fsys_getroot (diskfs_exec_ctl, root_pt, MACH_MSG_TYPE_COPY_SEND,
- idlist, 3, idlist, 3, 0,
- &retry, retry_name, &diskfs_exec);
- assert_perror (err);
- assert (retry == FS_RETRY_NORMAL);
- assert (retry_name[0] == '\0');
- assert (diskfs_exec);
-
+ if (diskfs_exec_server_task == MACH_PORT_NULL)
+ {
+ /* We are the boot command run by the real bootstrap filesystem.
+ Our parent (the real bootstrap filesystem) provides us a root
+ directory where we look up /servers/exec like any non-bootstrap
+ filesystem would. */
+ assert (_hurd_ports);
+ assert (_hurd_ports[INIT_PORT_CRDIR].port != MACH_PORT_NULL);
+ diskfs_exec = file_name_lookup (_SERVERS_EXEC, 0, 0);
+ if (diskfs_exec == MACH_PORT_NULL)
+ error (1, errno, "%s", _SERVERS_EXEC);
+ else
+ {
+#ifndef NDEBUG
+ /* Make sure this is really a port to another server. */
+ struct port_info *pi = ports_lookup_port (diskfs_port_bucket,
+ diskfs_exec, 0);
+ assert (!pi);
+#endif
+ }
- /* Execute the startup server. */
- initnamebuf = NULL;
- initname = default_init;
- if (index (diskfs_boot_flags, 'i'))
+ /* Here we assume the parent has already printed:
+ Hurd server bootstrap: bootfs[bootdev] exec ourfs
+ */
+ printf ("\nContinuing on new root filesystem %s:", diskfs_disk_name);
+ fflush (stdout);
+ }
+ else
{
- size_t bufsz;
- ssize_t len;
- printf ("Init name [%s]: ", default_init);
- bufsz = 0;
- switch (len = getline (&initnamebuf, &bufsz, stdin))
+ uid_t idlist[] = {0, 0, 0};
+ file_t execnode;
+
+ printf ("Hurd server bootstrap: %s[%s]",
+ program_invocation_short_name, diskfs_disk_name);
+ fflush (stdout);
+
+ /* Get the execserver going and wait for its fsys_startup */
+ mutex_init (&execstartlock);
+ condition_init (&execstarted);
+ mutex_lock (&execstartlock);
+ start_execserver ();
+ condition_wait (&execstarted, &execstartlock);
+ mutex_unlock (&execstartlock);
+ assert (diskfs_exec_ctl != MACH_PORT_NULL);
+
+ /* Contact the exec server. */
+ err = fsys_getroot (diskfs_exec_ctl, root_pt, MACH_MSG_TYPE_COPY_SEND,
+ idlist, 3, idlist, 3, 0,
+ &retry, retry_name, &diskfs_exec);
+ assert_perror (err);
+ assert (retry == FS_RETRY_NORMAL);
+ assert (retry_name[0] == '\0');
+ assert (diskfs_exec != MACH_PORT_NULL);
+
+ /* Attempt to set the active translator for the exec server so that
+ filesystems other than the bootstrap can find it. */
+ err = dir_lookup (root_pt, _SERVERS_EXEC, O_NOTRANS, 0,
+ &retry, pathbuf, &execnode);
+ if (err)
{
- case -1:
- perror ("getline");
- printf ("Using default of `%s'.\n", initname);
- case 0: /* Hmm. */
- case 1: /* Empty line, just a newline. */
- /* Use default. */
- break;
- default:
- initnamebuf[len - 1] = '\0'; /* Remove the newline. */
- initname = initnamebuf;
- while (*initname == '/')
- initname++;
- break;
+ error (0, err, "cannot set translator on %s", _SERVERS_EXEC);
+ mach_port_deallocate (mach_task_self (), diskfs_exec_ctl);
}
+ else
+ {
+ assert (retry == FS_RETRY_NORMAL);
+ assert (retry_name[0] == '\0');
+ assert (execnode != MACH_PORT_NULL);
+ err = file_set_translator (execnode, 0, FS_TRANS_SET, 0, 0, 0,
+ diskfs_exec_ctl, MACH_MSG_TYPE_COPY_SEND);
+ mach_port_deallocate (mach_task_self (), diskfs_exec_ctl);
+ mach_port_deallocate (mach_task_self (), execnode);
+ assert_perror (err);
+ }
+ diskfs_exec_ctl = MACH_PORT_NULL; /* Not used after this. */
+ }
+
+ /* Cache the exec server port for file_exec to use. */
+ _hurd_port_set (&_diskfs_exec_portcell, diskfs_exec);
+
+ if (_diskfs_boot_command)
+ {
+ /* We have a boot command line to run instead of init. */
+ err = argz_create (_diskfs_boot_command, &exec_argv, &exec_argvlen);
+ assert_perror (err);
+ initname = exec_argv;
+ while (*initname == '/')
+ initname++;
}
else
- initname = default_init;
+ {
+ /* Choose the name of the startup server to execute. */
+ initname = diskfs_boot_init_program;
+ while (*initname == '/')
+ initname++;
+
+ exec_argvlen = asprintf (&exec_argv, "/%s%c", initname, '\0');
+ assert (exec_argvlen != -1);
+ err = argz_add_sep (&exec_argv, &exec_argvlen,
+ diskfs_boot_command_line, ' ');
+ assert_perror (err);
+
+ initname = exec_argv + 1;
+ }
+ lookup_init:
err = dir_lookup (root_pt, initname, O_READ, 0,
&retry, pathbuf, &startup_pt);
+ init_lookups++;
+ if (err)
+ {
+ printf ("\nCannot find startup program `%s': %s\n",
+ initname, strerror (err));
+ fflush (stdout);
+ free (exec_argv);
+ assert_perror (err); /* XXX this won't reboot properly */
+ }
+ else if (retry == FS_RETRY_MAGICAL && pathbuf[0] == '/')
+ {
+ assert (init_lookups < SYMLOOP_MAX);
+
+ /* INITNAME is a symlink with an absolute target, so try again. */
+ initname = strdupa (pathbuf);
+ goto lookup_init;
+ }
- assert_perror (err);
assert (retry == FS_RETRY_NORMAL);
assert (pathbuf[0] == '\0');
err = ports_create_port (diskfs_initboot_class, diskfs_port_bucket,
sizeof (struct port_info), &bootinfo);
assert_perror (err);
- bootpt = ports_get_right (bootinfo);
- mach_port_insert_right (mach_task_self (), bootpt, bootpt,
- MACH_MSG_TYPE_MAKE_SEND);
+ bootpt = ports_get_send_right (bootinfo);
ports_port_deref (bootinfo);
portarray[INIT_PORT_CRDIR] = root_pt;
@@ -171,31 +262,34 @@ diskfs_start_bootstrap ()
fdarray[0] = fdarray[1] = fdarray[2] = get_console (); /* XXX */
- exec_argvlen =
- asprintf (&exec_argv, "%s%c%s%c", initname, '\0', diskfs_boot_flags, '\0');
+ err = argz_create (environ, &exec_env, &exec_envlen);
+ assert_perror (err);
- err = task_create (mach_task_self (), 0, &newt);
+ err = task_create (mach_task_self (),
+#ifdef KERN_INVALID_LEDGER
+ NULL, 0, /* OSF Mach */
+#endif
+ 0, &newt);
assert_perror (err);
- if (index (diskfs_boot_flags, 'd'))
+ if (_diskfs_boot_pause)
{
- printf ("pausing for init...\n");
+ printf ("pausing for %s...\n", exec_argv);
getc (stdin);
}
- printf (" init");
+ printf (" %s", basename (exec_argv));
fflush (stdout);
err = exec_exec (diskfs_exec, startup_pt, MACH_MSG_TYPE_COPY_SEND,
- newt, 0, exec_argv, exec_argvlen, 0, 0,
+ newt, 0, exec_argv, exec_argvlen, exec_env, exec_envlen,
fdarray, MACH_MSG_TYPE_COPY_SEND, 3,
portarray, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
/* Supply no intarray, since we have no info for it.
With none supplied, it will use the defaults. */
NULL, 0, 0, 0, 0, 0);
free (exec_argv);
+ free (exec_env);
mach_port_deallocate (mach_task_self (), root_pt);
mach_port_deallocate (mach_task_self (), startup_pt);
mach_port_deallocate (mach_task_self (), bootpt);
- if (initnamebuf != default_init)
- free (initnamebuf);
assert_perror (err);
}
@@ -228,6 +322,7 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
mach_port_t rootport;
struct ufsport *upt;
struct protid *rootpi;
+ struct peropen *rootpo;
if (!(upt = ports_lookup_port (diskfs_port_bucket, port,
diskfs_execboot_class)))
@@ -243,14 +338,14 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
*flags = EXEC_STACK_ARGS;
if (*portarraylen < INIT_PORT_MAX)
- vm_allocate (mach_task_self (), (vm_address_t *) portarrayP,
- (INIT_PORT_MAX * sizeof (mach_port_t)), 1);
+ *portarrayP = mmap (0, INIT_PORT_MAX * sizeof (mach_port_t),
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
portarray = *portarrayP;
*portarraylen = INIT_PORT_MAX;
if (*dtablelen < 3)
- vm_allocate (mach_task_self (), (vm_address_t *) dtableP,
- (3 * sizeof (mach_port_t)), 1);
+ *dtableP = mmap (0, 3 * sizeof (mach_port_t), PROT_READ|PROT_WRITE,
+ MAP_ANON, 0, 0);
dtable = *dtableP;
*dtablelen = 3;
dtable[0] = dtable[1] = dtable[2] = get_console (); /* XXX */
@@ -258,11 +353,12 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
*intarrayP = NULL;
*intarraylen = 0;
- err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node,
- O_READ | O_EXEC,
- MACH_PORT_NULL),
- 0,0,0,0, &rootpi);
+ err = diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, 0, &rootpo);
+ assert_perror (err);
+
+ err = diskfs_create_protid (rootpo, 0, &rootpi);
assert_perror (err);
+
rootport = ports_get_right (rootpi);
ports_port_deref (rootpi);
portarray[INIT_PORT_CWDIR] = rootport;
@@ -293,19 +389,18 @@ diskfs_execboot_fsys_startup (mach_port_t port, int flags,
enum retry_type retry;
struct port_info *pt;
struct protid *rootpi;
+ struct peropen *rootpo;
mach_port_t rootport;
if (!(pt = ports_lookup_port (diskfs_port_bucket, port,
diskfs_execboot_class)))
return EOPNOTSUPP;
- err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, flags,
- MACH_PORT_NULL),
- 0,0,0,0, &rootpi);
+ err = diskfs_make_peropen (diskfs_root_node, flags, 0, &rootpo);
assert_perror (err);
- rootport = ports_get_right (rootpi);
- mach_port_insert_right (mach_task_self (), rootport, rootport,
- MACH_MSG_TYPE_MAKE_SEND);
+ err = diskfs_create_protid (rootpo, 0, &rootpi);
+ assert_perror (err);
+ rootport = ports_get_send_right (rootpi);
ports_port_deref (rootpi);
err = dir_lookup (rootport, _SERVERS_EXEC, flags|O_NOTRANS, 0,
@@ -365,12 +460,11 @@ diskfs_S_fsys_init (mach_port_t port,
{
struct port_infe *pt;
static int initdone = 0;
- process_t execprocess;
- string_t version;
mach_port_t host, startup;
error_t err;
mach_port_t root_pt;
struct protid *rootpi;
+ struct peropen *rootpo;
pt = ports_lookup_port (diskfs_port_bucket, port, diskfs_initboot_class);
if (!pt)
@@ -384,9 +478,12 @@ diskfs_S_fsys_init (mach_port_t port,
anything which might attempt to send an RPC to init. */
fsys_init_reply (reply, replytype, 0);
- /* Allocate our reference here; _hurd_init will consume a reference
+ /* Allocate our references here; _hurd_init will consume a reference
for the library itself. */
err = mach_port_mod_refs (mach_task_self (),
+ procserver, MACH_PORT_RIGHT_SEND, +1);
+ assert_perror (err);
+ err = mach_port_mod_refs (mach_task_self (),
authhandle, MACH_PORT_RIGHT_SEND, +1);
assert_perror (err);
@@ -394,36 +491,78 @@ diskfs_S_fsys_init (mach_port_t port,
mach_port_deallocate (mach_task_self (), diskfs_auth_server_port);
diskfs_auth_server_port = authhandle;
- assert (diskfs_exec_server_task != MACH_PORT_NULL);
- err = proc_task2proc (procserver, diskfs_exec_server_task, &execprocess);
- assert_perror (err);
-
- /* Declare that the exec server is our child. */
- proc_child (procserver, diskfs_exec_server_task);
- proc_mark_exec (execprocess);
-
- /* Don't start this until now so that exec is fully authenticated
- with proc. */
- exec_init (diskfs_exec, authhandle, execprocess, MACH_MSG_TYPE_COPY_SEND);
- mach_port_deallocate (mach_task_self (), execprocess);
-
- /* We don't need this anymore. */
- mach_port_deallocate (mach_task_self (), diskfs_exec_server_task);
- diskfs_exec_server_task = MACH_PORT_NULL;
+ if (diskfs_exec_server_task != MACH_PORT_NULL)
+ {
+ process_t execprocess;
+ err = proc_task2proc (procserver, diskfs_exec_server_task, &execprocess);
+ assert_perror (err);
+
+ /* Declare that the exec server is our child. */
+ proc_child (procserver, diskfs_exec_server_task);
+ proc_mark_exec (execprocess);
+
+ /* Don't start this until now so that exec is fully authenticated
+ with proc. */
+ HURD_PORT_USE (&_diskfs_exec_portcell,
+ exec_init (port, authhandle,
+ execprocess, MACH_MSG_TYPE_COPY_SEND));
+ mach_port_deallocate (mach_task_self (), execprocess);
+
+ /* We don't need this anymore. */
+ mach_port_deallocate (mach_task_self (), diskfs_exec_server_task);
+ diskfs_exec_server_task = MACH_PORT_NULL;
+ }
+ else
+ {
+ mach_port_t bootstrap;
+ process_t parent_proc;
+
+ assert (parent_task != MACH_PORT_NULL);
+
+ /* Tell the proc server that our parent task is our child. This
+ makes the process hierarchy fail to represent the real order of
+ who created whom, but it sets the owner and authentication ids to
+ root. It doesn't really matter that the parent fs task be
+ authenticated, but the exec server needs to be authenticated to
+ complete the boot handshakes with init. The exec server gets its
+ privilege by the parent fs doing proc_child (code above) after
+ we send it fsys_init (below). */
+
+ err = proc_child (procserver, parent_task);
+ assert_perror (err);
+
+ /* Get the parent's proc server port so we can send it in the fsys_init
+ RPC just as init would. */
+ err = proc_task2proc (procserver, parent_task, &parent_proc);
+ assert_perror (err);
+
+ /* We don't need this anymore. */
+ mach_port_deallocate (mach_task_self (), parent_task);
+ parent_task = MACH_PORT_NULL;
+
+ proc_mark_exec (parent_proc);
+
+ /* Give our parent (the real bootstrap filesystem) an fsys_init
+ RPC of its own, as init would have sent it. */
+ err = task_get_bootstrap_port (mach_task_self (), &bootstrap);
+ assert_perror (err);
+ err = fsys_init (bootstrap, parent_proc, MACH_MSG_TYPE_COPY_SEND,
+ authhandle);
+ mach_port_deallocate (mach_task_self (), parent_proc);
+ mach_port_deallocate (mach_task_self (), bootstrap);
+ assert_perror (err);
+ }
/* Get a port to the root directory to put in the library's
data structures. */
- err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node,
- O_READ|O_EXEC,
- MACH_PORT_NULL),
- 0,0,0,0, &rootpi);
+ err = diskfs_make_peropen (diskfs_root_node, O_READ|O_EXEC, 0, &rootpo);
+ assert_perror (err);
+ err = diskfs_create_protid (rootpo, 0, &rootpi);
assert_perror (err);
- root_pt = ports_get_right (rootpi);
+ root_pt = ports_get_send_right (rootpi);
ports_port_deref (rootpi);
/* We need two send rights, for the crdir and cwdir slots. */
- mach_port_insert_right (mach_task_self (), root_pt, root_pt,
- MACH_MSG_TYPE_MAKE_SEND);
mach_port_mod_refs (mach_task_self (), root_pt,
MACH_PORT_RIGHT_SEND, +1);
@@ -437,7 +576,7 @@ diskfs_S_fsys_init (mach_port_t port,
_hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authhandle); /* Consume. */
_hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], root_pt); /* Consume. */
_hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], root_pt); /* Consume. */
- _hurd_proc_init (diskfs_argv);
+ _hurd_proc_init (diskfs_argv, NULL, 0);
}
else
{
@@ -447,8 +586,8 @@ diskfs_S_fsys_init (mach_port_t port,
and call _hurd_init. */
mach_port_t *portarray;
unsigned int i;
- __vm_allocate (__mach_task_self (), (vm_address_t *) &portarray,
- INIT_PORT_MAX * sizeof *portarray, 1);
+ portarray = mmap (0, INIT_PORT_MAX * sizeof *portarray,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
if (MACH_PORT_NULL != (mach_port_t) 0)
for (i = 0; i < INIT_PORT_MAX; ++i)
portarray[i] = MACH_PORT_NULL;
@@ -463,9 +602,8 @@ diskfs_S_fsys_init (mach_port_t port,
if (err)
return err;
- sprintf (version, "%d.%d", diskfs_major_version, diskfs_minor_version);
- proc_register_version (procserver, host,
- diskfs_server_name, HURD_RELEASE, version);
+ proc_register_version (procserver, host, diskfs_server_name, "",
+ diskfs_server_version);
err = proc_getmsgport (procserver, 1, &startup);
if (!err)
@@ -476,6 +614,7 @@ diskfs_S_fsys_init (mach_port_t port,
}
mach_port_deallocate (mach_task_self (), host);
+ mach_port_deallocate (mach_task_self (), procserver);
_diskfs_init_completed ();
@@ -496,14 +635,12 @@ start_execserver (void)
err = ports_create_port (diskfs_execboot_class, diskfs_port_bucket,
sizeof (struct port_info), &execboot_info);
assert_perror (err);
- right = ports_get_right (execboot_info);
- mach_port_insert_right (mach_task_self (), right,
- right, MACH_MSG_TYPE_MAKE_SEND);
+ right = ports_get_send_right (execboot_info);
ports_port_deref (execboot_info);
task_set_special_port (diskfs_exec_server_task, TASK_BOOTSTRAP_PORT, right);
mach_port_deallocate (mach_task_self (), right);
- if (index (diskfs_boot_flags, 'd'))
+ if (_diskfs_boot_pause)
{
printf ("pausing for exec\n");
getc (stdin);
@@ -513,4 +650,3 @@ start_execserver (void)
printf (" exec");
fflush (stdout);
}
-
diff --git a/libdiskfs/conch-fetch.c b/libdiskfs/conch-fetch.c
index 9d31265c..2c5d0fd8 100644
--- a/libdiskfs/conch-fetch.c
+++ b/libdiskfs/conch-fetch.c
@@ -1,5 +1,5 @@
/*
- 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
@@ -58,7 +58,7 @@ iohelp_fetch_shared_data (void *arg)
cred->po->np->dn_set_mtime = 1;
mod = 1;
}
- if (cred->mapped->accessed)
+ if (cred->mapped->accessed && ! _diskfs_noatime)
{
cred->po->np->dn_set_atime = 1;
mod = 1;
diff --git a/libdiskfs/console.c b/libdiskfs/console.c
index 885f527e..a4c3a1af 100644
--- a/libdiskfs/console.c
+++ b/libdiskfs/console.c
@@ -1,8 +1,7 @@
/* Redirect stdio to the console if possible
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Copyright (C) 1995,96,98,99,2001 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -31,24 +30,35 @@
#include <device/device.h>
#include <hurd.h>
-/* Make errors go somewhere reasonable. */
+#include "priv.h"
+
+/* Make sure errors go somewhere reasonable. */
void
diskfs_console_stdio ()
{
if (getpid () > 0)
{
- int fd = open ("/dev/console", O_RDWR);
+ if (write (2, "", 0) == 0)
+ /* We have a working stderr from our parent (e.g. settrans -a).
+ Just use it. */
+ dup2 (2, 1);
+ else
+ {
+ int fd = open ("/dev/console", O_RDWR);
- dup2 (fd, 0);
- dup2 (fd, 1);
- dup2 (fd, 2);
- if (fd > 2)
- close (fd);
+ dup2 (fd, 0);
+ dup2 (fd, 1);
+ dup2 (fd, 2);
+ if (fd > 2)
+ close (fd);
+ }
}
else
{
mach_port_t dev, cons;
error_t err;
+ if (diskfs_boot_filesystem ())
+ _diskfs_boot_privports ();
err = get_privileged_ports (NULL, &dev);
assert_perror (err);
err = device_open (dev, D_READ|D_WRITE, "console", &cons);
diff --git a/libdiskfs/dev-globals.c b/libdiskfs/dev-globals.c
deleted file mode 100644
index c32b6a59..00000000
--- a/libdiskfs/dev-globals.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Standard device global variables
-
- Copyright (C) 1995 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <diskfs.h>
-
-/* A mach device port for the device we're using. */
-mach_port_t diskfs_device = MACH_PORT_NULL;
-
-/* The mach device name of DISKFS_DEVICE. May be 0 if unknown. */
-char *diskfs_device_name = 0;
-
-/* The first valid block of DISKFS_DEVICE, in units of
- DISKFS_DEVICE_BLOCK_SIZE. */
-off_t diskfs_device_start = 0;
-
-/* The usable size of DISKFS_DEVICE, in units of DISKFS_DEVICE_BLOCK_SIZE. */
-off_t diskfs_device_size = 0;
-
-/* The unit of addressing for DISKFS_DEVICE. */
-unsigned diskfs_device_block_size = 0;
-
-/* Some handy calculations based on DISKFS_DEVICE_BLOCK_SIZE. */
-/* Log base 2 of DEVICE_BLOCK_SIZE, or 0 if it's not a power of two. */
-unsigned diskfs_log2_device_block_size = 0;
-/* Log base 2 of the number of device blocks in a vm page, or 0 if it's not a
- power of two. */
-unsigned diskfs_log2_device_blocks_per_page = 0;
diff --git a/libdiskfs/dev-io.c b/libdiskfs/dev-io.c
deleted file mode 100644
index 9d0ed9d0..00000000
--- a/libdiskfs/dev-io.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Device input and output
- Copyright (C) 1992, 1993, 1994, 1995 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. */
-
-#include <device/device.h>
-#include <device/device_request.h>
-
-#include <diskfs.h>
-
-/* Write disk block ADDR with DATA of LEN bytes to DISKFS_DEVICE, waiting for
- completion. ADDR is offset by DISKFS_DEVICE_START. If an error occurs,
- EIO is returned. */
-error_t
-diskfs_device_write_sync (off_t addr, vm_address_t data, size_t len)
-{
- int written;
- assert (!diskfs_readonly);
- if (device_write (diskfs_device, 0, diskfs_device_start + addr,
- (io_buf_ptr_t) data, len, &written)
- || written != len)
- return EIO;
- return 0;
-}
-
-/* Read disk block ADDR from DISKFS_DEVICE; put the address of the data in
- DATA; read LEN bytes. Always *DATA should be a full page no matter what.
- ADDR is offset by DISKFS_DEVICE_START. If an error occurs, EIO is
- returned. */
-error_t
-diskfs_device_read_sync (off_t addr, vm_address_t *data, size_t len)
-{
- unsigned read;
- if (device_read (diskfs_device, 0, diskfs_device_start + addr, len,
- (io_buf_ptr_t *)data, &read)
- || read != len)
- return EIO;
- return 0;
-}
-
diff --git a/libdiskfs/dev-open.c b/libdiskfs/dev-open.c
deleted file mode 100644
index 5b45c30e..00000000
--- a/libdiskfs/dev-open.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Standard device opening
-
- Copyright (C) 1995 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <diskfs.h>
-
-/* Uses the values of DISKFS_DEVICE_ARG and DISKFS_USE_MACH_DEVICE, and
- attempts to open the device and set the values of DISKFS_DEVICE,
- DISKFS_DEVICE_NAME, DISKFS_DEVICE_START, DISKFS_DEVICE_SIZE, and
- DISKFS_DEVICE_BLOCK_SIZE. */
-error_t
-diskfs_device_open ()
-{
- error_t err;
- if (diskfs_use_mach_device)
- {
- diskfs_device_name = diskfs_device_arg;
- err =
- diskfs_get_mach_device (diskfs_device_name, &diskfs_device,
- &diskfs_device_start, &diskfs_device_size,
- &diskfs_device_block_size);
- }
- else
- err =
- diskfs_get_file_device (diskfs_device_arg,
- &diskfs_device_name, &diskfs_device,
- &diskfs_device_start, &diskfs_device_size,
- &diskfs_device_block_size);
-
- if (! err)
- {
- diskfs_log2_device_block_size = 0;
- while ((1 << diskfs_log2_device_block_size) < diskfs_device_block_size)
- diskfs_log2_device_block_size++;
- while ((1 << diskfs_log2_device_block_size) != diskfs_device_block_size)
- diskfs_log2_device_block_size = 0;
-
- diskfs_log2_device_blocks_per_page = 0;
- while ((diskfs_device_block_size << diskfs_log2_device_blocks_per_page)
- < vm_page_size)
- diskfs_log2_device_blocks_per_page++;
- if ((diskfs_device_block_size << diskfs_log2_device_blocks_per_page)
- != vm_page_size)
- diskfs_log2_device_blocks_per_page = 0;
- }
-
- return err;
-}
diff --git a/libdiskfs/dir-chg.c b/libdiskfs/dir-chg.c
index 42dfb161..7ca34447 100644
--- a/libdiskfs/dir-chg.c
+++ b/libdiskfs/dir-chg.c
@@ -1,5 +1,5 @@
/* Notifications of directory changes.
- Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1998, 2001 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
@@ -17,40 +17,66 @@
#include "priv.h"
#include "fs_S.h"
-#include "ourfs_notify_U.h"
+#include "fs_notify_U.h"
kern_return_t
diskfs_S_dir_notice_changes (struct protid *cred,
mach_port_t notify)
{
- struct dirmod *req;
+ error_t err;
+ struct modreq *req;
struct node *np;
-
+
if (!cred)
return EOPNOTSUPP;
np = cred->po->np;
- req = malloc (sizeof (struct dirmod));
mutex_lock (&np->lock);
if (!S_ISDIR (np->dn_stat.st_mode))
{
mutex_unlock (&np->lock);
return ENOTDIR;
}
+ err = dir_changed (notify, np->dirmod_tick, DIR_CHANGED_NULL, "");
+ if (err)
+ {
+ mutex_unlock (&np->lock);
+ return err;
+ }
+ req = malloc (sizeof (struct modreq));
+ if (! req)
+ {
+ mutex_unlock (&np->lock);
+ return ENOMEM;
+ }
req->port = notify;
req->next = np->dirmod_reqs;
np->dirmod_reqs = req;
- nowait_dir_changed (notify, DIR_CHANGED_NULL, "");
mutex_unlock (&np->lock);
return 0;
}
void
diskfs_notice_dirchange (struct node *dp, enum dir_changed_type type,
- char *name)
+ const char *name)
{
- struct dirmod *req;
-
- for (req = dp->dirmod_reqs; req; req = req->next)
- nowait_dir_changed (req->port, type, name);
-}
+ error_t err;
+ struct modreq **preq;
+
+ dp->dirmod_tick++;
+ preq = &dp->dirmod_reqs;
+ while (*preq)
+ {
+ struct modreq *req = *preq;
+ err = dir_changed (req->port, dp->dirmod_tick, type, name);
+ if (err && err != MACH_SEND_TIMED_OUT)
+ {
+ /* Remove notify port. */
+ *preq = req->next;
+ mach_port_deallocate (mach_task_self (), req->port);
+ free (req);
+ }
+ else
+ preq = &req->next;
+ }
+}
diff --git a/libdiskfs/dir-clear.c b/libdiskfs/dir-clear.c
index 4cb300e2..7cf32358 100644
--- a/libdiskfs/dir-clear.c
+++ b/libdiskfs/dir-clear.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 1995, 1996, 1997 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
diff --git a/libdiskfs/dir-init.c b/libdiskfs/dir-init.c
index 67dc34eb..2cba3a4b 100644
--- a/libdiskfs/dir-init.c
+++ b/libdiskfs/dir-init.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 1995, 1996, 1997 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
@@ -28,10 +28,12 @@ diskfs_init_dir (struct node *dp, struct node *pdp, struct protid *cred)
struct dirstat *ds = alloca (diskfs_dirstat_size);
struct node *foo;
error_t err;
+
+ /* Fabricate a protid that represents root credentials. */
static uid_t zero = 0;
- static struct protid lookupcred = {{0, 0, 0, 0},
- &zero, &zero, 1, 1,
- 0, 0};
+ static struct idvec vec = {&zero, 1, 1};
+ static struct iouser user = {&vec, &vec, 0};
+ struct protid lookupcred = {{0, 0, 0, 0}, &user, cred->po, 0, 0};
/* New links */
if (pdp->dn_stat.st_nlink == diskfs_link_max - 1)
diff --git a/libdiskfs/dir-link.c b/libdiskfs/dir-link.c
index 27928d05..7cc88633 100644
--- a/libdiskfs/dir-link.c
+++ b/libdiskfs/dir-link.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: dir_link
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,97,99 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
@@ -31,16 +31,16 @@ diskfs_S_dir_link (struct protid *dircred,
struct dirstat *ds = alloca (diskfs_dirstat_size);
error_t error;
- if (!filecred)
+ if (!dircred)
return EOPNOTSUPP;
-
- np = filecred->po->np;
+
if (diskfs_check_readonly ())
return EROFS;
-
- if (!dircred)
+
+ if (!filecred)
return EXDEV;
-
+
+ np = filecred->po->np;
mutex_lock (&np->lock);
if (S_ISDIR (np->dn_stat.st_mode))
{
@@ -48,7 +48,7 @@ diskfs_S_dir_link (struct protid *dircred,
return EISDIR;
}
mutex_unlock (&np->lock);
-
+
dnp = dircred->po->np;
mutex_lock (&dnp->lock);
@@ -61,6 +61,8 @@ diskfs_S_dir_link (struct protid *dircred,
}
if (error && error != ENOENT)
{
+ if (error == EAGAIN)
+ error = EINVAL;
diskfs_drop_dirstat (dnp, ds);
mutex_unlock (&dnp->lock);
return error;
@@ -74,7 +76,7 @@ diskfs_S_dir_link (struct protid *dircred,
mach_port_deallocate (mach_task_self (), filecred->pi.port_right);
return 0;
}
-
+
if (tnp && S_ISDIR (tnp->dn_stat.st_mode))
{
diskfs_drop_dirstat (dnp, ds);
@@ -82,13 +84,13 @@ diskfs_S_dir_link (struct protid *dircred,
mutex_unlock (&tnp->lock);
return EISDIR;
}
-
+
/* Create new entry for NP */
/* This is safe because NP is not a directory (thus not DNP) and
not TNP and is a leaf. */
mutex_lock (&np->lock);
-
+
/* Increment link count */
if (np->dn_stat.st_nlink == diskfs_link_max - 1)
{
@@ -100,7 +102,7 @@ diskfs_S_dir_link (struct protid *dircred,
np->dn_stat.st_nlink++;
np->dn_set_ctime = 1;
diskfs_node_update (np, 1);
-
+
/* Attach it */
if (tnp)
{
@@ -118,10 +120,10 @@ diskfs_S_dir_link (struct protid *dircred,
}
else
error = diskfs_direnter (dnp, name, np, ds, dircred);
-
+
if (diskfs_synchronous)
diskfs_node_update (dnp, 1);
-
+
mutex_unlock (&dnp->lock);
mutex_unlock (&np->lock);
if (!error)
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index c8138254..7e092908 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -1,5 +1,6 @@
/* libdiskfs implementation of fs.defs:dir_lookup
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2008 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
@@ -15,16 +16,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include "priv.h"
-#include "fs_S.h"
+#include <stdio.h>
#include <fcntl.h>
#include <string.h>
+#include <sys/file.h>
#include <hurd/fsys.h>
#include <hurd/paths.h>
-/* XXX - Temporary hack; this belongs in a header file, probably types.h. */
-#define major(x) ((int)(((unsigned) (x) >> 8) & 0xff))
-#define minor(x) ((int)((x) & 0xff))
+#include "priv.h"
+#include "fs_S.h"
/* Implement dir_lookup as described in <hurd/fs.defs>. */
kern_return_t
@@ -51,15 +51,16 @@ diskfs_S_dir_lookup (struct protid *dircred,
int newnode = 0;
struct dirstat *ds = 0;
int mustbedir = 0;
- int amt;
+ size_t amt;
int type;
- struct protid *newpi;
+ struct protid *newpi = 0;
+ struct peropen *newpo = 0;
if (!dircred)
return EOPNOTSUPP;
flags &= O_HURD;
-
+
create = (flags & O_CREAT);
excl = (flags & O_EXCL);
@@ -73,8 +74,6 @@ diskfs_S_dir_lookup (struct protid *dircred,
if (path[0] == '\0')
{
- mustbedir = 1;
-
/* Set things up in the state expected by the code from gotit: on. */
dnp = 0;
np = dircred->po->np;
@@ -84,6 +83,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
}
dnp = dircred->po->np;
+
mutex_lock (&dnp->lock);
np = 0;
@@ -92,7 +92,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
do
{
assert (!lastcomp);
-
+
/* Find the name of the next pathname component */
nextname = index (path, '/');
@@ -114,14 +114,14 @@ diskfs_S_dir_lookup (struct protid *dircred,
}
else
lastcomp = 1;
-
+
np = 0;
/* diskfs_lookup the next pathname component */
if (lastcomp && create)
{
- assert (!ds);
- ds = alloca (diskfs_dirstat_size);
+ if (!ds)
+ ds = alloca (diskfs_dirstat_size);
error = diskfs_lookup (dnp, path, CREATE, &np, ds, dircred);
}
else
@@ -133,10 +133,37 @@ diskfs_S_dir_lookup (struct protid *dircred,
/* If we get an error we're done */
if (error == EAGAIN)
{
- if (dircred->po->dotdotport != MACH_PORT_NULL)
+ if (dnp == dircred->po->shadow_root)
+ /* We're at the root of a shadow tree. */
+ {
+ if (dircred->po->shadow_root_parent == MACH_PORT_NULL)
+ {
+ /* This is a shadow root with no parent, meaning
+ we should treat it as a virtual root disconnected
+ from its real .. directory. */
+ error = 0;
+ np = dnp;
+ diskfs_nref (np);
+ }
+ else
+ {
+ /* Punt the client up to the shadow root parent. */
+ *retry = FS_RETRY_REAUTH;
+ *returned_port = dircred->po->shadow_root_parent;
+ *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
+ if (! lastcomp)
+ strcpy (retryname, nextname);
+ error = 0;
+ goto out;
+ }
+ }
+ else if (dircred->po->root_parent != MACH_PORT_NULL)
+ /* We're at a real translator root; even if DIRCRED->po has a
+ shadow root, we can get here if its in a directory that was
+ renamed out from under it... */
{
*retry = FS_RETRY_REAUTH;
- *returned_port = dircred->po->dotdotport;
+ *returned_port = dircred->po->root_parent;
*returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
if (!lastcomp)
strcpy (retryname, nextname);
@@ -144,6 +171,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
goto out;
}
else
+ /* We're at a REAL root, as in there's no way up from here. */
{
error = 0;
np = dnp;
@@ -156,7 +184,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
{
if (error == ENOENT)
{
- mode &= ~(S_IFMT | S_ISPARE | S_ISVTX);
+ mode &= ~(S_IFMT | S_ISPARE | S_ISVTX | S_ITRANS);
mode |= S_IFREG;
error = diskfs_create_node (dnp, path, mode, &np, dircred, ds);
if (diskfs_synchronous)
@@ -169,26 +197,27 @@ diskfs_S_dir_lookup (struct protid *dircred,
else
diskfs_drop_dirstat (dnp, ds);
}
-
+
if (error)
goto out;
/* If this is translated, start the translator (if necessary)
and return. */
if ((((flags & O_NOTRANS) == 0) || !lastcomp)
- && (np->istranslated
+ && ((np->dn_stat.st_mode & S_IPTRANS)
|| S_ISFIFO (np->dn_stat.st_mode)
|| S_ISCHR (np->dn_stat.st_mode)
|| S_ISBLK (np->dn_stat.st_mode)
|| fshelp_translated (&np->transbox)))
{
mach_port_t dirport;
-
+ struct iouser *user;
+
/* A callback function for short-circuited translators.
Symlink & ifsock are handled elsewhere. */
error_t short_circuited_callback1 (void *cookie1, void *cookie2,
uid_t *uid, gid_t *gid,
- char **argz, int *argz_len)
+ char **argz, size_t *argz_len)
{
struct node *node = cookie1;
@@ -221,25 +250,33 @@ diskfs_S_dir_lookup (struct protid *dircred,
/* Create an unauthenticated port for DNP, and then
unlock it. */
- error =
- diskfs_create_protid (diskfs_make_peropen (dnp, 0,
- dircred->po->dotdotport),
- 0, 0, 0, 0, &newpi);
+ error = iohelp_create_empty_iouser (&user);
+ if (! error)
+ {
+ error = diskfs_make_peropen (dnp, 0, dircred->po, &newpo);
+ if (! error)
+ {
+ error = diskfs_create_protid (newpo, user, &newpi);
+ if (! error)
+ newpo = 0;
+ }
+
+ iohelp_free_iouser (user);
+ }
+
if (error)
goto out;
- dirport = ports_get_right (newpi);
- mach_port_insert_right (mach_task_self (), dirport, dirport,
- MACH_MSG_TYPE_MAKE_SEND);
+ dirport = ports_get_send_right (newpi);
ports_port_deref (newpi);
+ newpi = 0;
if (np != dnp)
mutex_unlock (&dnp->lock);
- error = fshelp_fetch_root (&np->transbox, &dircred->po->dotdotport,
- dirport, dircred->uids, dircred->nuids,
- dircred->gids, dircred->ngids,
+ error = fshelp_fetch_root (&np->transbox, dircred->po,
+ dirport, dircred->user,
lastcomp ? flags : 0,
- (np->istranslated
+ ((np->dn_stat.st_mode & S_IPTRANS)
? _diskfs_translator_callback1
: short_circuited_callback1),
_diskfs_translator_callback2,
@@ -256,8 +293,9 @@ diskfs_S_dir_lookup (struct protid *dircred,
*returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
if (!lastcomp && !error)
{
- strcat (retryname, "/");
- strcat (retryname, nextname);
+ char *end = strchr (retryname, '\0');
+ *end++ = '/';
+ strcpy (end, nextname);
}
return error;
}
@@ -278,9 +316,11 @@ diskfs_S_dir_lookup (struct protid *dircred,
}
}
}
-
+
if (S_ISLNK (np->dn_stat.st_mode)
- && !(lastcomp && (flags & (O_NOLINK|O_NOTRANS))))
+ && (!lastcomp
+ || mustbedir /* "foo/" must see that foo points to a dir */
+ || !(flags & (O_NOLINK|O_NOTRANS))))
{
/* Handle symlink interpretation */
@@ -289,51 +329,70 @@ diskfs_S_dir_lookup (struct protid *dircred,
error = ELOOP;
goto out;
}
-
+
nextnamelen = nextname ? strlen (nextname) + 1 : 0;
- newnamelen = nextnamelen + np->dn_stat.st_size + 1;
+ newnamelen = nextnamelen + np->dn_stat.st_size + 1 + 1;
if (pathbuflen < newnamelen)
{
pathbuf = alloca (newnamelen);
pathbuflen = newnamelen;
}
-
+
if (diskfs_read_symlink_hook)
error = (*diskfs_read_symlink_hook)(np, pathbuf);
if (!diskfs_read_symlink_hook || error == EINVAL)
- error = diskfs_node_rdwr (np, pathbuf,
- 0, np->dn_stat.st_size, 0,
- dircred, &amt);
- if (error)
- goto out;
-
- if (nextname)
{
- pathbuf[np->dn_stat.st_size] = '/';
- bcopy (nextname, pathbuf + np->dn_stat.st_size + 1,
- nextnamelen - 1);
+ error = diskfs_node_rdwr (np, pathbuf,
+ 0, np->dn_stat.st_size, 0,
+ dircred, &amt);
+ if (!error)
+ assert (amt == np->dn_stat.st_size);
}
- pathbuf[nextnamelen + np->dn_stat.st_size] = '\0';
+ if (error)
+ goto out;
- if (pathbuf[0] == '/')
+ if (np->dn_stat.st_size == 0) /* symlink to "" */
+ path = nextname;
+ else
{
- /* Punt to the caller. */
- *retry = FS_RETRY_MAGICAL;
- *returned_port = MACH_PORT_NULL;
- strcpy (retryname, pathbuf);
- goto out;
+ if (nextname)
+ {
+ pathbuf[np->dn_stat.st_size] = '/';
+ memcpy (pathbuf + np->dn_stat.st_size + 1,
+ nextname, nextnamelen - 1);
+ }
+ pathbuf[nextnamelen + np->dn_stat.st_size] = '\0';
+
+ if (pathbuf[0] == '/')
+ {
+ /* Punt to the caller. */
+ *retry = FS_RETRY_MAGICAL;
+ *returned_port = MACH_PORT_NULL;
+ memcpy (retryname, pathbuf,
+ nextnamelen + np->dn_stat.st_size + 1);
+ if (mustbedir)
+ {
+ retryname[nextnamelen + np->dn_stat.st_size] = '/';
+ retryname[nextnamelen + np->dn_stat.st_size + 1] = '\0';
+ }
+ goto out;
+ }
+
+ path = pathbuf;
}
-
- path = pathbuf;
+
if (lastcomp)
- {
- lastcomp = 0;
- /* Symlinks to nonexistent files aren't allowed to cause
- creation, so clear the flag here. */
- create = 0;
- }
+ lastcomp = 0;
+
diskfs_nput (np);
np = 0;
+
+ if (path == 0) /* symlink to "" was the last component */
+ {
+ np = dnp;
+ dnp = 0;
+ break;
+ }
}
else
{
@@ -352,7 +411,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
dnp = 0;
}
} while (path && *path);
-
+
/* At this point, np is the node to return. If newnode is set, then
we just created this node. */
@@ -364,20 +423,21 @@ diskfs_S_dir_lookup (struct protid *dircred,
error = ENOTDIR;
goto out;
}
-
+
if (!newnode)
/* Check permissions on existing nodes, but not new ones. */
{
- if ((type == S_IFSOCK || type == S_IFBLK || type == S_IFLNK
- || type == S_IFCHR || type == S_IFIFO)
- && (flags & (O_READ|O_WRITE|O_EXEC)))
- error = EOPNOTSUPP;
+ if (((type == S_IFSOCK || type == S_IFBLK || type == S_IFCHR ||
+ type == S_IFIFO)
+ && (flags & (O_READ|O_WRITE|O_EXEC)))
+ || (type == S_IFLNK && (flags & (O_WRITE|O_EXEC))))
+ error = EACCES;
if (!error && (flags & O_READ))
- error = diskfs_access (np, S_IREAD, dircred);
+ error = fshelp_access (&np->dn_stat, S_IREAD, dircred->user);
if (!error && (flags & O_EXEC))
- error = diskfs_access (np, S_IEXEC, dircred);
+ error = fshelp_access (&np->dn_stat, S_IEXEC, dircred->user);
if (!error && (flags & O_WRITE))
{
@@ -386,29 +446,41 @@ diskfs_S_dir_lookup (struct protid *dircred,
else if (diskfs_check_readonly ())
error = EROFS;
else
- error = diskfs_access (np, S_IWRITE, dircred);
+ error = fshelp_access (&np->dn_stat, S_IWRITE, dircred->user);
}
if (error)
goto out;
}
-
- if ((flags & O_NOATIME) && (diskfs_isowner (np, dircred) == EPERM))
+
+ if ((flags & O_NOATIME)
+ && (fshelp_isowner (&np->dn_stat, dircred->user) == EPERM))
flags &= ~O_NOATIME;
- flags &= ~OPENONLY_STATE_MODES;
-
- error = diskfs_create_protid (diskfs_make_peropen (np, flags,
- dircred->po->dotdotport),
- dircred->uids, dircred->nuids,
- dircred->gids, dircred->ngids,
- &newpi);
+ error = diskfs_make_peropen (np, (flags &~OPENONLY_STATE_MODES),
+ dircred->po, &newpo);
+
+ if (! error)
+ error = diskfs_create_protid (newpo, dircred->user, &newpi);
+
+ if (! error)
+ {
+ newpo = 0;
+ if (flags & O_EXLOCK)
+ error = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status,
+ &np->lock, LOCK_EX);
+ else if (flags & O_SHLOCK)
+ error = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status,
+ &np->lock, LOCK_SH);
+ }
+
if (! error)
{
*returned_port = ports_get_right (newpi);
ports_port_deref (newpi);
+ newpi = 0;
}
-
+
out:
if (np)
{
@@ -419,5 +491,11 @@ diskfs_S_dir_lookup (struct protid *dircred,
}
if (dnp)
diskfs_nput (dnp);
+
+ if (newpi)
+ ports_port_deref (newpi);
+ if (newpo)
+ diskfs_release_peropen (newpo);
+
return error;
}
diff --git a/libdiskfs/dir-mkdir.c b/libdiskfs/dir-mkdir.c
index 89477755..30d7a3b4 100644
--- a/libdiskfs/dir-mkdir.c
+++ b/libdiskfs/dir-mkdir.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: dir_mkdir
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,97,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
@@ -31,7 +31,7 @@ diskfs_S_dir_mkdir (struct protid *dircred,
if (!dircred)
return EOPNOTSUPP;
-
+
dnp = dircred->po->np;
if (diskfs_check_readonly ())
return EROFS;
@@ -39,7 +39,6 @@ diskfs_S_dir_mkdir (struct protid *dircred,
mutex_lock (&dnp->lock);
error = diskfs_lookup (dnp, name, CREATE, 0, ds, dircred);
-
if (error == EAGAIN)
error = EEXIST;
if (!error)
@@ -52,7 +51,7 @@ diskfs_S_dir_mkdir (struct protid *dircred,
return error;
}
- mode &= ~(S_ISPARE | S_IFMT);
+ mode &= ~(S_ISPARE | S_IFMT | S_ITRANS);
mode |= S_IFDIR;
error = diskfs_create_node (dnp, name, mode, &np, dircred, ds);
diff --git a/libdiskfs/dir-mkfile.c b/libdiskfs/dir-mkfile.c
index cdfe6e31..914b18fe 100644
--- a/libdiskfs/dir-mkfile.c
+++ b/libdiskfs/dir-mkfile.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+/* libdiskfs implementation of fs.defs: dir_mkfile
+ Copyright (C) 1994,95,96,97,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.
@@ -34,7 +34,8 @@ diskfs_S_dir_mkfile (struct protid *cred,
struct node *dnp, *np;
error_t err;
struct protid *newpi;
-
+ struct peropen *newpo;
+
if (!cred)
return EOPNOTSUPP;
if (diskfs_check_readonly ())
@@ -46,14 +47,14 @@ diskfs_S_dir_mkfile (struct protid *cred,
mutex_unlock (&dnp->lock);
return ENOTDIR;
}
- err = diskfs_access (dnp, S_IWRITE, cred);
+ err = fshelp_access (&dnp->dn_stat, S_IWRITE, cred->user);
if (err)
{
mutex_unlock (&dnp->lock);
return err;
}
-
- mode &= ~(S_IFMT | S_ISPARE | S_ISVTX);
+
+ mode &= ~(S_IFMT | S_ISPARE | S_ISVTX | S_ITRANS);
mode |= S_IFREG;
err = diskfs_create_node (dnp, 0, mode, &np, cred, 0);
mutex_unlock (&dnp->lock);
@@ -66,13 +67,17 @@ diskfs_S_dir_mkfile (struct protid *cred,
if (err)
return err;
-
- flags &= (O_READ | O_WRITE | O_EXEC);
- err = diskfs_create_protid (diskfs_make_peropen (np, flags,
- cred->po->dotdotport),
- cred->uids, cred->nuids,
- cred->gids, cred->ngids,
- &newpi);
+
+ flags &= ~OPENONLY_STATE_MODES; /* These bits are all meaningless here. */
+
+ err = diskfs_make_peropen (np, flags, cred->po, &newpo);
+ if (! err)
+ {
+ err = diskfs_create_protid (newpo, cred->user, &newpi);
+ if (err)
+ diskfs_release_peropen (newpo);
+ }
+
if (! err)
{
*newnode = ports_get_right (newpi);
@@ -84,5 +89,3 @@ diskfs_S_dir_mkfile (struct protid *cred,
return err;
}
-
-
diff --git a/libdiskfs/dir-readdir.c b/libdiskfs/dir-readdir.c
index c66b2dce..d2f9d750 100644
--- a/libdiskfs/dir-readdir.c
+++ b/libdiskfs/dir-readdir.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1993, 1994, 1996 Free Software Foundation
+ Copyright (C) 1993,94,96,99,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.
@@ -26,7 +26,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
kern_return_t
diskfs_S_dir_readdir (struct protid *cred,
char **data,
- u_int *datacnt,
+ size_t *datacnt,
+ boolean_t *data_dealloc,
int entry,
int nentries,
vm_size_t bufsiz,
@@ -54,8 +55,7 @@ diskfs_S_dir_readdir (struct protid *cred,
}
err = diskfs_get_directs (np, entry, nentries, data, datacnt, bufsiz, amt);
+ *data_dealloc = 1; /* XXX */
mutex_unlock (&np->lock);
return err;
}
-
-
diff --git a/libdiskfs/dir-rename.c b/libdiskfs/dir-rename.c
index 7e993def..867e395d 100644
--- a/libdiskfs/dir-rename.c
+++ b/libdiskfs/dir-rename.c
@@ -1,5 +1,7 @@
/* libdiskfs implementation of fs.defs: dir_rename
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 2007
+ 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,6 +19,7 @@
#include "priv.h"
#include "fs_S.h"
+#include <string.h>
/* To avoid races in checkpath, and to prevent a directory from being
simultaneously renamed by two processes, we serialize all renames of
@@ -39,7 +42,15 @@ diskfs_S_dir_rename (struct protid *fromcred,
return EOPNOTSUPP;
/* Verify that tocred really is a port to us. */
- if (!tocred)
+ if (! tocred)
+ return EXDEV;
+
+ if (!strcmp (fromname, ".") || !strcmp (fromname, "..")
+ || !strcmp (toname, ".") || !strcmp (toname, ".."))
+ return EINVAL;
+
+ if (tocred->po->shadow_root != fromcred->po->shadow_root)
+ /* Same translator, but in different shadow trees. */
return EXDEV;
if (diskfs_check_readonly ())
@@ -55,6 +66,8 @@ diskfs_S_dir_rename (struct protid *fromcred,
mutex_lock (&fdp->lock);
err = diskfs_lookup (fdp, fromname, LOOKUP, &fnp, 0, fromcred);
mutex_unlock (&fdp->lock);
+ if (err == EAGAIN)
+ err = EINVAL;
if (err)
return err;
@@ -100,7 +113,9 @@ diskfs_S_dir_rename (struct protid *fromcred,
mutex_lock (&tdp->lock);
err = diskfs_lookup (tdp, toname, RENAME, &tnp, ds, tocred);
- if (!err && excl)
+ if (err == EAGAIN)
+ err = EINVAL;
+ else if (!err && excl)
{
err = EEXIST;
diskfs_nput (tnp);
@@ -130,6 +145,7 @@ diskfs_S_dir_rename (struct protid *fromcred,
{
diskfs_drop_dirstat (tdp, ds);
diskfs_nrele (fnp);
+ diskfs_nput (tnp);
mutex_unlock (&tdp->lock);
return EISDIR;
}
@@ -141,6 +157,8 @@ diskfs_S_dir_rename (struct protid *fromcred,
{
diskfs_drop_dirstat (tdp, ds);
diskfs_nput (fnp);
+ if (tnp)
+ diskfs_nput (tnp);
mutex_unlock (&tdp->lock);
return EMLINK;
}
diff --git a/libdiskfs/dir-renamed.c b/libdiskfs/dir-renamed.c
index 6ef96ee3..79381b2c 100644
--- a/libdiskfs/dir-renamed.c
+++ b/libdiskfs/dir-renamed.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+/*
+ Copyright (C) 1994,95,96,97,98,99,2001,2003 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
@@ -31,8 +31,7 @@ checkpath(struct node *source,
{
error_t err;
struct node *np;
-
- np = target;
+
for (np = target, err = 0;
/* nothing */;
/* This special lookup does a diskfs_nput on its first argument
@@ -44,20 +43,20 @@ checkpath(struct node *source,
diskfs_nput (np);
return err;
}
-
+
if (np == source)
{
diskfs_nput (np);
return EINVAL;
}
-
+
if (np == diskfs_root_node)
{
diskfs_nput (np);
return 0;
}
}
-}
+}
/* Rename directory node FNP (whose parent is FDP, and which has name
FROMNAME in that directory) to have name TONAME inside directory
@@ -67,9 +66,9 @@ checkpath(struct node *source,
routine. FROMCRED and TOCRED are the users responsible for
FDP/FNP and TDP respectively. */
error_t
-diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
- struct node *tdp, char *toname, struct protid *fromcred,
- struct protid *tocred)
+diskfs_rename_dir (struct node *fdp, struct node *fnp, const char *fromname,
+ struct node *tdp, const char *toname,
+ struct protid *fromcred, struct protid *tocred)
{
error_t err;
struct node *tnp, *tmpnp;
@@ -81,32 +80,40 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
diskfs_nref (tdp); /* reference and lock will get consumed by
checkpath */
err = checkpath (fnp, tdp, tocred);
-
+
if (err)
return err;
-
+
/* Now, lock the parent directories. This is legal because tdp is not
a child of fnp (guaranteed by checkpath above). */
mutex_lock (&fdp->lock);
if (fdp != tdp)
mutex_lock (&tdp->lock);
-
+
/* 1: Lookup target; if it exists, make sure it's an empty directory. */
ds = buf;
err = diskfs_lookup (tdp, toname, RENAME, &tnp, ds, tocred);
-
+ assert (err != EAGAIN); /* <-> assert (TONAME != "..") */
+
if (tnp == fnp)
{
diskfs_drop_dirstat (tdp, ds);
- diskfs_nrele (tnp);
+ diskfs_nput (tnp);
mutex_unlock (&tdp->lock);
if (fdp != tdp)
mutex_unlock (&fdp->lock);
return 0;
}
-
- /* Now we can safely lock fnp */
- mutex_lock (&fnp->lock);
+
+ /* Check permissions to remove FROMNAME and lock FNP. */
+ tmpds = alloca (diskfs_dirstat_size);
+ err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, tmpds, fromcred);
+ assert (!tmpnp || tmpnp == fnp);
+ if (tmpnp)
+ diskfs_nrele (tmpnp);
+ diskfs_drop_dirstat (fdp, tmpds);
+ if (err)
+ goto out;
if (tnp)
{
@@ -114,7 +121,7 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
err = ENOTDIR;
else if (!diskfs_dirempty (tnp, tocred))
err = ENOTEMPTY;
- }
+ }
if (err && err != ENOENT)
goto out;
@@ -131,24 +138,24 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
tdp->dn_set_ctime = 1;
if (diskfs_synchronous)
diskfs_node_update (tdp, 1);
-
+
tmpds = alloca (diskfs_dirstat_size);
- err = diskfs_lookup (fnp, "..", RENAME | SPEC_DOTDOT,
+ err = diskfs_lookup (fnp, "..", RENAME | SPEC_DOTDOT,
&tmpnp, tmpds, fromcred);
assert (err != ENOENT);
- assert (tmpnp == fdp);
if (err)
{
diskfs_drop_dirstat (fnp, tmpds);
goto out;
}
+ assert (tmpnp == fdp);
err = diskfs_dirrewrite (fnp, fdp, tdp, "..", tmpds);
if (diskfs_synchronous)
diskfs_file_update (fnp, 1);
if (err)
goto out;
-
+
fdp->dn_stat.st_nlink--;
fdp->dn_set_ctime = 1;
if (diskfs_synchronous)
@@ -170,7 +177,7 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
fnp->dn_stat.st_nlink++;
fnp->dn_set_ctime = 1;
diskfs_node_update (fnp, 1);
-
+
if (tnp)
{
err = diskfs_dirrewrite (tdp, tnp, fnp, toname, ds);
@@ -198,11 +205,12 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
ds = buf;
mutex_unlock (&fnp->lock);
err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, ds, fromcred);
- assert (tmpnp == fnp);
- diskfs_nrele (tmpnp);
+ assert (!tmpnp || tmpnp == fnp);
+ if (tmpnp)
+ diskfs_nrele (tmpnp);
if (err)
goto out;
-
+
diskfs_dirremove (fdp, fnp, fromname, ds);
ds = 0;
fnp->dn_stat.st_nlink--;
diff --git a/libdiskfs/dir-rmdir.c b/libdiskfs/dir-rmdir.c
index 70c87d03..a90ff07b 100644
--- a/libdiskfs/dir-rmdir.c
+++ b/libdiskfs/dir-rmdir.c
@@ -1,5 +1,5 @@
/* libdsikfs implementation of fs.defs: dir_rmdir
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,97,99 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
@@ -25,13 +25,27 @@ diskfs_S_dir_rmdir (struct protid *dircred,
char *name)
{
struct node *dnp;
- struct node *np = 0;
+ struct node *np;
struct dirstat *ds = alloca (diskfs_dirstat_size);
error_t error;
+ /* This routine cleans up the state we have after calling diskfs_lookup.
+ After that call, all returns are done with `return done (ERROR, NP);'. */
+ inline error_t done (error_t error, struct node *np)
+ {
+ if (np)
+ diskfs_nput (np);
+
+ if (ds)
+ diskfs_drop_dirstat (dnp, ds);
+ mutex_unlock (&dnp->lock);
+
+ return error;
+ }
+
if (!dircred)
return EOPNOTSUPP;
-
+
dnp = dircred->po->np;
if (diskfs_check_readonly ())
return EROFS;
@@ -39,44 +53,32 @@ diskfs_S_dir_rmdir (struct protid *dircred,
mutex_lock (&dnp->lock);
error = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred);
- if (error == EAGAIN)
- error = ENOTEMPTY;
if (error)
- {
- mutex_unlock (&dnp->lock);
- diskfs_drop_dirstat (dnp, ds);
- return error;
- }
+ return done (error == EAGAIN ? ENOTEMPTY : error, 0);
- /* Attempt to rmdir(".") */
if (dnp == np)
{
+ /* Attempt to rmdir(".") */
diskfs_nrele (np);
diskfs_drop_dirstat (dnp, ds);
mutex_unlock (&dnp->lock);
return EINVAL;
}
- if (np->istranslated || fshelp_translated (&np->transbox))
- {
- diskfs_drop_dirstat (dnp, ds);
- diskfs_nput (np);
- mutex_unlock (&dnp->lock);
- return EBUSY;
- }
+ if ((np->dn_stat.st_mode & S_IPTRANS) || fshelp_translated (&np->transbox))
+ /* Attempt to rmdir a translated node. */
+ return done (EBUSY, np);
+
+ if (!S_ISDIR (np->dn_stat.st_mode))
+ return done (ENOTDIR, np);
- /* Verify the directory is empty (and valid). (Rmdir ".." won't be
- valid since ".." will contain a reference to the current directory and
- thus be non-empty). */
if (!diskfs_dirempty (np, dircred))
- {
- diskfs_nput (np);
- diskfs_drop_dirstat (dnp, ds);
- mutex_unlock (&dnp->lock);
- return ENOTEMPTY;
- }
+ return done (ENOTEMPTY, np);
+ /* Here we go! */
error = diskfs_dirremove (dnp, np, name, ds);
+ ds = 0;
+
if (!error)
{
np->dn_stat.st_nlink--;
@@ -88,7 +90,5 @@ diskfs_S_dir_rmdir (struct protid *dircred,
if (diskfs_synchronous)
diskfs_file_update (dnp, 1);
- diskfs_nput (np);
- mutex_unlock (&dnp->lock);
- return 0;
+ return done (error, np);
}
diff --git a/libdiskfs/dir-unlink.c b/libdiskfs/dir-unlink.c
index 34fe0b67..e40aead5 100644
--- a/libdiskfs/dir-unlink.c
+++ b/libdiskfs/dir-unlink.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: dir_unlink
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,97,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
@@ -32,7 +32,7 @@ diskfs_S_dir_unlink (struct protid *dircred,
if (!dircred)
return EOPNOTSUPP;
-
+
dnp = dircred->po->np;
if (diskfs_check_readonly ())
return EROFS;
@@ -41,14 +41,14 @@ diskfs_S_dir_unlink (struct protid *dircred,
error = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred);
if (error == EAGAIN)
- error = EISDIR;
+ error = EPERM; /* 1003.1-1996 5.5.1.4 */
if (error)
{
diskfs_drop_dirstat (dnp, ds);
mutex_unlock (&dnp->lock);
return error;
}
-
+
/* This isn't the BSD behavior, but it is Posix compliant and saves
us on several race conditions.*/
if (S_ISDIR(np->dn_stat.st_mode))
@@ -59,9 +59,9 @@ diskfs_S_dir_unlink (struct protid *dircred,
diskfs_nput (np);
diskfs_drop_dirstat (dnp, ds);
mutex_unlock (&dnp->lock);
- return EISDIR;
+ return EPERM; /* 1003.1-1996 5.5.1.4 */
}
-
+
error = diskfs_dirremove (dnp, np, name, ds);
if (diskfs_synchronous)
diskfs_node_update (dnp, 1);
@@ -71,7 +71,7 @@ diskfs_S_dir_unlink (struct protid *dircred,
mutex_unlock (&dnp->lock);
return error;
}
-
+
np->dn_stat.st_nlink--;
np->dn_set_ctime = 1;
if (diskfs_synchronous)
@@ -80,10 +80,10 @@ diskfs_S_dir_unlink (struct protid *dircred,
if (np->dn_stat.st_nlink == 0)
fshelp_fetch_control (&np->transbox, &control);
- /* This check is necessary because we might get here on an error while
+ /* This check is necessary because we might get here on an error while
checking the mode on something which happens to be `.'. */
if (np == dnp)
- diskfs_nrele (np);
+ diskfs_nrele (np);
else
diskfs_nput (np);
mutex_unlock (&dnp->lock);
diff --git a/libdiskfs/direnter.c b/libdiskfs/direnter.c
index ca0006eb..cb9b76ca 100644
--- a/libdiskfs/direnter.c
+++ b/libdiskfs/direnter.c
@@ -1,5 +1,5 @@
/* Wrapper for diskfs_direnter_hard
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -29,13 +29,13 @@
growth). This function is a wrapper for diskfs_direnter_hard. */
error_t
diskfs_direnter (struct node *dp,
- char *name,
+ const char *name,
struct node *np,
struct dirstat *ds,
struct protid *cred)
{
error_t err;
-
+
err = diskfs_direnter_hard (dp, name, np, ds, cred);
if (err)
return err;
@@ -45,5 +45,4 @@ diskfs_direnter (struct node *dp,
diskfs_enter_lookup_cache (dp, np, name);
return 0;
-}
-
+}
diff --git a/libdiskfs/dirremove.c b/libdiskfs/dirremove.c
index 8970d19a..239daa72 100644
--- a/libdiskfs/dirremove.c
+++ b/libdiskfs/dirremove.c
@@ -1,5 +1,5 @@
/* Wrapper for diskfs_dirremove_hard
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -27,20 +27,19 @@
call diskfs_notice_dirchange if DP->dirmod_reqs is nonzero. This
function is a wrapper for diskfs_dirremove_hard. The entry being
removed has name NAME and refers to NP. */
-error_t
-diskfs_dirremove (struct node *dp,
- struct node *np,
- char *name,
+error_t
+diskfs_dirremove (struct node *dp,
+ struct node *np,
+ const char *name,
struct dirstat *ds)
{
error_t err;
-
+
diskfs_purge_lookup_cache (dp, np);
-
+
err = diskfs_dirremove_hard (dp, ds);
-
+
if (!err && dp->dirmod_reqs)
diskfs_notice_dirchange (dp, DIR_CHANGED_UNLINK, name);
return err;
}
-
diff --git a/libdiskfs/dirrewrite.c b/libdiskfs/dirrewrite.c
index b2e750f5..8f713960 100644
--- a/libdiskfs/dirrewrite.c
+++ b/libdiskfs/dirrewrite.c
@@ -1,5 +1,5 @@
/* Wrapper for diskfs_dirrewrite_hard
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -29,23 +29,22 @@
diskfs_notice_dirchange if DP->dirmod_reqs is nonzero. NAME is the
name of OLDNP inside DP; it is this reference which is being
rewritten. This function is a wrapper for diskfs_dirrewrite_hard. */
-error_t diskfs_dirrewrite (struct node *dp,
+error_t diskfs_dirrewrite (struct node *dp,
struct node *oldnp,
struct node *np,
- char *name,
+ const char *name,
struct dirstat *ds)
{
error_t err;
-
+
diskfs_purge_lookup_cache (dp, oldnp);
-
+
err = diskfs_dirrewrite_hard (dp, np, ds);
if (err)
return err;
-
+
if (dp->dirmod_reqs)
diskfs_notice_dirchange (dp, DIR_CHANGED_RENUMBER, name);
diskfs_enter_lookup_cache (dp, np, name);
return 0;
}
-
diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
index 9ae2a2a5..fefd2ef4 100644
--- a/libdiskfs/disk-pager.c
+++ b/libdiskfs/disk-pager.c
@@ -1,5 +1,5 @@
/* Map the disk image and handle faults accessing it.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996,97,99,2001,02 Free Software Foundation, Inc.
Written by Roland McGrath.
This program is free software; you can redistribute it and/or
@@ -21,56 +21,53 @@
#include <hurd/sigpreempt.h>
#include <error.h>
-struct pager *disk_pager;
-void *disk_image;
-extern struct port_bucket *pager_bucket;
+struct pager *diskfs_disk_pager;
static void fault_handler (int sig, long int sigcode, struct sigcontext *scp);
-static struct hurd_signal_preempter preempter =
+static struct hurd_signal_preemptor preemptor =
{
signals: sigmask (SIGSEGV) | sigmask (SIGBUS),
- preempter: NULL,
+ preemptor: NULL,
handler: (sighandler_t) &fault_handler,
};
-
/* A top-level function for the paging thread that just services paging
requests. */
static void
-service_paging_requests (any_t foo __attribute__ ((unused)))
+service_paging_requests (any_t arg)
{
+ struct port_bucket *pager_bucket = arg;
for (;;)
- ports_manage_port_operations_multithread (pager_bucket, pager_demuxer,
- 1000 * 60 * 2, 1000 * 60 * 10,
- 1, MACH_PORT_NULL);
+ ports_manage_port_operations_multithread (pager_bucket,
+ pager_demuxer,
+ 1000 * 60 * 2,
+ 1000 * 60 * 10, 0);
}
void
-disk_pager_setup (struct user_pager_info *upi, int may_cache)
+diskfs_start_disk_pager (struct user_pager_info *upi,
+ struct port_bucket *pager_bucket, int may_cache,
+ size_t size, void **image)
{
error_t err;
mach_port_t disk_pager_port;
- if (! pager_bucket)
- pager_bucket = ports_create_bucket ();
-
/* Make a thread to service paging requests. */
cthread_detach (cthread_fork ((cthread_fn_t) service_paging_requests,
- (any_t) 0));
+ (any_t)pager_bucket));
/* Create the pager. */
- disk_pager = pager_create (upi, pager_bucket,
- may_cache, MEMORY_OBJECT_COPY_NONE);
- assert (disk_pager);
+ diskfs_disk_pager = pager_create (upi, pager_bucket,
+ may_cache, MEMORY_OBJECT_COPY_NONE);
+ assert (diskfs_disk_pager);
/* Get a port to the disk pager. */
- disk_pager_port = pager_get_port (disk_pager);
+ disk_pager_port = pager_get_port (diskfs_disk_pager);
mach_port_insert_right (mach_task_self (), disk_pager_port, disk_pager_port,
MACH_MSG_TYPE_MAKE_SEND);
/* Now map the disk image. */
- err = vm_map (mach_task_self (), (vm_address_t *)&disk_image,
- diskfs_device_size << diskfs_log2_device_block_size,
+ err = vm_map (mach_task_self (), (vm_address_t *)image, size,
0, 1, disk_pager_port, 0, 0,
VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE),
VM_PROT_READ | VM_PROT_WRITE,
@@ -78,11 +75,10 @@ disk_pager_setup (struct user_pager_info *upi, int may_cache)
if (err)
error (2, err, "cannot vm_map whole disk");
- /* Set up the signal preempter to catch faults on the disk image. */
- preempter.first = (vm_address_t) disk_image;
- preempter.last = ((vm_address_t) disk_image +
- (diskfs_device_size << diskfs_log2_device_block_size));
- hurd_preempt_signals (&preempter);
+ /* Set up the signal preemptor to catch faults on the disk image. */
+ preemptor.first = (vm_address_t) *image;
+ preemptor.last = ((vm_address_t) *image + size);
+ hurd_preempt_signals (&preemptor);
/* We have the mapping; we no longer need the send right. */
mach_port_deallocate (mach_task_self (), disk_pager_port);
@@ -94,14 +90,28 @@ fault_handler (int sig, long int sigcode, struct sigcontext *scp)
jmp_buf *env = cthread_data (cthread_self ());
error_t err;
- assert (env && "unexpected fault on disk image");
+#ifndef NDEBUG
+ if (!env)
+ {
+ error (0, 0,
+ "BUG: unexpected fault on disk image (%d, %#lx) in [%#lx,%#lx)"
+ " eip %#zx err %#x",
+ sig, sigcode,
+ preemptor.first, preemptor.last,
+ scp->sc_pc, scp->sc_error);
+ assert (scp->sc_error == EKERN_MEMORY_ERROR);
+ err = pager_get_error (diskfs_disk_pager, sigcode);
+ assert (err);
+ assert_perror (err);
+ }
+#endif
/* Clear the record, since the faulting thread will not. */
cthread_set_data (cthread_self (), 0);
/* Fetch the error code from the pager. */
assert (scp->sc_error == EKERN_MEMORY_ERROR);
- err = pager_get_error (disk_pager, sigcode);
+ err = pager_get_error (diskfs_disk_pager, sigcode);
assert (err);
/* Make `diskfault_catch' return the error code. */
diff --git a/libdiskfs/diskfs-pager.h b/libdiskfs/diskfs-pager.h
index a7d20c9d..4ec0b27b 100644
--- a/libdiskfs/diskfs-pager.h
+++ b/libdiskfs/diskfs-pager.h
@@ -1,5 +1,5 @@
/* Map the disk image and handle faults accessing it.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by Roland McGrath.
This program is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@
#ifndef _HURD_DISKFS_PAGER_H
#define _HURD_DISKFS_PAGER_H 1
+
#include <hurd/pager.h>
#include <hurd/ports.h>
#include <setjmp.h>
@@ -26,15 +27,16 @@
#include <assert.h>
#include <stdlib.h>
+/* Start a pager for the whole disk, and store it in DISKFS_DISK_PAGER,
+ preparing a signal preemptor so that the `diskfs_catch_exception' macro
+ below works. SIZE should be the size of the image to map, and the address
+ mapped is returned in IMAGE. INFO, PAGER_BUCKET, & MAY_CACHE are passed
+ to `pager_create'. */
+extern void diskfs_start_disk_pager (struct user_pager_info *info,
+ struct port_bucket *pager_bucket, int may_cache,
+ size_t size, void **image);
-/* Set up the three variables below and prepare a signal preempter
- so that the `diskfs_catch_exception' macro below works.
- INFO and MAY_CACHE are passed to `pager_create'. */
-extern void disk_pager_setup (struct user_pager_info *info, int may_cache);
-
-extern struct port_bucket *pager_bucket; /* Ports bucket used by pagers. */
-extern struct pager *disk_pager; /* Pager backing to the disk. */
-extern void *disk_image; /* Region mapping entire disk from it. */
+extern struct pager *diskfs_disk_pager;
struct disk_image_user
{
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 8cada32f..2051e41d 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -1,5 +1,7 @@
/* Definitions for fileserver helper functions
- Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2007, 2008,
+ 2009 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
@@ -18,13 +20,20 @@
#ifndef _HURD_DISKFS
#define _HURD_DISKFS
-#include <argp.h>
#include <assert.h>
#include <unistd.h>
#include <rwlock.h>
#include <hurd/ports.h>
#include <hurd/fshelp.h>
#include <hurd/iohelp.h>
+#include <idvec.h>
+#include <features.h>
+
+#ifdef DISKFS_DEFINE_EXTERN_INLINE
+#define DISKFS_EXTERN_INLINE
+#else
+#define DISKFS_EXTERN_INLINE __extern_inline
+#endif
/* Each user port referring to a file points to one of these
(with the aid of the ports library). */
@@ -33,8 +42,7 @@ struct protid
struct port_info pi; /* libports info block */
/* User identification */
- uid_t *uids, *gids;
- int nuids, ngids;
+ struct iouser *user;
/* Object this refers to */
struct peropen *po;
@@ -44,15 +52,23 @@ struct protid
struct shared_io *mapped;
};
-/* One of these is created for each node opened by dir_pathtrans. */
+/* One of these is created for each node opened by dir_lookup. */
struct peropen
{
int filepointer;
int lock_status;
int refcnt;
int openstat;
- mach_port_t dotdotport; /* dotdot from ROOT through this peropen */
+
struct node *np;
+
+ /* The parent of the translator's root node. */
+ mach_port_t root_parent;
+
+ /* If this node is in a shadow tree, the parent of its root. */
+ mach_port_t shadow_root_parent;
+ /* If in a shadow tree, its root node in this translator. */
+ struct node *shadow_root;
};
/* A unique one of these exists for each node currently in use (and
@@ -64,12 +80,11 @@ struct node
struct disknode *dn;
- struct stat dn_stat;
- int istranslated;
+ io_statbuf_t dn_stat;
/* Stat has been modified if one of the following four fields
is nonzero. Also, if one of the dn_set_?time fields is nonzero,
- the appropriate dn_stat.st_?time field needs to be updated. */
+ the appropriate dn_stat.st_?tim field needs to be updated. */
int dn_set_ctime;
int dn_set_atime;
int dn_set_mtime;
@@ -90,11 +105,17 @@ struct node
struct conch conch;
- struct dirmod *dirmod_reqs;
+ struct modreq *dirmod_reqs;
+ unsigned int dirmod_tick;
- off_t allocsize;
+ struct modreq *filemod_reqs;
+ unsigned int filemod_tick;
- int cache_id;
+ loff_t allocsize;
+
+ ino64_t cache_id;
+
+ int author_tracks_uid;
};
/* Possibly lookup types for diskfs_lookup call */
@@ -106,23 +127,25 @@ enum lookup_type
RENAME,
};
-/* Pending directory modification request */
-struct dirmod
+/* Pending directory and file modification request */
+struct modreq
{
mach_port_t port;
- struct dirmod *next;
+ struct modreq *next;
};
/* Special flag for diskfs_lookup. */
#define SPEC_DOTDOT 0x10000000
+struct argp; /* opaque in this file */
+struct argp_child; /* opaque in this file */
+struct store; /* opaque in this file */
+struct store_parsed; /* opaque in this file */
/* Declarations of variables the library sets. */
extern mach_port_t diskfs_default_pager; /* send right */
-extern mach_port_t diskfs_exec_ctl; /* send right */
-extern mach_port_t diskfs_exec; /* send right */
extern auth_t diskfs_auth_server_port; /* send right */
/* The io_identity identity port for the filesystem. */
@@ -133,10 +156,20 @@ extern mach_port_t diskfs_fsys_identity;
file systems, to give the procserver. */
extern char **diskfs_argv;
-/* When this is a bootstrap filesystem, the command line options passed from
- the kernel. If not a bootstrap filesystem, it is 0, so it can be used to
- distinguish between the two cases. */
-extern char *diskfs_boot_flags;
+/* When this is a bootstrap filesystem, the multiboot kernel command
+ line passed from the kernel. If not a bootstrap filesystem, it is
+ 0. As such, it can be used to distinguish between the two cases.
+ Note: this is only valid after the arguments have been parsed by,
+ for example, diskfs_init_main. */
+extern const char *diskfs_boot_command_line;
+#define diskfs_boot_filesystem() (diskfs_boot_command_line != 0)
+
+/* When this is a bootstrap filesystem, nonzero if starting each bootstrap
+ program should pause for a keystroke, for debugging purposes. */
+extern int _diskfs_boot_pause;
+
+/* Name of the init program run when this is a bootstrap filesystem. */
+extern const char *diskfs_boot_init_program;
/* Hold this lock while do fsys level operations. Innocuous users can just
hold a reader lock, and anyone who's going to do nasty things that would
@@ -155,6 +188,9 @@ extern spin_lock_t diskfs_node_refcnt_lock;
extern int pager_port_type;
+/* Whether the filesystem is currently writable or not. */
+extern int diskfs_readonly;
+
struct pager;
@@ -178,7 +214,7 @@ struct dirstat;
/* The user must define this variable; it should be the size in bytes
of a struct dirstat. */
-extern size_t diskfs_dirstat_size;
+extern const size_t diskfs_dirstat_size;
/* The user must define this variable; it is the maximum number of
links to any one file. The implementation of dir_rename does not know
@@ -186,14 +222,20 @@ extern size_t diskfs_dirstat_size;
reimplement dir_rename yourself. */
extern int diskfs_link_max;
+/* The user must define this variable; it is the maximum length of
+ a single pathname component (i.e. file name within directory).
+ The filesystem code does not use this for anything, but it is
+ returned to user queries for _PC_NAME_MAX. */
+extern int diskfs_name_max;
+
/* The user must define this variable; it is the maximum number of
- symlinks to be traversed within a single call to dir_pathtrans.
- If this is exceeded, dir_pathtrans will return ELOOP. */
+ symlinks to be traversed within a single call to dir_lookup.
+ If this is exceeded, dir_lookup will return ELOOP. */
extern int diskfs_maxsymlinks;
-/* The user must define this variable and set it if the filesystem
- should be readonly. */
-extern int diskfs_readonly;
+/* This variable is defined by diskfs; the user should set it if
+ the filesystem media cannot be made writeable. */
+extern int diskfs_hard_readonly;
/* The user must define this variable. Set this to be the node
of root of the filesystem. */
@@ -203,11 +245,13 @@ extern struct node *diskfs_root_node;
filesystem server. */
extern char *diskfs_server_name;
-/* The user must define these variables. Set these to be the major, minor,
- and edit version numbers. */
-extern int diskfs_major_version;
-extern int diskfs_minor_version;
-extern int diskfs_edit_version;
+/* The user must define this variables. Set this to be the server
+ version number. */
+extern char *diskfs_server_version;
+
+/* The user may define this variable. Set this to be any additional
+ version specification that should be printed for --version. */
+extern char *diskfs_extra_version;
/* The user may define this variable. This should be nonzero iff the
filesystem format supports shortcutting symlink translation.
@@ -239,8 +283,17 @@ int diskfs_shortcut_ifsock;
thread is started up (in diskfs_spawn_first_threa). */
extern int diskfs_default_sync_interval;
+/* The user must define this variable, which should be a string that somehow
+ identifies the particular disk this filesystem is interpreting. It is
+ generally only used to print messages or to distinguish instances of the
+ same filesystem type from one another. If this filesystem accesses no
+ external media, then define this to be 0. */
+extern char *diskfs_disk_name;
+
/* The user must define this function. Set *STATFSBUF with
- appropriate values to reflect the current state of the filesystem. */
+ appropriate values to reflect the current state of the filesystem.
+ The buffer will be initialized to all zeros by the caller;
+ the caller will set f_namelen to diskfs_name_max. */
error_t diskfs_set_statfs (fsys_statfsbuf_t *statfsbuf);
/* The user must define this function. Lookup in directory DP (which
@@ -282,7 +335,8 @@ error_t diskfs_set_statfs (fsys_statfsbuf_t *statfsbuf);
Return EAGAIN if NAME refers to the `..' of this filesystem's root.
Return EIO if appropriate.
*/
-error_t diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type,
+error_t diskfs_lookup_hard (struct node *dp,
+ const char *name, enum lookup_type type,
struct node **np, struct dirstat *ds,
struct protid *cred);
@@ -292,7 +346,7 @@ error_t diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type,
has been locked continuously since that call and DS is as that call
set it, NP is locked. CRED identifies the user responsible
for the call (to be used only to validate directory growth). */
-error_t diskfs_direnter_hard (struct node *dp, char *name,
+error_t diskfs_direnter_hard (struct node *dp, const char *name,
struct node *np, struct dirstat *ds,
struct protid *cred);
@@ -331,7 +385,7 @@ error_t diskfs_drop_dirstat (struct node *dp, struct dirstat *ds);
then there is no limit on *DATACNT; if N is -1, then there is no limit
on AMT. */
error_t diskfs_get_directs (struct node *dp, int entry, int n,
- char **data, u_int *datacnt,
+ char **data, size_t *datacnt,
vm_size_t bufsiz, int *amt);
/* The user must define this function. For locked node NP (for which
@@ -343,7 +397,8 @@ error_t diskfs_get_translator (struct node *np, char **namep, u_int *namelen);
/* The user must define this function. For locked node NP, set
the name of the translating program to be NAME, length NAMELEN. CRED
identifies the user responsible for the call. */
-error_t diskfs_set_translator (struct node *np, char *name, u_int namelen,
+error_t diskfs_set_translator (struct node *np,
+ const char *name, u_int namelen,
struct protid *cred);
/* The user must define this function. Truncate locked node NP to be SIZE
@@ -351,20 +406,20 @@ error_t diskfs_set_translator (struct node *np, char *name, u_int namelen,
long, do nothing.) If this is a symlink (and diskfs_shortcut_symlink
is set) then this should clear the symlink, even if
diskfs_create_symlink_hook stores the link target elsewhere. */
-error_t diskfs_truncate (struct node *np, off_t size);
+error_t diskfs_truncate (struct node *np, loff_t size);
/* The user must define this function. Grow the disk allocated to locked node
NP to be at least SIZE bytes, and set NP->allocsize to the actual
allocated size. (If the allocated size is already SIZE bytes, do
nothing.) CRED identifies the user responsible for the call. */
-error_t diskfs_grow (struct node *np, off_t size, struct protid *cred);
+error_t diskfs_grow (struct node *np, loff_t size, struct protid *cred);
/* The user must define this function. Write to disk (synchronously
iff WAIT is nonzero) from format-specific buffers any non-paged
metadata. If CLEAN is nonzero, then after this is written the
filesystem will be absolutely clean, and the non-paged metadata can
so indicate. */
-void diskfs_set_hypermetadata (int wait, int clean);
+error_t diskfs_set_hypermetadata (int wait, int clean);
/* The user must define this function. Allocate a new node to be of
mode MODE in locked directory DP (don't actually set the mode or
@@ -462,7 +517,7 @@ void diskfs_shutdown_pager ();
/* The user must define this function. Return a memory object port (send
right) for the file contents of NP. PROT is the maximum allowable
- access. */
+ access. On errors, return MACH_PORT_NULL and set errno. */
mach_port_t diskfs_get_filemap (struct node *np, vm_prot_t prot);
/* The user must define this function. Return true if there are pager
@@ -502,7 +557,7 @@ error_t diskfs_node_reload (struct node *node);
is called to set a symlink. If it returns EINVAL or isn't set,
then the normal method (writing the contents into the file data) is
used. If it returns any other error, it is returned to the user. */
-error_t (*diskfs_create_symlink_hook)(struct node *np, char *target);
+error_t (*diskfs_create_symlink_hook)(struct node *np, const char *target);
/* If this function is nonzero (and diskfs_shortcut_symlink is set) it
is called to read the contents of a symlink. If it returns EINVAL or
@@ -512,33 +567,6 @@ error_t (*diskfs_read_symlink_hook)(struct node *np, char *target);
/* The library exports the following functions for general use */
-/* Returns the name and a send right for the mach device on which the file
- NAME is stored, and returns it in DEV_NAME (which is malloced) and PORT.
- Other values returned are START, the first valid offset, SIZE, the the
- number of blocks after START, and BLOCK_SIZE, the units in which the
- device is addressed.
-
- The device is opened for reading, and if the diskfs global variable
- DISKFS_READONLY is false, writing. */
-error_t diskfs_get_file_device (char *name,
- char **dev_name, mach_port_t *port,
- off_t *start, off_t *size, size_t *block_size);
-
-/* Returns a send right to for the mach device called NAME, and returns it in
- PORT. Other values returned are START, the first valid offset, SIZE, the
- the number of blocks after START, and BLOCK_SIZE, the units in which the
- device is addressed.
-
- The device is opened for reading, and if the diskfs global variable
- DISKFS_READ_ONLY is false, writing.
-
- If NAME cannot be opened and this is a bootstrap filesystem, the user will
- be prompted for new names until a valid one is found. */
-error_t diskfs_get_mach_device (char *name,
- mach_port_t *port,
- off_t *start, off_t *size, size_t *block_size);
-
-
/* Call this after arguments have been parsed to initialize the library.
You must call this before calling any other diskfs functions, and after
parsing diskfs options. */
@@ -553,8 +581,9 @@ mach_port_t diskfs_startup_diskfs (mach_port_t bootstrap, int flags);
/* Call this after all format-specific initialization is done (except
for setting diskfs_root_node); at this point the pagers should be
- ready to go. */
-void diskfs_spawn_first_thread (void);
+ ready to go. DEMUXER is the demuxer to user. Normally, this is
+ just diskfs_demuxer. */
+void diskfs_spawn_first_thread (ports_demuxer_type demuxer);
/* Once diskfs_root_node is set, call this if we are a bootstrap
filesystem. If you call this, then the library will call
@@ -574,240 +603,30 @@ void diskfs_node_update (struct node *np, int wait);
/* Add a hard reference to a node. If there were no hard
references previously, then the node cannot be locked
(because you must hold a hard reference to hold the lock). */
-extern inline void
-diskfs_nref (struct node *np)
-{
- int new_hardref;
- spin_lock (&diskfs_node_refcnt_lock);
- np->references++;
- new_hardref = (np->references == 1);
- spin_unlock (&diskfs_node_refcnt_lock);
- if (new_hardref)
- {
- mutex_lock (&np->lock);
- diskfs_new_hardrefs (np);
- mutex_unlock (&np->lock);
- }
-}
+void diskfs_nref (struct node *np);
/* Unlock node NP and release a hard reference; if this is the last
hard reference and there are no links to the file then request
soft references to be dropped. */
-extern inline void
-diskfs_nput (struct node *np)
-{
- int tried_drop_softrefs = 0;
-
- loop:
- spin_lock (&diskfs_node_refcnt_lock);
- assert (np->references);
- np->references--;
- if (np->references + np->light_references == 0)
- diskfs_drop_node (np);
- else if (np->references == 0 && !tried_drop_softrefs)
- {
- spin_unlock (&diskfs_node_refcnt_lock);
- diskfs_lost_hardrefs (np);
- if (!np->dn_stat.st_nlink)
- {
- /* There are no links. If there are soft references that
- can be dropped, we can't let them postpone deallocation.
- So attempt to drop them. But that's a user-supplied
- routine, which might result in further recursive calls to
- the ref-counting system. So we have to reacquire our
- reference around the call to forestall disaster. */
- spin_lock (&diskfs_node_refcnt_lock);
- np->references++;
- spin_unlock (&diskfs_node_refcnt_lock);
-
- diskfs_try_dropping_softrefs (np);
-
- /* But there's no value in looping forever in this
- routine; only try to drop soft refs once. */
- tried_drop_softrefs = 1;
-
- /* Now we can drop the reference back... */
- goto loop;
- }
- mutex_unlock (&np->lock);
- }
- else
- {
- spin_unlock (&diskfs_node_refcnt_lock);
- mutex_unlock (&np->lock);
- }
-}
+void diskfs_nput (struct node *np);
/* Release a hard reference on NP. If NP is locked by anyone, then
this cannot be the last hard reference (because you must hold a
hard reference in order to hold the lock). If this is the last
hard reference and there are no links, then request soft references
to be dropped. */
-extern inline void
-diskfs_nrele (struct node *np)
-{
- int tried_drop_softrefs = 0;
-
- loop:
- spin_lock (&diskfs_node_refcnt_lock);
- assert (np->references);
- np->references--;
- if (np->references + np->light_references == 0)
- {
- mutex_lock (&np->lock);
- diskfs_drop_node (np);
- }
- else if (np->references == 0)
- {
- mutex_lock (&np->lock);
- spin_unlock (&diskfs_node_refcnt_lock);
- diskfs_lost_hardrefs (np);
- if (!np->dn_stat.st_nlink && !tried_drop_softrefs)
- {
- /* Same issue here as in nput; see that for explanation */
- spin_lock (&diskfs_node_refcnt_lock);
- np->references++;
- spin_unlock (&diskfs_node_refcnt_lock);
-
- diskfs_try_dropping_softrefs (np);
- tried_drop_softrefs = 1;
-
- /* Now we can drop the reference back... */
- mutex_unlock (&np->lock);
- goto loop;
- }
- mutex_unlock (&np->lock);
- }
- else
- spin_unlock (&diskfs_node_refcnt_lock);
-}
+void diskfs_nrele (struct node *np);
/* Add a light reference to a node. */
-extern inline void
-diskfs_nref_light (struct node *np)
-{
- spin_lock (&diskfs_node_refcnt_lock);
- np->light_references++;
- spin_unlock (&diskfs_node_refcnt_lock);
-}
+void diskfs_nref_light (struct node *np);
/* Unlock node NP and release a light reference */
-extern inline void
-diskfs_nput_light (struct node *np)
-{
- spin_lock (&diskfs_node_refcnt_lock);
- assert (np->light_references);
- np->light_references--;
- if (np->references + np->light_references == 0)
- diskfs_drop_node (np);
- else
- {
- spin_unlock (&diskfs_node_refcnt_lock);
- mutex_unlock (&np->lock);
- }
-}
+void diskfs_nput_light (struct node *np);
/* Release a light reference on NP. If NP is locked by anyone, then
this cannot be the last reference (because you must hold a
hard reference in order to hold the lock). */
-extern inline void
-diskfs_nrele_light (struct node *np)
-{
- spin_lock (&diskfs_node_refcnt_lock);
- assert (np->light_references);
- np->light_references--;
- if (np->references + np->light_references == 0)
- {
- mutex_lock (&np->lock);
- diskfs_drop_node (np);
- }
- else
- spin_unlock (&diskfs_node_refcnt_lock);
-}
-
-/* Return nonzero iff the user identified by CRED has uid UID. */
-extern inline int
-diskfs_isuid (uid_t uid, struct protid *cred)
-{
- int i;
- for (i = 0; i < cred->nuids; i++)
- if (cred->uids[i] == uid)
- return 1;
- return 0;
-}
-
-/* Return nonzero iff the user identified by CRED has group GRP. */
-extern inline int
-diskfs_groupmember (uid_t grp, struct protid *cred)
-{
- int i;
- for (i = 0; i < cred->ngids; i++)
- if (cred->gids[i] == grp)
- return 1;
- return 0;
-}
-
-/* Check to see if the user identified by CRED is permitted to do
- owner-only operations on node NP; if so, return 0; if not, return
- EPERM. */
-extern inline error_t
-diskfs_isowner (struct node *np, struct protid *cred)
-{
- /* Permitted if the user is the owner, superuser, or if the user
- is in the group of the file and has the group ID as their user
- ID. (This last is colloquially known as `group leader'.) */
- if (diskfs_isuid (np->dn_stat.st_uid, cred) || diskfs_isuid (0, cred)
- || (diskfs_groupmember (np->dn_stat.st_gid, cred)
- && diskfs_isuid (np->dn_stat.st_gid, cred)))
- return 0;
- else
- return EPERM;
-}
-
-/* Check to see is the user identified by CRED is permitted to do
- operation OP on node NP. Op is one of S_IREAD, S_IWRITE, or S_IEXEC.
- Return 0 if the operation is permitted and EACCES if not. */
-extern inline error_t
-diskfs_access (struct node *np, int op, struct protid *cred)
-{
- int gotit;
- if (diskfs_isuid (0, cred))
- gotit = 1;
- else if (cred->nuids == 0 && (np->dn_stat.st_mode & S_IUSEUNK))
- gotit = np->dn_stat.st_mode & (op << S_IUNKSHIFT);
- else if (!diskfs_isowner (np, cred))
- gotit = np->dn_stat.st_mode & op;
- else if (diskfs_groupmember (np->dn_stat.st_gid, cred))
- gotit = np->dn_stat.st_mode & (op >> 3);
- else
- gotit = np->dn_stat.st_mode & (op >> 6);
- return gotit ? 0 : EACCES;
-}
-
-/* Check to see if the user identified by CRED is allowed to modify
- directory DP with respect to existing file NP. This is the same
- as diskfs_access (dp, S_IWRITE, cred), except when the directory
- has the sticky bit set. (If there is no existing file NP, then
- 0 can be passed.) */
-extern inline error_t
-diskfs_checkdirmod (struct node *dp, struct node *np,
- struct protid *cred)
-{
- error_t err;
-
- /* The user must be able to write the directory, but if the directory
- is sticky, then the user must also be either the owner of the directory
- or the file. */
- err = diskfs_access (dp, S_IWRITE, cred);
- if (err)
- return err;
-
- if ((dp->dn_stat.st_mode & S_ISVTX) && np && !diskfs_isuid (0, cred)
- && diskfs_isowner (dp, cred) && diskfs_isowner (np, cred))
- return EACCES;
-
- return 0;
-}
+void diskfs_nrele_light (struct node *np);
/* Reading and writing of files. this is called by other filesystem
routines and handles extension of files automatically. NP is the
@@ -819,7 +638,7 @@ diskfs_checkdirmod (struct node *dp, struct node *np,
extension). For reads, *AMTREAD is filled with the amount actually
read. */
error_t
-diskfs_node_rdwr (struct node *np, char *data, off_t off,
+diskfs_node_rdwr (struct node *np, char *data, loff_t off,
size_t amt, int dir, struct protid *cred,
size_t *amtread);
@@ -832,7 +651,15 @@ diskfs_node_rdwr (struct node *np, char *data, off_t off,
fully completed. */
void
diskfs_notice_dirchange (struct node *dp, enum dir_changed_type type,
- char *name);
+ const char *name);
+
+/* Send notifications to users who have requested them with
+ file_notice_changes for file NP. The type of modification is TYPE.
+ START and END identify the affected region of the file's data.
+ This should be called after the change is fully completed. */
+void
+diskfs_notice_filechange (struct node *np, enum file_changed_type type,
+ loff_t start, loff_t end);
/* Create a new node structure with DS as its physical disknode.
The new node will have one hard reference and no light references. */
@@ -846,6 +673,11 @@ struct node *diskfs_make_node (struct disknode *dn);
either be LOOKUP, CREATE, RENAME, or REMOVE. CRED identifies the
user making the call.
+ NAME will have leading and trailing slashes stripped. It is an
+ error if there are internal slashes. NAME will be modified in
+ place if there are slashes in it; it is therefore an error to
+ specify a constant NAME which contains slashes.
+
If the name is found, return zero, and (if NP is nonzero) set *NP
to point to the node for it, locked. If the name is not found,
return ENOENT, and (if NP is nonzero) set *NP to zero. If NP is
@@ -884,10 +716,11 @@ struct node *diskfs_make_node (struct disknode *dn);
Return ENOENT if NAME isn't in the directory.
Return EAGAIN if NAME refers to the `..' of this filesystem's root.
Return EIO if appropriate.
-
- This function is a wrapper for diskfs_lookup_hard.
+
+ This function is a wrapper for diskfs_lookup_hard.
*/
-error_t diskfs_lookup (struct node *dp, char *name, enum lookup_type type,
+error_t diskfs_lookup (struct node *dp,
+ const char *name, enum lookup_type type,
struct node **np, struct dirstat *ds,
struct protid *cred);
@@ -898,7 +731,7 @@ error_t diskfs_lookup (struct node *dp, char *name, enum lookup_type type,
responsible for the call (to be used only to validate directory
growth). This function is a wrapper for diskfs_direnter_hard. */
error_t
-diskfs_direnter (struct node *dp, char *name, struct node *np,
+diskfs_direnter (struct node *dp, const char *name, struct node *np,
struct dirstat *ds, struct protid *cred);
/* This will only be called after a successful call to diskfs_lookup
@@ -910,7 +743,8 @@ diskfs_direnter (struct node *dp, char *name, struct node *np,
name of OLDNP inside DP; it is this reference which is being
rewritten. This function is a wrapper for diskfs_dirrewrite_hard. */
error_t diskfs_dirrewrite (struct node *dp, struct node *oldnp,
- struct node *np, char *name, struct dirstat *ds);
+ struct node *np, const char *name,
+ struct dirstat *ds);
/* This will only be called after a successful call to diskfs_lookup
of type REMOVE; this call should remove the name found from the
@@ -920,10 +754,10 @@ error_t diskfs_dirrewrite (struct node *dp, struct node *oldnp,
function is a wrapper for diskfs_dirremove_hard. The entry being
removed has name NAME and refers to NP. */
error_t diskfs_dirremove (struct node *dp, struct node *np,
- char *name, struct dirstat *ds);
+ const char *name, struct dirstat *ds);
/* Return the node corresponding to CACHE_ID in *NPP. */
-error_t diskfs_cached_lookup (int cache_id, struct node **npp);
+error_t diskfs_cached_lookup (ino64_t cache_id, struct node **npp);
/* Create a new node. Give it MODE; if that includes IFDIR, also
initialize `.' and `..' in the new directory. Return the node in NPP.
@@ -933,29 +767,49 @@ error_t diskfs_cached_lookup (int cache_id, struct node **npp);
DIR must always be provided as at least a hint for disk allocation
strategies. */
error_t
-diskfs_create_node (struct node *dir, char *name, mode_t mode,
+diskfs_create_node (struct node *dir, const char *name, mode_t mode,
struct node **newnode, struct protid *cred,
struct dirstat *ds);
-/* Create and return a protid for an existing peropen PO in CRED. The uid
- set is UID (length NUIDS); the gid set is GID (length NGIDS). The node
- PO->np must be locked. */
-error_t diskfs_create_protid (struct peropen *po, uid_t *uids, int nuids,
- uid_t *gids, int ngids, struct protid **cred);
+/* Create and return a protid for an existing peropen PO in CRED,
+ referring to user USER. The node PO->np must be locked. */
+error_t diskfs_create_protid (struct peropen *po, struct iouser *user,
+ struct protid **cred);
/* Build and return in CRED a protid which has no user identification, for
peropen PO. The node PO->np must be locked. */
error_t diskfs_start_protid (struct peropen *po, struct protid **cred);
/* Finish building protid CRED started with diskfs_start_protid;
- the uid set is UID (length NUIDS); the gid set is GID (length NGIDS). */
-void diskfs_finish_protid (struct protid *cred, uid_t *uids, int nuids,
- gid_t *gids, int nguds);
+ the user to install is USER. */
+void diskfs_finish_protid (struct protid *cred, struct iouser *user);
-/* Create and return a new peropen structure on node NP with open
- flags FLAGS. */
-struct peropen *diskfs_make_peropen (struct node *np, int flags,
- mach_port_t dotdotnode);
+extern struct protid * diskfs_begin_using_protid_port (file_t port);
+
+extern void diskfs_end_using_protid_port (struct protid *cred);
+
+#if defined(__USE_EXTERN_INLINES) || defined(DISKFS_DEFINE_EXTERN_INLINE)
+
+/* Called by MiG to translate ports into struct protid *.
+ fsmutations.h arranges for this to happen for the io and
+ fs interfaces. */
+DISKFS_EXTERN_INLINE struct protid *
+diskfs_begin_using_protid_port (file_t port)
+{
+ return ports_lookup_port (diskfs_port_bucket, port, diskfs_protid_class);
+}
+
+/* Called by MiG after server routines have been run; this
+ balances begin_using_protid_port, and is arranged for the io
+ and fs interfaces by fsmutations.h. */
+DISKFS_EXTERN_INLINE void
+diskfs_end_using_protid_port (struct protid *cred)
+{
+ if (cred)
+ ports_port_deref (cred);
+}
+
+#endif /* Use extern inlines. */
/* Called when a protid CRED has no more references. (Because references\
to protids are maintained by the port management library, this is
@@ -963,14 +817,23 @@ struct peropen *diskfs_make_peropen (struct node *np, int flags,
free the structure for us. */
void diskfs_protid_rele (void *arg);
+/* Create a new peropen structure on node NP with open flags FLAGS in
+ *PPO. The initial values for the root_parent, shadow_root, and
+ shadow_root_parent fields are copied from CONTEXT if it's non-zero,
+ otherwise they are zeroed. */
+error_t
+diskfs_make_peropen (struct node *np, int flags,
+ struct peropen *context, struct peropen **ppo);
+
/* Decrement the reference count on a peropen structure. */
void diskfs_release_peropen (struct peropen *po);
/* Node NP has just been found in DIR with NAME. If NP is null, that
means that this name has been confirmed as absent in the directory. */
-void diskfs_enter_lookup_cache (struct node *dir, struct node *np, char *name);
+void diskfs_enter_lookup_cache (struct node *dir, struct node *np,
+ const char *name);
-/* Purge all references in the cache to NP as a node inside
+/* Purge all references in the cache to NP as a node inside
directory DP. */
void diskfs_purge_lookup_cache (struct node *dp, struct node *np);
@@ -978,7 +841,7 @@ void diskfs_purge_lookup_cache (struct node *dp, struct node *np);
anything entry at all, then return 0. If the entry is confirmed to
not exist, then return -1. Otherwise, return NP for the entry, with
a newly allocated reference. */
-struct node *diskfs_check_lookup_cache (struct node *dir, char *name);
+struct node *diskfs_check_lookup_cache (struct node *dir, const char *name);
/* Rename directory node FNP (whose parent is FDP, and which has name
FROMNAME in that directory) to have name TONAME inside directory
@@ -991,9 +854,9 @@ struct node *diskfs_check_lookup_cache (struct node *dir, char *name);
if that is not true for your format, you have to redefine this
function.*/
error_t
-diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname,
- struct node *tdp, char *toname, struct protid *fromcred,
- struct protid *tocred);
+diskfs_rename_dir (struct node *fdp, struct node *fnp, const char *fromname,
+ struct node *tdp, const char *toname,
+ struct protid *fromcred, struct protid *tocred);
/* Clear the `.' and `..' entries from directory DP. Its parent is
PDP, and the user responsible for this is identified by CRED. Both
@@ -1014,11 +877,15 @@ error_t diskfs_clear_directory (struct node *dp, struct node *pdp,
error_t
diskfs_init_dir (struct node *dp, struct node *pdp, struct protid *cred);
-/* If NP->dn_set_ctime is set, then modify NP->dn_stat.st_ctime
+/* If disk is not readonly and the noatime option is not enabled, set
+ NP->dn_set_atime. */
+void diskfs_set_node_atime (struct node *np);
+
+/* If NP->dn_set_ctime is set, then modify NP->dn_stat.st_ctim
appropriately; do the analogous operation for atime and mtime as well. */
void diskfs_set_node_times (struct node *np);
-/* Shutdown the filesystem; flags are as for fsys_shutdown. */
+/* Shutdown the filesystem; flags are as for fsys_goaway. */
error_t diskfs_shutdown (int flags);
/* Change an active filesystem between read-only and writable modes, setting
@@ -1049,14 +916,12 @@ error_t diskfs_set_sync_interval (int interval);
/* Parse and execute the runtime options in ARGZ & ARGZ_LEN. EINVAL is
returned if some option is unrecognized. The default definition of this
routine will parse them using DISKFS_RUNTIME_ARGP, which see. */
-error_t diskfs_set_options (char *argz, size_t argz_len);
+error_t diskfs_set_options (const char *argz, size_t argz_len);
-/* Return an argz string describing the current options. Fill *ARGZ
- with a pointer to newly malloced storage holding the list and *LEN
- to the length of that storage. The default definition of this routine
- simply initializes *ARGZ and *ARGZ_LEN to 0 and calls
- diskfs_append_std_options. */
-error_t diskfs_get_options (char **argz, unsigned *argz_len);
+/* Append to the malloced string *ARGZ of length *ARGZ_LEN a NUL-separated
+ list of the arguments to this translator. The default definition of this
+ routine simply calls diskfs_append_std_options. */
+error_t diskfs_append_args (char **argz, size_t *argz_len);
/* If this is defined or set to an argp structure, it will be used by the
default diskfs_set_options to handle runtime option parsing. The default
@@ -1071,12 +936,19 @@ extern const struct argp diskfs_std_runtime_argp;
/* An argp structure for the standard diskfs command line arguments. The
user may call argp_parse on this to parse the command line, chain it onto
the end of his own argp structure, or ignore it completely. */
-extern const struct argp diskfs_std_startup_argp;
+extern const struct argp diskfs_startup_argp;
+
+/* An argp structure for the standard diskfs command line arguments plus a
+ store specification. The address of a location in which to return the
+ resulting struct store_parsed structure should be passed as the input
+ argument to argp_parse; see the declaration for STORE_ARGP in
+ <hurd/store.h> for more information. */
+extern const struct argp diskfs_store_startup_argp;
/* *Appends* to ARGZ & ARGZ_LEN '\0'-separated options describing the standard
diskfs option state (note that unlike diskfs_get_options, ARGZ & ARGZ_LEN
must already have a sane value). */
-error_t diskfs_append_std_options (char **argz, unsigned *argz_len);
+error_t diskfs_append_std_options (char **argz, size_t *argz_len);
/* Demultiplex incoming messages on ports created by libdiskfs. */
int diskfs_demuxer (mach_msg_header_t *, mach_msg_header_t *);
@@ -1089,67 +961,33 @@ int diskfs_check_readonly (void);
fsys, interrupt, and notify interfaces. All the server routines
have the prefix `diskfs_S_'; `in' arguments of type file_t or io_t
appear as `struct protid *' to the stub. */
+
+
+/* All-in-one initialization function for diskfs filesystems using
+ libstore. This parses arguments using STARTUP_ARGP (defaulting to
+ diskfs_store_startup_argp if it's null; note that the ARGP_IN_ORDER
+ flag is always used); it calls diskfs_init_diskfs; it opens the
+ store with store_parsed_open, and sets diskfs_hard_readonly and
+ diskfs_readonly if the store is unwritable; it calls
+ diskfs_spawn_first_thread; finally, it returns the store and its
+ description in *STORE and *STORE_PARSED, and the bootstrap port in
+ *BOOTSTRAP. The caller should pass *BOOTSTRAP to
+ diskfs_startup_diskfs after setting diskfs_root_node.
+ (See <argp.h> and <hurd/store.h>.)
+
+ This call cannot return failure; if it encounters a fatal problem,
+ it prints a diagnostic on stderr (or the console) and exits the
+ program. */
+struct store *diskfs_init_main (struct argp *startup_argp,
+ int argc, char **argv,
+ struct store_parsed **store_parsed,
+ mach_port_t *bootstrap);
/* The following are optional convenience routines and global variable, which
can be used by any user program that uses a mach device to hold the
underlying filesystem. */
-/* A pointer to an argp structure for the standard diskfs command line
- arguments, that also parses a device argument. The user may call
- argp_parse on this to parse the command line, chain it onto the end of his
- own argp structure, or ignore it completely. */
-extern const struct argp diskfs_std_device_startup_argp;
-
-/* The following two are set by the preceding argument parser: */
-/* The device specifier given on the command line. */
-extern char *diskfs_device_arg;
-/* True if --machdev was specified, meaning that DISKFS_DEVICE_ARG names a
- mach device and not a filesystem device node. */
-extern int diskfs_use_mach_device;
-
-/* Uses the values of DISKFS_DEVICE_ARG and DISKFS_USE_MACH_DEVICE, and
- attempts to open the device and set the values of DISKFS_DEVICE,
- DISKFS_DEVICE_NAME, DISKFS_DEVICE_START, DISKFS_DEVICE_SIZE, and
- DISKFS_DEVICE_BLOCK_SIZE. */
-extern error_t diskfs_device_open ();
-
-/* A mach device port for the device we're using. */
-extern mach_port_t diskfs_device;
-
-/* The mach device name of DISKFS_DEVICE. May be 0 if unknown. */
-extern char *diskfs_device_name;
-
-/* The first valid block of DISKFS_DEVICE, in units of
- DISKFS_DEVICE_BLOCK_SIZE. */
-extern off_t diskfs_device_start;
-
-/* The usable size of DISKFS_DEVICE, in units of DISKFS_DEVICE_BLOCK_SIZE. */
-extern off_t diskfs_device_size;
-
-/* The unit of addressing for DISKFS_DEVICE. */
-extern unsigned diskfs_device_block_size;
-
-/* Some handy calculations based on DISKFS_DEVICE_BLOCK_SIZE. */
-/* Log base 2 of DEVICE_BLOCK_SIZE, or 0 if it's not a power of two. */
-extern unsigned diskfs_log2_device_block_size;
-/* Log base 2 of the number of device blocks in a vm page. This number is
- only valid if DISKFS_LOG2_DEVICE_BLOCK_SIZE is not 0. */
-extern unsigned diskfs_log2_device_blocks_per_page;
-
-/* Write disk block ADDR with DATA of LEN bytes to DISKFS_DEVICE, waiting for
- completion. ADDR is offset by DISKFS_DEVICE_START. If an error occurs,
- EIO is returned. */
-error_t diskfs_device_write_sync (off_t addr, vm_address_t data, size_t len);
-
-/* Read disk block ADDR from DISKFS_DEVICE; put the address of the data in
- DATA; read LEN bytes. Always *DATA should be a full page no matter what.
- ADDR is offset by DISKFS_DEVICE_START. If an error occurs, EIO is
- returned. */
-error_t diskfs_device_read_sync (off_t addr, vm_address_t *data, size_t len);
-
/* Make errors go somewhere reasonable. */
void diskfs_console_stdio ();
-
#endif /* hurd/diskfs.h */
-
diff --git a/libdiskfs/ports-consts.c b/libdiskfs/extern-inline.c
index c2726c4c..43de88d6 100644
--- a/libdiskfs/ports-consts.c
+++ b/libdiskfs/extern-inline.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994 Free Software Foundation
+/* Run time callable functions for extern inlines.
+ Copyright (C) 2001 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
@@ -15,6 +15,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define DISKFS_DEFINE_EXTERN_INLINE
-/* ports_wire_threads is set in init-init.c. */
-int ports_wire_cthreads = 1;
+#include "diskfs.h"
diff --git a/libdiskfs/ports-noports.c b/libdiskfs/extra-version.c
index cddd8f00..b1d78084 100644
--- a/libdiskfs/ports-noports.c
+++ b/libdiskfs/extra-version.c
@@ -1,27 +1,24 @@
-/*
- Copyright (C) 1994 Free Software Foundation
+/* Default value for diskfs_extra_version
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, n/BSG.
- This program is free software; you can redistribute it and/or
+ 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.
- This program is distributed in the hope that it will be useful, but
+ 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. */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include "priv.h"
-/* Called by ports library when there are no ports outstanding. */
-void
-ports_no_live_ports ()
-{
- diskfs_sync_everything (1);
- exit (0);
-}
+char *diskfs_extra_version = "";
diff --git a/libdiskfs/fhandle.h b/libdiskfs/fhandle.h
new file mode 100644
index 00000000..bd827d84
--- /dev/null
+++ b/libdiskfs/fhandle.h
@@ -0,0 +1,36 @@
+/* File handle type (for nfs server support)
+
+ Copyright (C) 1997,99 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. */
+
+#ifndef __FHANDLE_H__
+#define __FHANDLE_H__
+
+/* Must be exactly 28 bytes long */
+union diskfs_fhandle
+{
+ unsigned char bytes[28];
+ struct
+ {
+ int pad1;
+ int cache_id;
+ unsigned int gen;
+ } data;
+};
+
+#endif /* __FHANDLE_H__ */
diff --git a/libdiskfs/file-access.c b/libdiskfs/file-access.c
index 7553ffda..4a5eb17d 100644
--- a/libdiskfs/file-access.c
+++ b/libdiskfs/file-access.c
@@ -31,11 +31,11 @@ diskfs_S_file_check_access (struct protid *cred,
np = cred->po->np;
mutex_lock (&np->lock);
*type = 0;
- if (diskfs_access (np, S_IREAD, cred) == 0)
+ if (fshelp_access (&np->dn_stat, S_IREAD, cred->user) == 0)
*type |= O_READ;
- if (diskfs_access (np, S_IWRITE, cred) == 0)
+ if (fshelp_access (&np->dn_stat, S_IWRITE, cred->user) == 0)
*type |= O_WRITE;
- if (diskfs_access (np, S_IEXEC, cred) == 0)
+ if (fshelp_access (&np->dn_stat, S_IEXEC, cred->user) == 0)
*type |= O_EXEC;
mutex_unlock (&np->lock);
diff --git a/libdiskfs/file-chauthor.c b/libdiskfs/file-chauthor.c
index 25f4c4ec..6e49c53f 100644
--- a/libdiskfs/file-chauthor.c
+++ b/libdiskfs/file-chauthor.c
@@ -27,13 +27,16 @@ dithkfth_TH_file_chauthor (struct protid *cred,
{
CHANGE_NODE_FIELD (cred,
({
- err = dithkfth_ithowner (np, cred);
+ err = fthhelp_ithowner (&np->dn_thtat, cred->uther);
if (!err)
err = dithkfth_validate_author_change (np, author);
if (!err)
{
np->dn_thtat.tht_author = author;
np->dn_thet_theetime = 1;
+ if (np->filemod_reqs)
+ diskfs_notice_filechange(np, FILE_CHANGED_META,
+ 0, 0);
}
}));
}
diff --git a/libdiskfs/file-chflags.c b/libdiskfs/file-chflags.c
index e1403f25..01dc495c 100644
--- a/libdiskfs/file-chflags.c
+++ b/libdiskfs/file-chflags.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs:file_chflags
- Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation
+ Copyright (C) 1992, 1993, 1994, 1996, 1998 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
@@ -25,10 +25,16 @@ diskfs_S_file_chflags (struct protid *cred,
{
CHANGE_NODE_FIELD (cred,
({
- err = diskfs_isowner (np, cred);
+ err = fshelp_isowner (&np->dn_stat, cred->user);
if (!err)
err = diskfs_validate_flags_change (np, flags);
if (!err)
- np->dn_stat.st_flags = flags;
+ {
+ np->dn_stat.st_flags = flags;
+ np->dn_set_ctime = 1;
+ }
+ if (!err && np->filemod_reqs)
+ diskfs_notice_filechange(np, FILE_CHANGED_META,
+ 0, 0);
}));
}
diff --git a/libdiskfs/file-chg.c b/libdiskfs/file-chg.c
index 27d932e6..22edc69c 100644
--- a/libdiskfs/file-chg.c
+++ b/libdiskfs/file-chg.c
@@ -17,11 +17,55 @@
#include "priv.h"
#include "fs_S.h"
+#include "fs_notify_U.h"
kern_return_t
-diskfs_S_file_notice_changes (struct protid *cred __attribute__ ((unused)),
- mach_port_t notify __attribute__ ((unused)))
+diskfs_S_file_notice_changes (struct protid *cred, mach_port_t notify)
{
- return EOPNOTSUPP;
+ error_t err;
+ struct modreq *req;
+ struct node *np;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ np = cred->po->np;
+ mutex_lock (&np->lock);
+ err = file_changed (notify, np->filemod_tick, FILE_CHANGED_NULL, 0, 0);
+ if (err)
+ {
+ mutex_unlock (&np->lock);
+ return err;
+ }
+ req = malloc (sizeof (struct modreq));
+ req->port = notify;
+ req->next = np->filemod_reqs;
+ np->filemod_reqs = req;
+ mutex_unlock (&np->lock);
+ return 0;
}
+void
+diskfs_notice_filechange (struct node *dp, enum file_changed_type type,
+ off_t start, off_t end)
+{
+ error_t err;
+ struct modreq **preq;
+
+ dp->filemod_tick++;
+ preq = &dp->filemod_reqs;
+ while (*preq)
+ {
+ struct modreq *req = *preq;
+ err = file_changed (req->port, dp->filemod_tick, type, start, end);
+ if (err && err != MACH_SEND_TIMED_OUT)
+ {
+ /* Remove notify port. */
+ *preq = req->next;
+ mach_port_deallocate (mach_task_self (), req->port);
+ free (req);
+ }
+ else
+ preq = &req->next;
+ }
+}
diff --git a/libdiskfs/file-chmod.c b/libdiskfs/file-chmod.c
index 545b810f..5dad2c78 100644
--- a/libdiskfs/file-chmod.c
+++ b/libdiskfs/file-chmod.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_chmod
- Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,96,97,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
@@ -22,29 +22,35 @@ error_t
diskfs_S_file_chmod (struct protid *cred,
mode_t mode)
{
- mode &= ~(S_IFMT | S_ISPARE);
-
+ mode &= ~(S_IFMT | S_ISPARE | S_ITRANS);
+
CHANGE_NODE_FIELD (cred,
- ({
- if (!(err = diskfs_isowner (np, cred)))
- {
- if (!diskfs_isuid (0, cred))
- {
- if (!S_ISDIR (np->dn_stat.st_mode))
- mode &= ~S_ISVTX;
- if (!diskfs_groupmember (np->dn_stat.st_gid,
- cred))
- mode &= ~S_ISGID;
- if (!diskfs_isuid (np->dn_stat.st_uid, cred))
- mode &= ~S_ISUID;
- }
- mode |= (np->dn_stat.st_mode & (S_IFMT | S_ISPARE));
- err = diskfs_validate_mode_change (np, mode);
- if (!err)
- {
- np->dn_stat.st_mode = mode;
- np->dn_set_ctime = 1;
- }
- }
- }));
+ ({
+ if (!(err = fshelp_isowner (&np->dn_stat, cred->user)))
+ {
+ if (!idvec_contains (cred->user->uids, 0))
+ {
+ if (!S_ISDIR (np->dn_stat.st_mode))
+ mode &= ~S_ISVTX;
+ if (!idvec_contains (cred->user->gids,
+ np->dn_stat.st_gid))
+ mode &= ~S_ISGID;
+ if (!idvec_contains (cred->user->uids,
+ np->dn_stat.st_uid))
+ mode &= ~S_ISUID;
+ }
+ mode |= (np->dn_stat.st_mode
+ & (S_IFMT | S_ISPARE | S_ITRANS));
+ err = diskfs_validate_mode_change (np, mode);
+ if (!err)
+ {
+ np->dn_stat.st_mode = mode;
+ np->dn_set_ctime = 1;
+ if (np->filemod_reqs)
+ diskfs_notice_filechange (np,
+ FILE_CHANGED_META,
+ 0, 0);
+ }
+ }
+ }));
}
diff --git a/libdiskfs/file-chown.c b/libdiskfs/file-chown.c
index a0c4f225..ecb851f2 100644
--- a/libdiskfs/file-chown.c
+++ b/libdiskfs/file-chown.c
@@ -1,5 +1,5 @@
/* libdiskfs implementetation of fs.defs: file_chown
- Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation
+ Copyright (C) 1992, 1993, 1994, 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
@@ -24,24 +24,40 @@ diskfs_S_file_chown (struct protid *cred,
uid_t uid,
gid_t gid)
{
+ if (uid == (uid_t) -1 && gid == (gid_t) -1) /* No change requested. */
+ return 0;
+
CHANGE_NODE_FIELD (cred,
({
- err = diskfs_isowner (np, cred);
+ err = fshelp_isowner (&np->dn_stat, cred->user);
if (err
- || ((!diskfs_isuid (uid, cred)
- || !diskfs_groupmember (gid, cred))
- && !diskfs_isuid (0, cred)))
+ || (((uid != (uid_t) -1
+ && !idvec_contains (cred->user->uids, uid))
+ || (gid != (gid_t) -1
+ && !idvec_contains (cred->user->gids, gid)))
+ && !idvec_contains (cred->user->uids, 0)))
err = EPERM;
- else
+ else
{
- err = diskfs_validate_owner_change (np, uid);
- if (!err)
+ if (uid != (uid_t) -1)
+ err = diskfs_validate_owner_change (np, uid);
+ if (!err && gid != (gid_t) -1)
err = diskfs_validate_group_change (np, gid);
if (!err)
{
- np->dn_stat.st_uid = uid;
- np->dn_stat.st_gid = gid;
+ if (uid != (uid_t) -1)
+ {
+ np->dn_stat.st_uid = uid;
+ if (np->author_tracks_uid)
+ np->dn_stat.st_author = uid;
+ }
+ if (gid != (gid_t) -1)
+ np->dn_stat.st_gid = gid;
np->dn_set_ctime = 1;
+ if (np->filemod_reqs)
+ diskfs_notice_filechange(np,
+ FILE_CHANGED_META,
+ 0, 0);
}
}
}));
diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c
index c21f12e1..452240c0 100644
--- a/libdiskfs/file-exec.c
+++ b/libdiskfs/file-exec.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation
+/* File execution (file_exec RPC) for diskfs servers, using exec server.
+ Copyright (C) 1993,94,95,96,97,98,2000,02 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.
@@ -22,30 +22,30 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "priv.h"
#include "fs_S.h"
#include <sys/stat.h>
-#include <fcntlbits.h>
+#include <fcntl.h>
#include <hurd/exec.h>
#include <hurd/paths.h>
#include <string.h>
#include <idvec.h>
-kern_return_t
+kern_return_t
diskfs_S_file_exec (struct protid *cred,
task_t task,
int flags,
char *argv,
- u_int argvlen,
+ size_t argvlen,
char *envp,
- u_int envplen,
+ size_t envplen,
mach_port_t *fds,
- u_int fdslen,
+ size_t fdslen,
mach_port_t *portarray,
- u_int portarraylen,
+ size_t portarraylen,
int *intarray,
- u_int intarraylen,
+ size_t intarraylen,
mach_port_t *deallocnames,
- u_int deallocnameslen,
+ size_t deallocnameslen,
mach_port_t *destroynames,
- u_int destroynameslen)
+ size_t destroynameslen)
{
struct node *np;
uid_t uid;
@@ -53,44 +53,67 @@ diskfs_S_file_exec (struct protid *cred,
mode_t mode;
int suid, sgid;
struct protid *newpi;
+ struct peropen *newpo;
error_t err = 0;
-
+ mach_port_t execserver;
+ int cached_exec;
+ struct hurd_userlink ulink;
+ mach_port_t right;
+
+#define RETURN(code) do { err = (code); goto out; } while (0)
+
if (!cred)
return EOPNOTSUPP;
- if (diskfs_exec == MACH_PORT_NULL)
- diskfs_exec = file_name_lookup (_SERVERS_EXEC, 0, 0);
- if (diskfs_exec == MACH_PORT_NULL)
- return EOPNOTSUPP;
-
+ /* Get a light reference to the cached exec server port. */
+ execserver = _hurd_port_get (&_diskfs_exec_portcell, &ulink);
+ cached_exec = (execserver != MACH_PORT_NULL);
+ if (execserver == MACH_PORT_NULL)
+ {
+ /* No cached port. Look up the canonical naming point. */
+ execserver = file_name_lookup (_SERVERS_EXEC, 0, 0);
+ if (execserver == MACH_PORT_NULL)
+ return EOPNOTSUPP; /* No exec server, no exec. */
+ else
+ {
+ /* Install the newly-gotten exec server port for other
+ threads to use, then get a light reference for this call. */
+ _hurd_port_set (&_diskfs_exec_portcell, execserver);
+ execserver = _hurd_port_get (&_diskfs_exec_portcell, &ulink);
+ }
+ }
+
np = cred->po->np;
mutex_lock (&np->lock);
mode = np->dn_stat.st_mode;
uid = np->dn_stat.st_uid;
- gid = np->dn_stat.st_uid;
+ gid = np->dn_stat.st_gid;
mutex_unlock (&np->lock);
+ if (_diskfs_noexec)
+ RETURN (EACCES);
+
if ((cred->po->openstat & O_EXEC) == 0)
- return EBADF;
-
+ RETURN (EBADF);
+
if (!((mode & (S_IXUSR|S_IXGRP|S_IXOTH))
|| ((mode & S_IUSEUNK) && (mode & (S_IEXEC << S_IUNKSHIFT)))))
- return EACCES;
-
+ RETURN (EACCES);
+
if ((mode & S_IFMT) == S_IFDIR)
- return EACCES;
+ RETURN (EACCES);
suid = mode & S_ISUID;
sgid = mode & S_ISGID;
- if (suid || sgid)
+ if (!_diskfs_nosuid && (suid || sgid))
{
int secure = 0;
error_t get_file_ids (struct idvec *uids, struct idvec *gids)
{
- error_t err = idvec_merge_ids (uids, cred->uids, cred->nuids);
+ error_t err = idvec_merge (uids, cred->user->uids);
if (! err)
- err = idvec_merge_ids (gids, cred->gids, cred->ngids);
+ err = idvec_merge (gids, cred->user->gids);
return err;
}
err =
@@ -107,34 +130,74 @@ diskfs_S_file_exec (struct protid *cred,
to the user. Too many things depend on that that it can't be
changed. So this vague attempt isn't even worth trying. */
#if 0
- if (diskfs_access (np, S_IREAD, cred))
+ if (fshelp_access (&np->dn_stat, S_IREAD, cred->user))
flags |= EXEC_NEWTASK;
#endif
if (! err)
- err = diskfs_create_protid (diskfs_make_peropen (np, O_READ,
- cred->po->dotdotport),
- cred->uids, cred->nuids,
- cred->gids, cred->ngids,
- &newpi);
+ /* Make a new peropen for the exec server to access the file, since any
+ seeking the exec server might want to do should not affect the
+ original peropen on which file_exec was called. (The new protid for
+ this peropen clones the caller's iouser to preserve the caller's
+ authentication credentials.) The new peropen's openmodes must have
+ O_READ even if the caller had only O_EXEC privilege, so the exec
+ server can read the executable file. We also include O_EXEC so that
+ the exec server can turn this peropen into a file descriptor in the
+ target process and permit it to exec its /dev/fd/N pseudo-file. */
+ {
+ err = diskfs_make_peropen (np, O_READ|O_EXEC, cred->po, &newpo);
+ if (! err)
+ {
+ err = diskfs_create_protid (newpo, cred->user, &newpi);
+ if (err)
+ diskfs_release_peropen (newpo);
+ }
+ }
if (! err)
{
- err = exec_exec (diskfs_exec,
- ports_get_right (newpi),
- MACH_MSG_TYPE_MAKE_SEND,
- task, flags, argv, argvlen, envp, envplen,
- fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
- portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
- intarray, intarraylen, deallocnames, deallocnameslen,
- destroynames, destroynameslen);
+ do
+ {
+ right = ports_get_send_right (newpi);
+ err = exec_exec (execserver,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, argv, argvlen, envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+ mach_port_deallocate (mach_task_self (), right);
+ if (err == MACH_SEND_INVALID_DEST)
+ {
+ if (cached_exec)
+ {
+ /* We were using a previously looked-up exec server port.
+ Try looking up a new one before giving an error. */
+ cached_exec = 0;
+ _hurd_port_free (&_diskfs_exec_portcell, &ulink, execserver);
+
+ execserver = file_name_lookup (_SERVERS_EXEC, 0, 0);
+ if (execserver == MACH_PORT_NULL)
+ err = EOPNOTSUPP;
+ else
+ {
+ _hurd_port_set (&_diskfs_exec_portcell, execserver);
+ execserver = _hurd_port_get (&_diskfs_exec_portcell,
+ &ulink);
+ }
+ }
+ else
+ err = EOPNOTSUPP;
+ }
+ } while (err == MACH_SEND_INVALID_DEST);
ports_port_deref (newpi);
}
if (! err)
{
unsigned int i;
-
+
mach_port_deallocate (mach_task_self (), task);
for (i = 0; i < fdslen; i++)
mach_port_deallocate (mach_task_self (), fds[i]);
@@ -142,5 +205,8 @@ diskfs_S_file_exec (struct protid *cred,
mach_port_deallocate (mach_task_self (), portarray[i]);
}
- return err;
+ out:
+ _hurd_port_free (&_diskfs_exec_portcell, &ulink, execserver);
+
+ return err;
}
diff --git a/libdiskfs/file-get-fs-opts.c b/libdiskfs/file-get-fs-opts.c
index 662e7511..b3bca821 100644
--- a/libdiskfs/file-get-fs-opts.c
+++ b/libdiskfs/file-get-fs-opts.c
@@ -1,8 +1,7 @@
/* Get run-time file system options
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Copyright (C) 1995,96,98,2002 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -22,26 +21,33 @@
#include <errno.h>
#include <string.h>
+#include <argz.h>
#include "priv.h"
error_t
diskfs_S_file_get_fs_options (struct protid *cred,
- char **data, unsigned *data_len)
+ char **data, size_t *data_len)
{
error_t err;
- char *argz;
- size_t argz_len;
+ char *argz = 0;
+ size_t argz_len = 0;
if (! cred)
return EOPNOTSUPP;
+ err = argz_add (&argz, &argz_len, program_invocation_name);
+ if (err)
+ return err;
+
rwlock_reader_lock (&diskfs_fsys_lock);
- err = diskfs_get_options (&argz, &argz_len);
+ err = diskfs_append_args (&argz, &argz_len);
rwlock_reader_unlock (&diskfs_fsys_lock);
if (! err)
/* Move ARGZ from a malloced buffer into a vm_alloced one. */
- err = fshelp_return_malloced_buffer (argz, argz_len, data, data_len);
+ err = iohelp_return_malloced_buffer (argz, argz_len, data, data_len);
+ else
+ free (argz);
return err;
}
diff --git a/libdiskfs/file-get-trans.c b/libdiskfs/file-get-trans.c
index abb9e9e7..e77dba82 100644
--- a/libdiskfs/file-get-trans.c
+++ b/libdiskfs/file-get-trans.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_get_translator
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,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
@@ -25,14 +25,14 @@
kern_return_t
diskfs_S_file_get_translator (struct protid *cred,
char **trans,
- u_int *translen)
+ size_t *translen)
{
struct node *np;
error_t error = 0;
-
+
if (!cred)
return EOPNOTSUPP;
-
+
np = cred->po->np;
mutex_lock (&np->lock);
@@ -41,14 +41,14 @@ diskfs_S_file_get_translator (struct protid *cred,
if (S_ISLNK (np->dn_stat.st_mode))
{
unsigned int len = sizeof _HURD_SYMLINK + np->dn_stat.st_size + 1;
- int amt;
+ size_t amt;
assert (diskfs_shortcut_symlink);
- if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *)trans, len, 1);
+ if (len > *translen)
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (_HURD_SYMLINK, *trans, sizeof _HURD_SYMLINK);
if (diskfs_read_symlink_hook)
- error = (*diskfs_read_symlink_hook) (np,
+ error = (*diskfs_read_symlink_hook) (np,
*trans + sizeof _HURD_SYMLINK);
if (!diskfs_read_symlink_hook || error == EINVAL)
{
@@ -62,6 +62,8 @@ diskfs_S_file_get_translator (struct protid *cred,
(*trans)[sizeof _HURD_SYMLINK + np->dn_stat.st_size] = '\0';
*translen = len;
}
+ else if (len > *translen)
+ munmap (trans, len);
}
else if (S_ISCHR (np->dn_stat.st_mode) || S_ISBLK (np->dn_stat.st_mode))
{
@@ -73,27 +75,28 @@ diskfs_S_file_get_translator (struct protid *cred,
else
assert (diskfs_shortcut_blkdev);
- buflen = asprintf (&buf, "%s%c%d%c%d",
- (S_ISCHR (np->dn_stat.st_mode)
+ buflen = asprintf (&buf, "%s%c%d%c%d",
+ (S_ISCHR (np->dn_stat.st_mode)
? _HURD_CHRDEV
: _HURD_BLKDEV),
'\0', (np->dn_stat.st_rdev >> 8) & 0377,
'\0', (np->dn_stat.st_rdev) & 0377);
buflen++; /* terminating nul */
-
+
if (buflen > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans, buflen, 1);
+ *trans = mmap (0, buflen, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (buf, *trans, buflen);
+ free (buf);
*translen = buflen;
error = 0;
}
else if (S_ISFIFO (np->dn_stat.st_mode))
{
unsigned int len;
-
+
len = sizeof _HURD_FIFO;
if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans, len, 1);
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (_HURD_FIFO, *trans, sizeof _HURD_FIFO);
*translen = len;
error = 0;
@@ -101,17 +104,17 @@ diskfs_S_file_get_translator (struct protid *cred,
else if (S_ISSOCK (np->dn_stat.st_mode))
{
unsigned int len;
-
+
len = sizeof _HURD_IFSOCK;
if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans, len, 1);
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (_HURD_IFSOCK, *trans, sizeof _HURD_IFSOCK);
*translen = len;
error = 0;
}
else
{
- if (!np->istranslated)
+ if (! (np->dn_stat.st_mode & S_IPTRANS))
error = EINVAL;
else
{
@@ -121,15 +124,14 @@ diskfs_S_file_get_translator (struct protid *cred,
if (!error)
{
if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans,
- len, 1);
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (string, *trans, len);
*translen = len;
free (string);
}
}
}
-
+
mutex_unlock (&np->lock);
return error;
diff --git a/libdiskfs/file-get-transcntl.c b/libdiskfs/file-get-transcntl.c
index adda4477..528529fb 100644
--- a/libdiskfs/file-get-transcntl.c
+++ b/libdiskfs/file-get-transcntl.c
@@ -33,13 +33,16 @@ diskfs_S_file_get_translator_cntl (struct protid *cred,
np = cred->po->np;
mutex_lock (&np->lock);
- error = diskfs_isowner (np, cred);
+
+ error = fshelp_isowner (&np->dn_stat, cred->user);
if (!error)
error = fshelp_fetch_control (&np->transbox, ctl);
- if (ctl == MACH_PORT_NULL)
+ if (!error && *ctl == MACH_PORT_NULL)
error = ENXIO;
if (!error)
- *ctltype = MACH_MSG_TYPE_COPY_SEND;
+ *ctltype = MACH_MSG_TYPE_MOVE_SEND;
+
mutex_unlock (&np->lock);
+
return error;
}
diff --git a/libdiskfs/file-getcontrol.c b/libdiskfs/file-getcontrol.c
index e510a271..23afb7cb 100644
--- a/libdiskfs/file-getcontrol.c
+++ b/libdiskfs/file-getcontrol.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs:file_getcontrol.c
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,2001 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,6 +17,7 @@
#include "priv.h"
#include "fs_S.h"
+#include <hurd/fshelp.h>
/* Implement file_getcontrol as described in <hurd/fs.defs>. */
kern_return_t
@@ -24,28 +25,27 @@ diskfs_S_file_getcontrol (struct protid *cred,
mach_port_t *control,
mach_msg_type_name_t *controltype)
{
- int error = 0;
+ int error;
struct port_info *newpi;
if (!cred)
return EOPNOTSUPP;
- if (!diskfs_isuid (0, cred))
- error = EPERM;
- else
- {
- error = ports_create_port (diskfs_control_class, diskfs_port_bucket,
- sizeof (struct port_info), &newpi);
- if (! error)
- {
- spin_lock (&_diskfs_control_lock);
- _diskfs_ncontrol_ports++;
- spin_unlock (&_diskfs_control_lock);
- *control = ports_get_right (newpi);
- *controltype = MACH_MSG_TYPE_MAKE_SEND;
- ports_port_deref (newpi);
- }
- }
-
- return error;
+ error = fshelp_iscontroller (&diskfs_root_node->dn_stat, cred->user);
+ if (error)
+ return error;
+
+ error = ports_create_port (diskfs_control_class, diskfs_port_bucket,
+ sizeof (struct port_info), &newpi);
+ if (error)
+ return error;
+
+ spin_lock (&_diskfs_control_lock);
+ _diskfs_ncontrol_ports++;
+ spin_unlock (&_diskfs_control_lock);
+ *control = ports_get_right (newpi);
+ *controltype = MACH_MSG_TYPE_MAKE_SEND;
+ ports_port_deref (newpi);
+
+ return 0;
}
diff --git a/libdiskfs/file-getfh.c b/libdiskfs/file-getfh.c
index bc788a20..2dcf68e5 100644
--- a/libdiskfs/file-getfh.c
+++ b/libdiskfs/file-getfh.c
@@ -1,28 +1,60 @@
-/* libdiskfs implementation of fs.defs: file_getfh
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation
+/* Return a file handle (for nfs server support)
- 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.
+ Copyright (C) 1997,99,2002 Free Software Foundation, Inc.
- 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.
+ 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. */
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <string.h>
#include "priv.h"
#include "fs_S.h"
+#include "fhandle.h"
-/* Implement file_getfh as described in <hurd/fs.defs>. */
-kern_return_t
-diskfs_S_file_getfh (struct protid *cred __attribute__ ((unused)),
- char **data __attribute__ ((unused)),
- u_int *datalen __attribute__ ((unused)))
+/* Return an NFS file handle for CRED in FH & FN_LEN. */
+error_t
+diskfs_S_file_getfh (struct protid *cred, char **fh, size_t *fh_len)
{
- return EOPNOTSUPP;
+ struct node *node;
+ union diskfs_fhandle *f;
+
+ if (! cred)
+ return EOPNOTSUPP;
+
+ if (! idvec_contains (cred->user->uids, 0))
+ return EPERM;
+
+ assert (sizeof *f == sizeof f->bytes);
+
+ node = cred->po->np;
+
+ mutex_lock (&node->lock);
+
+ if (*fh_len < sizeof (union diskfs_fhandle))
+ *fh = mmap (0, sizeof (union diskfs_fhandle), PROT_READ|PROT_WRITE,
+ MAP_ANON, 0, 0);
+ *fh_len = sizeof *f;
+
+ f = (union diskfs_fhandle *) *fh;
+
+ bzero (f, sizeof *f);
+ f->data.cache_id = node->cache_id;
+ f->data.gen = node->dn_stat.st_gen;
+
+ mutex_unlock (&node->lock);
+
+ return 0;
}
diff --git a/libdiskfs/file-inv-trans.c b/libdiskfs/file-inv-trans.c
deleted file mode 100644
index bbdac6ff..00000000
--- a/libdiskfs/file-inv-trans.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- Copyright (C) 1994, 1995, 1996 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. */
-
-#include "priv.h"
-#include "fs_S.h"
-#include <fcntl.h>
-
-/* Implement fs.defs:file_invoke_translator as described in <hurd/fs.defs>. */
-kern_return_t
-diskfs_S_file_invoke_translator (struct protid *cred __attribute__ ((unused)),
- int flags __attribute__ ((unused)),
- retry_type *retry __attribute__ ((unused)),
- char *retry_name __attribute__ ((unused)),
- mach_port_t *retrypt __attribute__ ((unused)),
- mach_msg_type_name_t *retrypttype
- __attribute__ ((unused)))
-{
-#if 0
- /* XXX */
- static mach_port_t _diskfs_dotdot_file = MACH_PORT_NULL;
- error_t error = 0;
- mode_t type;
- struct node *np;
- struct protid *newpi;
-
- /* This code is very similar (but subtly different) from
- dir-pathtrans.c and fsys-getroot.c. A way should be found to
- combine them. */
-
- if (!cred)
- return EOPNOTSUPP;
-
- flags &= O_HURD;
-
- np = cred->po->np;
-
- mutex_lock (&np->lock);
-
- type = np->dn_stat.st_mode & S_IFMT;
-
- repeat_transcheck:
- /* Ignore O_NOTRANS in the following check */
- if (np->istranslated || np->translator.control != MACH_PORT_NULL)
- {
- mach_port_t control = np->translator.control;
-
- if (control == MACH_PORT_NULL)
- {
- /* This use of _diskfs_dotdot_file is completely and utterly
- bogus. XXX */
- if (error = diskfs_start_translator (np, _diskfs_dotdot_file))
- {
- mutex_unlock (&np->lock);
- return error;
- }
- control = np->translator.control;
- }
-
- mach_port_mod_refs (mach_task_self (), control, MACH_PORT_RIGHT_SEND, 1);
- mutex_unlock (&np->lock);
- error = fsys_getroot (control, cred->uids, cred->nuids,
- cred->gids, cred->ngids, flags, retry,
- retry_name, retrypt);
- if (error == MACH_SEND_INVALID_DEST)
- {
- mutex_lock (&np->lock);
- if (np->translator.control == control)
- fshelp_translator_drop (&np->translator);
- mach_port_deallocate (mach_task_self (), control);
- error = 0;
- goto repeat_transcheck;
- }
-
- if (!error && *retrypt != MACH_PORT_NULL)
- *retrypttype = MACH_MSG_TYPE_MOVE_SEND;
- else
- *retrypttype = MACH_MSG_TYPE_COPY_SEND;
-
- return error;
- }
-
- /* Ignore O_NOTRANS here. */
- if (type == S_IFLNK && !(flags & O_NOLINK))
- {
- /* Handle symlink interpretation */
- char pathbuf[np->dn_stat.st_size + 1];
- int amt;
-
- if (diskfs_read_symlink_hook)
- error = (*diskfs_read_symlink_hook) (np, pathbuf);
- if (!diskfs_read_symlink_hook || error == EINVAL)
- error = diskfs_node_rdwr (np, pathbuf, 0, np->dn_stat.st_size, 0,
- 0, &amt);
- pathbuf[amt] = '\0';
-
- mutex_unlock (&np->lock);
- if (error)
- return error;
-
- if (pathbuf[0] == '/')
- {
- *retry = FS_RETRY_MAGICAL;
- *retrypt = MACH_PORT_NULL;
- *retrypttype = MACH_MSG_TYPE_COPY_SEND;
- strcpy (retry_name, pathbuf);
- return 0;
- }
- else
- {
- *retry = FS_RETRY_REAUTH;
- *retrypt = _diskfs_dotdot_file;
- *retrypttype = MACH_MSG_TYPE_COPY_SEND;
- strcpy (retry_name, pathbuf);
- return 0;
- }
- }
-
- if ((type == S_IFSOCK || type == S_IFBLK
- || type == S_IFCHR || type == S_IFIFO)
- && (flags & (O_READ|O_WRITE|O_EXEC)))
- error = EOPNOTSUPP;
-
-
- flags &= ~OPENONLY_STATE_MODES;
-
- error = diskfs_create_protid (diskfs_make_peropen (np, flags,
- _diskfs_dotdot_file),
- cred->uids, cred->nuids,
- cred->gids, cred->ngids,
- &newpi);
- if (! error)
- {
- *retry = FS_RETRY_NONE;
- retry_name[0] = '\0';
- *retrypt = ports_get_right (newpi);
- *retrypttype = MACH_MSG_TYPE_MAKE_SEND;
- ports_port_deref (newpi);
- }
-
- mutex_unlock (&np->lock);
-
- return error;
-#else
- return EOPNOTSUPP;
-#endif
-}
diff --git a/libdiskfs/file-reparent.c b/libdiskfs/file-reparent.c
new file mode 100644
index 00000000..e659bcf0
--- /dev/null
+++ b/libdiskfs/file-reparent.c
@@ -0,0 +1,70 @@
+/* Reparent a file
+
+ Copyright (C) 1997,2002 Free Software Foundation
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+#include "fs_S.h"
+
+error_t
+diskfs_S_file_reparent (struct protid *cred, mach_port_t parent,
+ mach_port_t *new, mach_msg_type_name_t *new_type)
+{
+ error_t err;
+ struct node *node;
+ struct protid *new_cred;
+ struct peropen *new_po;
+
+ if (! cred)
+ return EOPNOTSUPP;
+
+ node = cred->po->np;
+
+ mutex_lock (&node->lock);
+ err = diskfs_make_peropen (node, cred->po->openstat, cred->po, &new_po);
+ if (! err)
+ {
+ err = diskfs_create_protid (new_po, cred->user, &new_cred);
+ if (err)
+ diskfs_release_peropen (new_po);
+ }
+ mutex_unlock (&node->lock);
+
+ if (! err)
+ {
+ /* Remove old shadow root state. */
+ if (new_cred->po->shadow_root && new_cred->po->shadow_root != node)
+ diskfs_nrele (new_cred->po->shadow_root);
+ if (new_cred->po->shadow_root_parent)
+ mach_port_deallocate (mach_task_self (),
+ new_cred->po->shadow_root_parent);
+
+ /* And install PARENT instead. */
+ new_cred->po->shadow_root = node;
+ new_cred->po->shadow_root_parent = parent;
+
+ *new = ports_get_right (new_cred);
+ *new_type = MACH_MSG_TYPE_MAKE_SEND;
+
+ ports_port_deref (new_cred);
+ }
+
+ return err;
+}
diff --git a/libdiskfs/file-set-size.c b/libdiskfs/file-set-size.c
index f4d3f110..18abb469 100644
--- a/libdiskfs/file-set-size.c
+++ b/libdiskfs/file-set-size.c
@@ -29,7 +29,13 @@ diskfs_S_file_set_size (struct protid *cred,
if (!(cred->po->openstat & O_WRITE))
err = EINVAL;
else if (size < np->dn_stat.st_size)
- err = diskfs_truncate (np, size);
+ {
+ err = diskfs_truncate (np, size);
+ if (!err && np->filemod_reqs)
+ diskfs_notice_filechange (np,
+ FILE_CHANGED_TRUNCATE,
+ 0, size);
+ }
else if (size > np->dn_stat.st_size)
{
err = diskfs_grow (np, size, cred);
@@ -37,6 +43,10 @@ diskfs_S_file_set_size (struct protid *cred,
{
np->dn_stat.st_size = size;
np->dn_set_ctime = np->dn_set_mtime = 1;
+ if (np->filemod_reqs)
+ diskfs_notice_filechange (np,
+ FILE_CHANGED_EXTEND,
+ 0, size);
}
}
else
diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c
index 1143ef4a..26a19eb4 100644
--- a/libdiskfs/file-set-trans.c
+++ b/libdiskfs/file-set-trans.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_set_translator
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992,93,94,95,96,99,2001,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
@@ -20,9 +20,6 @@
#include <hurd/paths.h>
#include <hurd/fsys.h>
-/* XXX - Temporary */
-#define makedev(maj,min) ((((maj)&0xFF)<<8)+((min)&0xFF))
-
/* Implement file_set_translator as described in <hurd/fs.defs>. */
kern_return_t
diskfs_S_file_set_translator (struct protid *cred,
@@ -30,7 +27,7 @@ diskfs_S_file_set_translator (struct protid *cred,
int active_flags,
int killtrans_flags,
char *passive,
- u_int passivelen,
+ size_t passivelen,
fsys_t active)
{
struct node *np;
@@ -53,14 +50,15 @@ diskfs_S_file_set_translator (struct protid *cred,
mutex_lock (&np->lock);
- error = diskfs_isowner (np, cred);
+ error = fshelp_isowner (&np->dn_stat, cred->user);
if (error)
{
mutex_unlock (&np->lock);
return error;
}
- if (active_flags & FS_TRANS_SET)
+ if ((active_flags & FS_TRANS_SET)
+ && ! (active_flags & FS_TRANS_ORPHAN))
{
error = fshelp_fetch_control (&np->transbox, &control);
if (error)
@@ -87,7 +85,7 @@ diskfs_S_file_set_translator (struct protid *cred,
/* Handle exclusive passive bit *first*. */
if ((passive_flags & FS_TRANS_SET)
&& (passive_flags & FS_TRANS_EXCL)
- && np->istranslated)
+ && (np->dn_stat.st_mode & S_IPTRANS))
{
mutex_unlock (&np->lock);
return EBUSY;
@@ -159,7 +157,7 @@ diskfs_S_file_set_translator (struct protid *cred,
}
minor = strtol (arg, 0, 0);
- error = diskfs_validate_rdev_change (np,
+ error = diskfs_validate_rdev_change (np,
makedev (major, minor));
if (error)
{
diff --git a/libdiskfs/file-statfs.c b/libdiskfs/file-statfs.c
index f90b74ef..817b0115 100644
--- a/libdiskfs/file-statfs.c
+++ b/libdiskfs/file-statfs.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_statfs
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1992,93,94,98,2000 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
@@ -15,6 +15,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <string.h>
+#include <sys/statvfs.h>
+
#include "priv.h"
#include "fs_S.h"
@@ -25,8 +28,23 @@ diskfs_S_file_statfs (struct protid *file,
{
if (!file)
return EOPNOTSUPP;
-
+
+ /* Start will all zeros, so the fs can skip fields for which
+ it has no information to contribute. */
+ bzero (statbuf, sizeof *statbuf);
+
+ if (diskfs_readonly)
+ statbuf->f_flag |= ST_RDONLY;
+ if (_diskfs_nosuid)
+ statbuf->f_flag |= ST_NOSUID;
+ if (_diskfs_noexec)
+ statbuf->f_flag |= ST_NOEXEC;
+ if (diskfs_synchronous)
+ statbuf->f_flag |= ST_SYNCHRONOUS;
+
diskfs_set_statfs (statbuf);
+ statbuf->f_namelen = diskfs_name_max;
+
return 0;
}
diff --git a/libdiskfs/file-utimes.c b/libdiskfs/file-utimes.c
index a79d91bd..39fac504 100644
--- a/libdiskfs/file-utimes.c
+++ b/libdiskfs/file-utimes.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_utimes
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1992, 1993, 1994, 1998, 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
@@ -26,12 +26,32 @@ diskfs_S_file_utimes (struct protid *cred,
{
CHANGE_NODE_FIELD (cred,
({
- if (!(err = diskfs_isowner (np, cred)))
+ if (!(err = fshelp_isowner (&np->dn_stat, cred->user)))
{
- np->dn_stat.st_atime = atime.seconds;
- np->dn_stat.st_mtime = mtime.seconds;
- np->dn_set_atime = np->dn_set_mtime = 0;
+ if (atime.microseconds == -1)
+ np->dn_set_atime = 1;
+ else
+ {
+ np->dn_stat.st_atim.tv_sec = atime.seconds;
+ np->dn_stat.st_atim.tv_nsec = atime.microseconds * 1000;
+ np->dn_set_atime = 0;
+ }
+
+ if (mtime.microseconds == -1)
+ np->dn_set_mtime = 1;
+ else
+ {
+ np->dn_stat.st_mtim.tv_sec = mtime.seconds;
+ np->dn_stat.st_mtim.tv_nsec = mtime.microseconds * 1000;
+ np->dn_set_mtime = 0;
+ }
+
np->dn_set_ctime = 1;
+
+ if (np->filemod_reqs)
+ diskfs_notice_filechange (np,
+ FILE_CHANGED_META,
+ 0, 0);
}
}));
}
diff --git a/libdiskfs/filedev.c b/libdiskfs/filedev.c
deleted file mode 100644
index d7ee7030..00000000
--- a/libdiskfs/filedev.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Get the mach device underlying a file
-
- 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 <errno.h>
-#include <sys/fcntl.h>
-
-#include <device/device.h>
-
-#include "priv.h"
-
-/* Returns the name and a send right for the mach device on which the file
- NAME is stored, and returns it in DEV_NAME (which is malloced) and PORT.
- Other values returned are START, the first valid offset, SIZE, the the
- number of blocks after START, and BLOCK_SIZE, the units in which the
- device is addressed.
-
- The device is opened for reading, and if the diskfs global variable
- DISKFS_READONLY is false, writing. */
-error_t
-diskfs_get_file_device (char *name,
- char **dev_name, mach_port_t *port,
- off_t *start, off_t *size, size_t *block_size)
-{
- int i;
- error_t err;
- mach_msg_type_number_t data_len = 100;
- mach_msg_type_number_t num_ints = 10, num_ports = 10, num_offsets = 10;
- int _ints[num_ints], *ints = _ints;
- mach_port_t _ports[num_ports], *ports = _ports;
- off_t _offsets[num_offsets], *offsets = _offsets;
- char _data[data_len], *data = _data;
- file_t node =
- file_name_lookup (name, diskfs_readonly ? O_RDONLY : O_RDWR, 0);
-
- if (node == MACH_PORT_NULL)
- return errno;
-
- *port = MACH_PORT_NULL;
-
- err = file_get_storage_info (node, &ports, &num_ports, &ints, &num_ints,
- &offsets, &num_offsets, &data, &data_len);
- if (err)
- return err;
-
- /* See <hurd/store.h> for an explanation of what's in the vectors returned
- by file_get_storage_info. */
-
- if (num_ints < 6)
- err = EGRATUITOUS;
- else if (ints[0] != STORAGE_DEVICE)
- err = ENODEV;
-
- if (!err && block_size)
- *block_size = ints[2];
-
- if (!err && (start || size))
- /* Extract the device block addresses. */
- {
- size_t num_runs = ints[3];
- if (num_runs != 1)
- /* We can't handle anything but a contiguous set of blocks. */
- err = ENODEV; /* XXX */
- else
- {
- if (start)
- *start = offsets[0];
- if (size)
- *size = offsets[1];
- }
- }
-
- if (!err && dev_name)
- /* Extract the device name into DEV_NAME. */
- {
- size_t name_len = ints[4];
- if (data && name_len > 0)
- if (data_len < name_len)
- err = EGRATUITOUS;
- else
- {
- *dev_name = malloc (name_len);
- if (*dev_name)
- strcpy (*dev_name, data);
- else
- err = ENOMEM;
- }
- }
-
- if (!err && port)
- /* Extract the device port. */
- if (num_ports != 1)
- err = EGRATUITOUS;
- else
- *port = ports[0];
-
- /* Deallocate things we don't care about or that we've made copies of. */
- for (i = (err || !port) ? 0 : 1; i < num_ports; i++)
- if (MACH_PORT_VALID (ports[i]))
- mach_port_deallocate (mach_task_self (), ports[i]);
-
-#define DISCARD_MEM(v, vl, b) \
- if (v != b) \
- vm_deallocate (mach_task_self (), (vm_address_t)v, vl * sizeof *v);
- DISCARD_MEM (ports, num_ports, _ports);
- DISCARD_MEM (ints, num_ints, _ints);
- DISCARD_MEM (offsets, num_offsets, _offsets);
- DISCARD_MEM (data, data_len, _data);
-
- /* Note that we don't deallocate NODE unless we're returning an error,
- which should prevent the information returned by file_get_storage_info
- from changing. */
-
- if (err)
- /* We got an error, deallocate everything. */
- mach_port_deallocate (mach_task_self (), node);
-
- return err;
-}
diff --git a/libdiskfs/fsmutations.h b/libdiskfs/fsmutations.h
index 9280ee04..5026810c 100644
--- a/libdiskfs/fsmutations.h
+++ b/libdiskfs/fsmutations.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994,2001 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,11 +17,11 @@
/* Only CPP macro definitions should go in this file. */
-#define FILE_INTRAN protid_t begin_using_protid_port (file_t)
-#define FILE_DESTRUCTOR end_using_protid_port (protid_t)
+#define FILE_INTRAN protid_t diskfs_begin_using_protid_port (file_t)
+#define FILE_DESTRUCTOR diskfs_end_using_protid_port (protid_t)
-#define IO_INTRAN protid_t begin_using_protid_port (io_t)
-#define IO_DESTRUCTOR end_using_protid_port (protid_t)
+#define IO_INTRAN protid_t diskfs_begin_using_protid_port (io_t)
+#define IO_DESTRUCTOR diskfs_end_using_protid_port (protid_t)
#define FILE_IMPORTS import "priv.h";
#define IO_IMPORTS import "priv.h";
diff --git a/libdiskfs/fsys-getfile.c b/libdiskfs/fsys-getfile.c
index 90352ead..2fe9495e 100644
--- a/libdiskfs/fsys-getfile.c
+++ b/libdiskfs/fsys-getfile.c
@@ -1,40 +1,110 @@
-/*
- Copyright (C) 1994, 1995 Free Software Foundation
+/* Return the file for a given handle (for nfs server support)
-This file is part of the GNU Hurd.
+ Copyright (C) 1997,99,2001,02 Free Software Foundation, Inc.
-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.
+ This file is part of the GNU Hurd.
-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.
+ 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.
-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. */
+ 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.
-/* Written by Michael I. Bushnell. */
+ 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. */
+
+#include <fcntl.h>
#include "priv.h"
#include "fsys_S.h"
+#include "fhandle.h"
+/* Return in FILE & FILE_TYPE the file in FSYS corresponding to the NFS file
+ handle HANDLE & HANDLE_LEN. */
error_t
-diskfs_S_fsys_getfile (mach_port_t fsys __attribute__ ((unused)),
- mach_port_t reply,
- mach_msg_type_name_t replytype,
- uid_t *gen_uids __attribute__ ((unused)),
- u_int ngen_uids __attribute__ ((unused)),
- uid_t *gen_gids __attribute__ ((unused)),
- u_int ngen_gids __attribute__ ((unused)),
- char *handle __attribute__ ((unused)),
- u_int handlelen __attribute__ ((unused)),
- mach_port_t *file __attribute__ ((unused)),
- mach_msg_type_name_t *filetype __attribute__ ((unused)))
+diskfs_S_fsys_getfile (mach_port_t fsys,
+ mach_port_t reply, mach_msg_type_name_t reply_type,
+ uid_t *uids, mach_msg_type_number_t nuids,
+ gid_t *gids, mach_msg_type_number_t ngids,
+ char *handle, mach_msg_type_number_t handle_len,
+ mach_port_t *file, mach_msg_type_name_t *file_type)
{
- return EOPNOTSUPP;
-}
+ int flags;
+ error_t err;
+ struct node *node;
+ const union diskfs_fhandle *f;
+ struct protid *new_cred;
+ struct peropen *new_po;
+ struct iouser *user;
+ struct port_info *pt =
+ ports_lookup_port (diskfs_port_bucket, fsys, diskfs_control_class);
+
+ if (!pt)
+ return EOPNOTSUPP;
+
+ if (handle_len != sizeof *f)
+ {
+ ports_port_deref (pt);
+ return EINVAL;
+ }
+
+ f = (const union diskfs_fhandle *) handle;
+
+ err = diskfs_cached_lookup (f->data.cache_id, &node);
+ if (err)
+ {
+ ports_port_deref (pt);
+ return err;
+ }
+
+ if (node->dn_stat.st_gen != f->data.gen)
+ {
+ diskfs_nput (node);
+ ports_port_deref (pt);
+ return ESTALE;
+ }
+ err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
+ if (err)
+ {
+ diskfs_nput (node);
+ ports_port_deref (pt);
+ return err;
+ }
+
+ flags = 0;
+ if (! fshelp_access (&node->dn_stat, S_IREAD, user))
+ flags |= O_READ;
+ if (! fshelp_access (&node->dn_stat, S_IEXEC, user))
+ flags |= O_EXEC;
+ if (! fshelp_access (&node->dn_stat, S_IWRITE, user)
+ && ! S_ISDIR (node->dn_stat.st_mode)
+ && ! diskfs_check_readonly ())
+ flags |= O_WRITE;
+
+ err = diskfs_make_peropen (node, flags, 0, &new_po);
+ if (! err)
+ {
+ err = diskfs_create_protid (new_po, user, &new_cred);
+ if (err)
+ diskfs_release_peropen (new_po);
+ }
+
+ iohelp_free_iouser (user);
+
+ diskfs_nput (node);
+ ports_port_deref (pt);
+
+ if (! err)
+ {
+ *file = ports_get_right (new_cred);
+ *file_type = MACH_MSG_TYPE_MAKE_SEND;
+ }
+
+ return err;
+}
diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c
index 9db349c9..e083032e 100644
--- a/libdiskfs/fsys-getroot.c
+++ b/libdiskfs/fsys-getroot.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1993,94,95,96,97,98,2002 Free Software Foundation
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.
@@ -31,43 +31,55 @@ diskfs_S_fsys_getroot (fsys_t controlport,
mach_msg_type_name_t replytype,
mach_port_t dotdot,
uid_t *uids,
- u_int nuids,
+ size_t nuids,
uid_t *gids,
- u_int ngids,
+ size_t ngids,
int flags,
retry_type *retry,
char *retryname,
file_t *returned_port,
mach_msg_type_name_t *returned_port_poly)
{
- struct port_info *pt = ports_lookup_port (diskfs_port_bucket, controlport,
+ struct port_info *pt = ports_lookup_port (diskfs_port_bucket, controlport,
diskfs_control_class);
error_t error = 0;
mode_t type;
- struct protid pseudocred;
struct protid *newpi;
-
+ struct peropen *newpo;
+ struct iouser user;
+ struct peropen peropen_context =
+ {
+ root_parent: dotdot,
+ shadow_root_parent: MACH_PORT_NULL,
+ shadow_root: _diskfs_chroot_directory ? diskfs_root_node : NULL /* XXX */
+ };
+
if (!pt)
return EOPNOTSUPP;
flags &= O_HURD;
+ user.uids = make_idvec ();
+ user.gids = make_idvec ();
+ idvec_set_ids (user.uids, uids, nuids);
+ idvec_set_ids (user.gids, gids, ngids);
+#define drop_idvec() idvec_free (user.gids); idvec_free (user.uids)
+
rwlock_reader_lock (&diskfs_fsys_lock);
mutex_lock (&diskfs_root_node->lock);
-
+
/* This code is similar (but not the same as) the code in
- dir-pathtrans.c that does the same thing. Perhaps a way should
+ dir-lookup.c that does the same thing. Perhaps a way should
be found to share the logic. */
type = diskfs_root_node->dn_stat.st_mode & S_IFMT;
- if ((diskfs_root_node->istranslated
+ if (((diskfs_root_node->dn_stat.st_mode & S_IPTRANS)
|| fshelp_translated (&diskfs_root_node->transbox))
&& !(flags & O_NOTRANS))
{
error = fshelp_fetch_root (&diskfs_root_node->transbox,
- &dotdot, dotdot, uids, nuids,
- gids, ngids, flags,
+ &peropen_context, dotdot, &user, flags,
_diskfs_translator_callback1,
_diskfs_translator_callback2,
retry, retryname, returned_port);
@@ -75,21 +87,22 @@ diskfs_S_fsys_getroot (fsys_t controlport,
{
mutex_unlock (&diskfs_root_node->lock);
rwlock_reader_unlock (&diskfs_fsys_lock);
+ drop_idvec ();
if (!error)
*returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
return error;
}
-
+
/* ENOENT means the translator was removed in the interim. */
error = 0;
}
-
+
if (type == S_IFLNK && !(flags & (O_NOLINK | O_NOTRANS)))
{
/* Handle symlink interpretation */
char pathbuf[diskfs_root_node->dn_stat.st_size + 1];
- int amt;
-
+ size_t amt;
+
if (diskfs_read_symlink_hook)
error = (*diskfs_read_symlink_hook) (diskfs_root_node, pathbuf);
if (!diskfs_read_symlink_hook || error == EINVAL)
@@ -101,8 +114,11 @@ diskfs_S_fsys_getroot (fsys_t controlport,
mutex_unlock (&diskfs_root_node->lock);
rwlock_reader_unlock (&diskfs_fsys_lock);
if (error)
- return error;
-
+ {
+ drop_idvec ();
+ return error;
+ }
+
if (pathbuf[0] == '/')
{
*retry = FS_RETRY_MAGICAL;
@@ -110,6 +126,7 @@ diskfs_S_fsys_getroot (fsys_t controlport,
*returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
strcpy (retryname, pathbuf);
mach_port_deallocate (mach_task_self (), dotdot);
+ drop_idvec ();
return 0;
}
else
@@ -118,67 +135,73 @@ diskfs_S_fsys_getroot (fsys_t controlport,
*returned_port = dotdot;
*returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
strcpy (retryname, pathbuf);
+ drop_idvec ();
return 0;
}
}
- if ((type == S_IFSOCK || type == S_IFBLK
+ if ((type == S_IFSOCK || type == S_IFBLK
|| type == S_IFCHR || type == S_IFIFO)
&& (flags & (O_READ|O_WRITE|O_EXEC)))
error = EOPNOTSUPP;
-
- /* diskfs_access requires a cred; so we give it one. */
- pseudocred.uids = uids;
- pseudocred.gids = gids;
- pseudocred.nuids = nuids;
- pseudocred.ngids = ngids;
-
+
if (!error && (flags & O_READ))
- error = diskfs_access (diskfs_root_node, S_IREAD, &pseudocred);
-
+ error = fshelp_access (&diskfs_root_node->dn_stat, S_IREAD, &user);
+
if (!error && (flags & O_EXEC))
- error = diskfs_access (diskfs_root_node, S_IEXEC, &pseudocred);
-
+ error = fshelp_access (&diskfs_root_node->dn_stat, S_IEXEC, &user);
+
if (!error && (flags & (O_WRITE)))
{
if (type == S_IFDIR)
error = EISDIR;
else if (diskfs_check_readonly ())
error = EROFS;
- else
- error = diskfs_access (diskfs_root_node, S_IWRITE, &pseudocred);
+ else
+ error = fshelp_access (&diskfs_root_node->dn_stat,
+ S_IWRITE, &user);
}
if (error)
{
mutex_unlock (&diskfs_root_node->lock);
rwlock_reader_unlock (&diskfs_fsys_lock);
+ drop_idvec ();
return error;
}
-
+
if ((flags & O_NOATIME)
- && (diskfs_isowner (diskfs_root_node, &pseudocred) == EPERM))
+ && (fshelp_isowner (&diskfs_root_node->dn_stat, &user)
+ == EPERM))
flags &= ~O_NOATIME;
flags &= ~OPENONLY_STATE_MODES;
- error = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node,
- flags, dotdot),
- uids, nuids, gids, ngids, &newpi);
- mach_port_deallocate (mach_task_self (), dotdot);
+ error = diskfs_make_peropen (diskfs_root_node, flags,
+ &peropen_context, &newpo);
if (! error)
{
+ error = diskfs_create_protid (newpo, &user, &newpi);
+ if (error)
+ diskfs_release_peropen (newpo);
+ }
+
+ if (! error)
+ {
+ mach_port_deallocate (mach_task_self (), dotdot);
*retry = FS_RETRY_NORMAL;
*retryname = '\0';
*returned_port = ports_get_right (newpi);
*returned_port_poly = MACH_MSG_TYPE_MAKE_SEND;
ports_port_deref (newpi);
}
-
+
mutex_unlock (&diskfs_root_node->lock);
rwlock_reader_unlock (&diskfs_fsys_lock);
ports_port_deref (pt);
+ drop_idvec ();
+
return error;
}
diff --git a/libdiskfs/fsys-options.c b/libdiskfs/fsys-options.c
index 5a8b681f..ea5ee8c5 100644
--- a/libdiskfs/fsys-options.c
+++ b/libdiskfs/fsys-options.c
@@ -1,6 +1,6 @@
/* Parse run-time options
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -88,8 +88,8 @@ diskfs_S_fsys_get_options (fsys_t fsys,
mach_msg_type_name_t replytype,
char **data, mach_msg_type_number_t *data_len)
{
- char *argz;
- size_t argz_len;
+ char *argz = 0;
+ size_t argz_len = 0;
error_t err;
struct port_info *port =
ports_lookup_port (diskfs_port_bucket, fsys, diskfs_control_class);
@@ -97,13 +97,19 @@ diskfs_S_fsys_get_options (fsys_t fsys,
if (!port)
return EOPNOTSUPP;
+ err = argz_add (&argz, &argz_len, program_invocation_name);
+ if (err)
+ return err;
+
rwlock_reader_lock (&diskfs_fsys_lock);
- err = diskfs_get_options (&argz, &argz_len);
+ err = diskfs_append_args (&argz, &argz_len);
rwlock_reader_unlock (&diskfs_fsys_lock);
if (! err)
/* Move ARGZ from a malloced buffer into a vm_alloced one. */
- err = fshelp_return_malloced_buffer (argz, argz_len, data, data_len);
+ err = iohelp_return_malloced_buffer (argz, argz_len, data, data_len);
+ else
+ free (argz);
ports_port_deref (port);
return err;
diff --git a/libdiskfs/ifsock.c b/libdiskfs/ifsock.c
index bee9cc19..3e9b8325 100644
--- a/libdiskfs/ifsock.c
+++ b/libdiskfs/ifsock.c
@@ -45,7 +45,7 @@ diskfs_S_ifsock_getsockaddr (struct protid *cred,
mutex_unlock (&np->lock);
return EOPNOTSUPP;
}
- err = diskfs_access (np, S_IREAD, cred);
+ err = fshelp_access (&np->dn_stat, S_IWRITE, cred->user);
if (err)
{
mutex_unlock (&np->lock);
diff --git a/libdiskfs/init-completed.c b/libdiskfs/init-completed.c
deleted file mode 100644
index cbb94e3b..00000000
--- a/libdiskfs/init-completed.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Function called when we're done initializing at boot time
-
- Copyright (C) 1994, 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 <stdio.h>
-
-#include <hurd/startup.h>
-
-#include "diskfs.h"
-
-/* Called by diskfs_start_bootstrap, after the filesystem has a normal
- environment (complete with auth and proc ports). */
-void
-diskfs_init_completed ()
-{
-}
diff --git a/libdiskfs/init-first.c b/libdiskfs/init-first.c
index f1df3dd1..d91345be 100644
--- a/libdiskfs/init-first.c
+++ b/libdiskfs/init-first.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995 Free Software Foundation
+ Copyright (C) 1994,95,97,2001 Free Software Foundation
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.
@@ -20,33 +20,37 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Michael I. Bushnell. */
#include "priv.h"
+#include <stdlib.h>
+#include <hurd/ports.h>
static int thread_timeout = 1000 * 60 * 2; /* two minutes */
static int server_timeout = 1000 * 60 * 10; /* ten minutes */
static any_t
-master_thread_function (any_t foo __attribute__ ((unused)))
+master_thread_function (any_t demuxer)
{
error_t err;
- do
+ do
{
ports_manage_port_operations_multithread (diskfs_port_bucket,
- diskfs_demuxer,
+ (ports_demuxer_type) demuxer,
thread_timeout,
server_timeout,
- 1, MACH_PORT_NULL);
+ 0);
err = diskfs_shutdown (0);
}
while (err);
-
+
exit (0);
+ /* NOTREACHED */
+ return (any_t) 0;
}
void
-diskfs_spawn_first_thread (void)
+diskfs_spawn_first_thread (ports_demuxer_type demuxer)
{
cthread_detach (cthread_fork ((cthread_fn_t) master_thread_function,
- (any_t) 0));
+ (any_t) demuxer));
}
diff --git a/libdiskfs/init-init.c b/libdiskfs/init-init.c
index 14c6f84d..cd0c1b29 100644
--- a/libdiskfs/init-init.c
+++ b/libdiskfs/init-init.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 95, 96, 97, 98, 99, 2001 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.
@@ -28,12 +28,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
mach_port_t diskfs_default_pager;
mach_port_t diskfs_auth_server_port;
volatile struct mapped_time_value *diskfs_mtime;
+
+struct rwlock diskfs_fsys_lock = RWLOCK_INITIALIZER;
mach_port_t diskfs_fsys_identity;
+int _diskfs_nosuid, _diskfs_noexec;
+int _diskfs_noatime;
+
+struct hurd_port _diskfs_exec_portcell;
+
spin_lock_t diskfs_node_refcnt_lock = SPIN_LOCK_INITIALIZER;
spin_lock_t _diskfs_control_lock = SPIN_LOCK_INITIALIZER;
-int _diskfs_ncontrol_ports = 0;
+int _diskfs_ncontrol_ports;
struct port_class *diskfs_protid_class;
struct port_class *diskfs_control_class;
@@ -44,13 +51,13 @@ struct port_class *diskfs_shutdown_notification_class;
struct port_bucket *diskfs_port_bucket;
/* Call this after arguments have been parsed to initialize the
- library. */
+ library. */
error_t
diskfs_init_diskfs (void)
{
error_t err;
-
- if (diskfs_boot_flags)
+
+ if (diskfs_boot_filesystem ())
/* This is a boot filesystem, we have to do some things specially. */
{
mach_port_t host;
@@ -86,6 +93,8 @@ diskfs_init_diskfs (void)
diskfs_port_bucket = ports_create_bucket ();
+ _hurd_port_init (&_diskfs_exec_portcell, MACH_PORT_NULL);
+
return 0;
}
diff --git a/libdiskfs/init-loop.c b/libdiskfs/init-loop.c
deleted file mode 100644
index d0aa0413..00000000
--- a/libdiskfs/init-loop.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- Copyright (C) 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. */
-
-#include "priv.h"
-
-void
-diskfs_main_request_loop (void)
-{
- ports_manage_port_operations_multithread ();
-}
diff --git a/libdiskfs/init-main.c b/libdiskfs/init-main.c
new file mode 100644
index 00000000..16fdafa4
--- /dev/null
+++ b/libdiskfs/init-main.c
@@ -0,0 +1,78 @@
+/* diskfs_init_main -- initialize diskfs world, parse arguments, and open store
+ Copyright (C) 1999, 2001 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. */
+
+#include "diskfs.h"
+#include <argp.h>
+#include <assert.h>
+#include <error.h>
+#include <hurd/store.h>
+
+struct store *
+diskfs_init_main (struct argp *startup_argp,
+ int argc, char **argv,
+ struct store_parsed **store_parsed,
+ mach_port_t *bootstrap)
+{
+ error_t err;
+ struct store_argp_params store_params = { 0 };
+ struct store *store;
+
+ /* We must use ARGP_IN_ORDER for the parsing of --boot-command to work. */
+ err = argp_parse (startup_argp ?: &diskfs_store_startup_argp,
+ argc, argv, ARGP_IN_ORDER, NULL,
+ &store_params);
+ assert_perror (err);
+ *store_parsed = store_params.result;
+
+ err = store_parsed_name (*store_parsed, &diskfs_disk_name);
+ if (err)
+ error (2, err, "store_parsed_name");
+
+ /* 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_filesystem ())
+ /* 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->flags & STORE_HARD_READONLY)
+ diskfs_readonly = diskfs_hard_readonly = 1;
+
+ /* Start the first request thread, to handle RPCs and page requests. */
+ diskfs_spawn_first_thread (diskfs_demuxer);
+
+ return store;
+}
diff --git a/libdiskfs/init-startup.c b/libdiskfs/init-startup.c
index 885f7ccc..bf1acf29 100644
--- a/libdiskfs/init-startup.c
+++ b/libdiskfs/init-startup.c
@@ -1,5 +1,5 @@
/* diskfs_startup_diskfs -- advertise our fsys control port to our parent FS.
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,98,99,2000,02 Free Software Foundation
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.
@@ -22,30 +22,84 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "priv.h"
#include <stdio.h>
#include <string.h>
+#include <fcntl.h>
+#include <error.h>
#include <hurd/fsys.h>
#include <hurd/startup.h>
+char *_diskfs_chroot_directory;
+
mach_port_t
diskfs_startup_diskfs (mach_port_t bootstrap, int flags)
{
- mach_port_t realnode;
+ error_t err;
+ mach_port_t realnode, right;
struct port_info *newpi;
-
- if (bootstrap != MACH_PORT_NULL)
+
+ if (_diskfs_chroot_directory != NULL)
{
- errno = ports_create_port (diskfs_control_class, diskfs_port_bucket,
- sizeof (struct port_info), &newpi);
- if (! errno)
+ /* The boot options requested we change to a subdirectory
+ and treat that as the root of the filesystem. */
+ struct node *np, *old;
+ struct protid *rootpi;
+ struct peropen *rootpo;
+
+ /* Skip leading slashes. */
+ while (*_diskfs_chroot_directory == '/')
+ ++_diskfs_chroot_directory;
+
+ mutex_lock (&diskfs_root_node->lock);
+
+ /* Create a protid we can use in diskfs_lookup. */
+ err = diskfs_make_peropen (diskfs_root_node, O_READ|O_EXEC,
+ 0, &rootpo);
+ assert_perror (err);
+ err = diskfs_create_protid (rootpo, 0, &rootpi);
+ assert_perror (err);
+
+ /* Look up the directory name. */
+ err = diskfs_lookup (diskfs_root_node, _diskfs_chroot_directory,
+ LOOKUP, &np, NULL, rootpi);
+ mutex_unlock (&diskfs_root_node->lock);
+ ports_port_deref (rootpi);
+
+ if (err == EAGAIN)
+ error (1, 0, "`--virtual-root=%s' specifies the real root directory",
+ _diskfs_chroot_directory);
+ else if (err)
+ error (1, err, "`%s' not found", _diskfs_chroot_directory);
+
+ if (!S_ISDIR (np->dn_stat.st_mode))
{
- errno = fsys_startup (bootstrap, flags, ports_get_right (newpi),
- MACH_MSG_TYPE_MAKE_SEND, &realnode);
- ports_port_deref (newpi);
+ mutex_unlock (&np->lock);
+ error (1, ENOTDIR, "%s", _diskfs_chroot_directory);
}
- if (errno)
+
+ /* Install this node as the new root, forgetting about the real root
+ node. The last essential piece that makes the virtual root work
+ is in fsys-getroot.c, which sets the first peropen's shadow_root
+ if _diskfs_chroot_directory is non-null. */
+ old = diskfs_root_node;
+ diskfs_root_node = np;
+ mutex_unlock (&np->lock);
+ diskfs_nput (old);
+ }
+
+ if (bootstrap != MACH_PORT_NULL)
+ {
+ err = ports_create_port (diskfs_control_class, diskfs_port_bucket,
+ sizeof (struct port_info), &newpi);
+ if (! err)
{
- perror ("Translator startup failure: fsys_startup");
- exit (1);
+ right = ports_get_send_right (newpi);
+ err = fsys_startup (bootstrap, flags, right,
+ MACH_MSG_TYPE_COPY_SEND, &realnode);
+ mach_port_deallocate (mach_task_self (), right);
+ ports_port_deref (newpi);
}
+ if (err)
+ error (1, err, "Translator startup failure: fsys_startup");
+
mach_port_deallocate (mach_task_self (), bootstrap);
_diskfs_ncontrol_ports++;
@@ -70,22 +124,22 @@ error_t
diskfs_S_startup_dosync (mach_port_t handle)
{
error_t err = 0;
- struct port_info *pi
+ struct port_info *pi
= ports_lookup_port (diskfs_port_bucket, handle,
diskfs_shutdown_notification_class);
if (!pi)
return EOPNOTSUPP;
-
+
if (! diskfs_readonly)
{
/* First start a sync so that if something goes wrong
we at least get this much done. */
diskfs_sync_everything (0);
diskfs_set_hypermetadata (0, 0);
-
+
rwlock_writer_lock (&diskfs_fsys_lock);
-
+
/* Permit all the current RPC's to finish, and then suspend new ones */
err = ports_inhibit_class_rpcs (diskfs_protid_class);
if (! err)
@@ -107,7 +161,7 @@ diskfs_S_startup_dosync (mach_port_t handle)
/* This is called when we have an ordinary environment, complete
with proc and auth ports. */
-void
+void
_diskfs_init_completed ()
{
startup_t init;
@@ -117,12 +171,12 @@ _diskfs_init_completed ()
mach_port_t notify;
char *name;
- /* Contact the startup server and register our shutdown request.
+ /* Contact the startup server and register our shutdown request.
If we get an error, print an informational message. */
proc = getproc ();
assert (proc);
-
+
err = ports_create_port (diskfs_shutdown_notification_class,
diskfs_port_bucket, sizeof (struct port_info),
&pi);
@@ -133,23 +187,21 @@ _diskfs_init_completed ()
mach_port_deallocate (mach_task_self (), proc);
if (err)
goto errout;
-
- notify = ports_get_right (pi);
+
+ notify = ports_get_send_right (pi);
ports_port_deref (pi);
- asprintf (&name, "%s %s", program_invocation_short_name,
- diskfs_device_arg);
- err = startup_request_notification (init, notify,
- MACH_MSG_TYPE_MAKE_SEND, name);
+ asprintf (&name,
+ "%s %s", program_invocation_short_name, diskfs_disk_name ?: "-");
+ err = startup_request_notification (init, notify,
+ MACH_MSG_TYPE_COPY_SEND, name);
+ mach_port_deallocate (mach_task_self (), notify);
free (name);
if (err)
goto errout;
-
+
mach_port_deallocate (mach_task_self (), init);
return;
errout:
- fprintf (stderr, "Cannot request shutdown notification: %s\n",
- strerror (err));
+ error (0, err, "Cannot request shutdown notification");
}
-
-
diff --git a/libdiskfs/interrupt.c b/libdiskfs/interrupt.c
deleted file mode 100644
index ffd7fb83..00000000
--- a/libdiskfs/interrupt.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Copyright (C) 1993, 1994, 1995 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. */
-
-#include "priv.h"
-#include "interrupt_S.h"
-
-kern_return_t
-diskfs_S_interrupt_operation (mach_port_t handle)
-{
- struct port_info *pi;
-
- pi = ports_lookup_port (diskfs_port_bucket, handle, 0);
- if (!pi)
- return EOPNOTSUPP;
-
- ports_interrupt_rpc (pi);
-
- ports_port_deref (pi);
-
- return 0;
-}
diff --git a/libdiskfs/io-duplicate.c b/libdiskfs/io-duplicate.c
index addefc48..3cbf8f7b 100644
--- a/libdiskfs/io-duplicate.c
+++ b/libdiskfs/io-duplicate.c
@@ -32,8 +32,7 @@ diskfs_S_io_duplicate (struct protid *cred,
mutex_lock (&cred->po->np->lock);
- err = diskfs_create_protid (cred->po, cred->uids, cred->nuids,
- cred->gids, cred->ngids, &newpi);
+ err = diskfs_create_protid (cred->po, cred->user, &newpi);
if (! err)
{
*port = ports_get_right (newpi);
diff --git a/libdiskfs/io-identity.c b/libdiskfs/io-identity.c
index 2cd64907..6f4e7546 100644
--- a/libdiskfs/io-identity.c
+++ b/libdiskfs/io-identity.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of io_identity RPC
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996,97,98,2001,02 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -28,26 +28,40 @@ diskfs_S_io_identity (struct protid *cred,
mach_msg_type_name_t *idtype,
mach_port_t *fsys,
mach_msg_type_name_t *fsystype,
- int *fileno)
+ ino_t *fileno)
{
struct node *np;
error_t err;
+ ino_t inum;
if (!cred)
return EOPNOTSUPP;
-
+
np = cred->po->np;
mutex_lock (&np->lock);
-
- err = fshelp_get_identity (diskfs_port_bucket, np->dn_stat.st_ino, id);
- if (!err)
+ inum = np->dn_stat.st_ino;
+ mutex_unlock (&np->lock);
+
+ err = fshelp_get_identity (diskfs_port_bucket, inum, id);
+ if (! err)
+ {
+ if (cred->po->shadow_root && cred->po->shadow_root != diskfs_root_node)
+ {
+ err = fshelp_get_identity (diskfs_port_bucket,
+ cred->po->shadow_root->dn_stat.st_ino,
+ fsys);
+ if (err)
+ mach_port_deallocate (mach_task_self (), *id);
+ }
+ else
+ *fsys = diskfs_fsys_identity;
+ }
+ if (! err)
{
*idtype = MACH_MSG_TYPE_MAKE_SEND;
- *fsys = diskfs_fsys_identity;
*fsystype = MACH_MSG_TYPE_MAKE_SEND;
- *fileno = np->dn_stat.st_ino;
+ *fileno = inum;
}
-
- mutex_unlock (&np->lock);
+
return err;
}
diff --git a/libdiskfs/io-map-cntl.c b/libdiskfs/io-map-cntl.c
index b45ccffd..d615b046 100644
--- a/libdiskfs/io-map-cntl.c
+++ b/libdiskfs/io-map-cntl.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1994,96,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
@@ -34,8 +34,8 @@ diskfs_S_io_map_cntl (struct protid *cred,
{
default_pager_object_create (diskfs_default_pager, &cred->shared_object,
__vm_page_size);
- vm_map (mach_task_self (), (u_int *)&cred->mapped, vm_page_size, 0, 1,
- cred->shared_object, 0, 0,
+ vm_map (mach_task_self (), (vm_address_t *)&cred->mapped, vm_page_size,
+ 0, 1, cred->shared_object, 0, 0,
VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0);
cred->mapped->shared_page_magic = SHARED_PAGE_MAGIC;
cred->mapped->conch_status = USER_HAS_NOT_CONCH;
diff --git a/libdiskfs/io-map.c b/libdiskfs/io-map.c
index c9e897c6..6268f2c5 100644
--- a/libdiskfs/io-map.c
+++ b/libdiskfs/io-map.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 1997 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
@@ -44,13 +44,19 @@ diskfs_S_io_map (struct protid *cred,
{
case O_READ | O_WRITE:
*wrobj = *rdobj = diskfs_get_filemap (node, VM_PROT_READ |VM_PROT_WRITE);
+ if (*wrobj == MACH_PORT_NULL)
+ goto error;
mach_port_mod_refs (mach_task_self (), *rdobj, MACH_PORT_RIGHT_SEND, 1);
break;
case O_READ:
*rdobj = diskfs_get_filemap (node, VM_PROT_READ);
+ if (*rdobj == MACH_PORT_NULL)
+ goto error;
break;
case O_WRITE:
*wrobj = diskfs_get_filemap (node, VM_PROT_WRITE);
+ if (*wrobj == MACH_PORT_NULL)
+ goto error;
break;
}
mutex_unlock (&node->lock);
@@ -59,4 +65,9 @@ diskfs_S_io_map (struct protid *cred,
*wrtype = MACH_MSG_TYPE_MOVE_SEND;
return 0;
+
+error:
+ mutex_unlock (&node->lock);
+ return errno;
}
+
diff --git a/libdiskfs/io-pathconf.c b/libdiskfs/io-pathconf.c
index 0b80b14e..38e277c3 100644
--- a/libdiskfs/io-pathconf.c
+++ b/libdiskfs/io-pathconf.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of io.defs: io_pathconf
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation
+ Copyright (C) 1992, 1993, 1994, 1995, 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
@@ -15,16 +15,66 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <unistd.h>
#include "priv.h"
#include "io_S.h"
+#include <dirent.h>
+#include <limits.h>
/* Implement io_pathconf as described in <hurd/io.defs>. */
kern_return_t
diskfs_S_io_pathconf (struct protid *cred,
- int name __attribute__ ((unused)), int *value)
+ int name,
+ int *value)
{
if (!cred)
return EOPNOTSUPP;
- *value = 0; /* XXX */
+
+ switch (name)
+ {
+ case _PC_LINK_MAX:
+ *value = diskfs_link_max;
+ break;
+
+ case _PC_MAX_CANON:
+ case _PC_MAX_INPUT:
+ case _PC_PIPE_BUF:
+ case _PC_VDISABLE:
+ case _PC_SOCK_MAXBUF:
+ case _PC_PATH_MAX:
+ *value = -1;
+ break;
+
+ case _PC_NAME_MAX:
+ /* <hurd/hurd_types.defs> string_t constrains the upper bound.
+ The `struct dirent' format defined by libc further contrains it. */
+#define D_NAMLEN_MAX (UCHAR_MAX * sizeof (((struct dirent *) 0)->d_namlen))
+ if (diskfs_name_max > D_NAMLEN_MAX || diskfs_name_max < 0)
+ diskfs_name_max = D_NAMLEN_MAX;
+ *value = diskfs_name_max;
+ break;
+
+ case _PC_NO_TRUNC: /* enforced in diskfs_lookup */
+ *value = 1; /* diskfs_name_max >= 0; */ /* see above */
+ break;
+
+ case _PC_CHOWN_RESTRICTED:
+ case _PC_SYNC_IO:
+ case _PC_ASYNC_IO:
+ *value = 1;
+ break;
+
+ case _PC_PRIO_IO:
+ *value = 0;
+ break;
+
+ case _PC_FILESIZEBITS:
+ *value = 32;
+ break;
+
+ default:
+ return EINVAL;
+ }
+
return 0;
}
diff --git a/libdiskfs/io-prenotify.c b/libdiskfs/io-prenotify.c
index 4ae3967b..f193f52b 100644
--- a/libdiskfs/io-prenotify.c
+++ b/libdiskfs/io-prenotify.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 1995, 1996, 2001 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
@@ -22,7 +22,7 @@
We set the prenotify size to be the allocated size of the file;
then users are forced to call this routine before writing past
- that, and we can do allocation (orreturn ENOSPC if necessary. */
+ that, and we can do allocation (or return ENOSPC if necessary). */
kern_return_t
diskfs_S_io_prenotify (struct protid *cred,
vm_offset_t start __attribute__ ((unused)),
@@ -64,6 +64,8 @@ diskfs_S_io_prenotify (struct protid *cred,
err = diskfs_grow (np, end, cred);
if (diskfs_synchronous)
diskfs_node_update (np, 1);
+ if (!err && np->filemod_reqs)
+ diskfs_notice_filechange (np, FILE_CHANGED_EXTEND, 0, end);
out:
mutex_unlock (&np->lock);
return err;
diff --git a/libdiskfs/io-read.c b/libdiskfs/io-read.c
index a5dd148a..787c0eae 100644
--- a/libdiskfs/io-read.c
+++ b/libdiskfs/io-read.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,97,99,2001 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
@@ -29,7 +29,7 @@ diskfs_S_io_read (struct protid *cred,
{
struct node *np;
int err;
- int off = offset;
+ off_t off = offset;
char *buf;
int ourbuf = 0;
@@ -46,6 +46,11 @@ diskfs_S_io_read (struct protid *cred,
if (off == -1)
off = cred->po->filepointer;
+ if (off < 0)
+ {
+ mutex_unlock (&np->lock);
+ return EINVAL;
+ }
if (off > np->dn_stat.st_size)
maxread = 0;
@@ -55,24 +60,49 @@ diskfs_S_io_read (struct protid *cred,
if (maxread > *datalen)
{
ourbuf = 1;
- vm_allocate (mach_task_self (), (u_int *) &buf, maxread, 1);
+ buf = mmap (0, maxread, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
*data = buf;
}
else
buf = *data;
*datalen = maxread;
- if (maxread)
+
+ if (maxread == 0)
+ err = 0;
+ else if (S_ISLNK (np->dn_stat.st_mode))
+ {
+ /* Read from a symlink. */
+ if (! diskfs_read_symlink_hook)
+ err = EINVAL;
+ else
+ {
+ if (off == 0 && maxread == np->dn_stat.st_size)
+ err = (*diskfs_read_symlink_hook)(np, buf);
+ else
+ {
+ char *whole_link = alloca (np->dn_stat.st_size);
+ err = (*diskfs_read_symlink_hook)(np, whole_link);
+ if (! err)
+ memcpy (buf, whole_link + off, maxread);
+ }
+ }
+ }
+ else
+ err = EINVAL; /* Use read below. */
+
+ if (err == EINVAL)
err = _diskfs_rdwr_internal (np, buf, off, datalen, 0,
cred->po->openstat & O_NOATIME);
- else
- err = 0;
+
if (diskfs_synchronous)
diskfs_node_update (np, 1); /* atime! */
+
if (offset == -1 && !err)
cred->po->filepointer += *datalen;
+
if (err && ourbuf)
- vm_deallocate (mach_task_self (), (u_int) buf, maxread);
+ munmap (buf, maxread);
mutex_unlock (&np->lock);
return err;
diff --git a/libdiskfs/io-reauthenticate.c b/libdiskfs/io-reauthenticate.c
index 9b065a3b..3c5da52d 100644
--- a/libdiskfs/io-reauthenticate.c
+++ b/libdiskfs/io-reauthenticate.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,2000,01 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
@@ -24,22 +24,14 @@ diskfs_S_io_reauthenticate (struct protid *cred,
mach_port_t rend_port)
{
struct protid *newcred;
- uid_t gubuf[20], ggbuf[20], aubuf[20], agbuf[20];
- uid_t *gen_uids, *gen_gids, *aux_uids, *aux_gids;
- u_int genuidlen, gengidlen, auxuidlen, auxgidlen;
error_t err;
mach_port_t newright;
+ struct iouser *user;
if (cred == 0)
return EOPNOTSUPP;
- genuidlen = gengidlen = auxuidlen = auxgidlen = 20;
- gen_uids = gubuf;
- gen_gids = ggbuf;
- aux_uids = aubuf;
- aux_gids = agbuf;
-
- /* This routine must carefully ignore EINTR because we
+ /* This routine must carefully ignore EINTR because we
are a simpleroutine, so callers won't know to restart. */
mutex_lock (&cred->po->np->lock);
@@ -52,44 +44,23 @@ diskfs_S_io_reauthenticate (struct protid *cred,
return err;
}
- newright = ports_get_right (newcred);
- err = mach_port_insert_right (mach_task_self (), newright, newright,
- MACH_MSG_TYPE_MAKE_SEND);
- assert_perror (err);
- do
- err = auth_server_authenticate (diskfs_auth_server_port,
- rend_port,
- MACH_MSG_TYPE_COPY_SEND,
- newright,
- MACH_MSG_TYPE_COPY_SEND,
- &gen_uids, &genuidlen,
- &aux_uids, &auxuidlen,
- &gen_gids, &gengidlen,
- &aux_gids, &auxgidlen);
- while (err == EINTR);
- mach_port_deallocate (mach_task_self (), rend_port);
+ newright = ports_get_send_right (newcred);
+ assert (newright != MACH_PORT_NULL);
+
+ err = iohelp_reauth (&user, diskfs_auth_server_port, rend_port,
+ newright, 1);
+ if (! err)
+ {
+ diskfs_finish_protid (newcred, user);
+ iohelp_free_iouser (user);
+ mach_port_deallocate (mach_task_self (), rend_port);
+ }
+
mach_port_deallocate (mach_task_self (), newright);
-
- if (err)
- diskfs_finish_protid (newcred, 0, 0, 0, 0);
- else
- diskfs_finish_protid (newcred, gen_uids, genuidlen, gen_gids, gengidlen);
+
mutex_unlock (&cred->po->np->lock);
ports_port_deref (newcred);
- if (gubuf != gen_uids)
- vm_deallocate (mach_task_self (), (u_int) gen_uids,
- genuidlen * sizeof (uid_t));
- if (ggbuf != gen_gids)
- vm_deallocate (mach_task_self (), (u_int) gen_gids,
- gengidlen * sizeof (uid_t));
- if (aubuf != aux_uids)
- vm_deallocate (mach_task_self (), (u_int) aux_uids,
- auxuidlen * sizeof (uid_t));
- if (agbuf != aux_gids)
- vm_deallocate (mach_task_self (), (u_int) aux_gids,
- auxgidlen * sizeof (uid_t));
-
- return 0;
+ return err;
}
diff --git a/libdiskfs/io-restrict-auth.c b/libdiskfs/io-restrict-auth.c
index f2e00293..c1560ac1 100644
--- a/libdiskfs/io-restrict-auth.c
+++ b/libdiskfs/io-restrict-auth.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+/*
+ Copyright (C) 1994,95,96,2001, 2002 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
@@ -18,16 +18,6 @@
#include "priv.h"
#include "io_S.h"
-/* Tell if the array LIST (of size N) contains a member equal to QUERY. */
-static inline int
-listmember (int *list, int query, int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (list[i] == query)
- return 1;
- return 0;
-}
/* Implement io_restrict_auth as described in <hurd/io.defs>. */
kern_return_t
@@ -35,31 +25,23 @@ diskfs_S_io_restrict_auth (struct protid *cred,
mach_port_t *newport,
mach_msg_type_name_t *newportpoly,
uid_t *uids,
- u_int nuids,
+ size_t nuids,
gid_t *gids,
- u_int ngids)
+ size_t ngids)
{
error_t err;
- uid_t *newuids, *newgids;
- int i, newnuids, newngids;
+ struct iouser *user;
struct protid *newpi;
-
+
if (!cred)
return EOPNOTSUPP;
-
- newuids = alloca (sizeof (uid_t) * cred->nuids);
- newgids = alloca (sizeof (uid_t) * cred->ngids);
-
- for (i = newnuids = 0; i < cred->nuids; i++)
- if (listmember (uids, cred->uids[i], nuids))
- newuids[newnuids++] = cred->uids[i];
- for (i = newngids = 0; i < cred->ngids; i++)
- if (listmember (gids, cred->gids[i], ngids))
- newgids[newngids++] = cred->gids[i];
-
+
+ err = iohelp_restrict_iouser (&user, cred->user, uids, nuids, gids, ngids);
+ if (err)
+ return err;
+
mutex_lock (&cred->po->np->lock);
- err = diskfs_create_protid (cred->po, newuids, newnuids, newgids, newngids,
- &newpi);
+ err = diskfs_create_protid (cred->po, user, &newpi);
if (! err)
{
*newport = ports_get_right (newpi);
@@ -68,5 +50,6 @@ diskfs_S_io_restrict_auth (struct protid *cred,
}
mutex_unlock (&cred->po->np->lock);
+ iohelp_free_iouser (user);
return err;
}
diff --git a/libdiskfs/io-interrupt.c b/libdiskfs/io-revoke.c
index 2d2e4c61..d42fb6c1 100644
--- a/libdiskfs/io-interrupt.c
+++ b/libdiskfs/io-revoke.c
@@ -1,5 +1,6 @@
-/*
- Copyright (C) 1994 Free Software Foundation
+/*
+ Copyright (C) 1999 Free Software Foundation
+ Written by Thomas Bushnell, BSG.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -18,12 +19,41 @@
#include "priv.h"
#include "io_S.h"
-/* Implement io_interrupt as described in <hurd/io.defs>. */
-error_t
-S_io_interrupt (struct protid *cred)
+/* Implement io_revoke as described in <hurd/io.defs>. */
+kern_return_t
+diskfs_S_io_revoke (struct protid *cred)
{
+ error_t err;
+ struct node *np;
+
+ error_t
+ iterator_function (void *port)
+ {
+ struct protid *user = port;
+
+ if ((user != cred)
+ && (user->po->np == np))
+ ports_destroy_right (user);
+ return 0;
+ }
+
if (!cred)
return EOPNOTSUPP;
-
+
+ np = cred->po->np;
+
+ mutex_lock (&np->lock);
+
+ err = fshelp_isowner (&np->dn_stat, cred->user);
+
+ mutex_unlock (&np->lock);
+
+ if (err)
+ return err;
+
+ ports_inhibit_bucket_rpcs (diskfs_port_bucket);
+ ports_class_iterate (diskfs_protid_class, iterator_function);
+ ports_resume_bucket_rpcs (diskfs_port_bucket);
+
return 0;
}
diff --git a/libdiskfs/io-seek.c b/libdiskfs/io-seek.c
index 33aa77d4..71179816 100644
--- a/libdiskfs/io-seek.c
+++ b/libdiskfs/io-seek.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+/*
+ Copyright (C) 1994,1995,1996,2000,2006 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
@@ -19,9 +19,6 @@
#include "io_S.h"
#include <unistd.h>
-#define diskfs_readonly 0
-#define diskfs_synchronous 0
-
/* Implement io_seek as described in <hurd/io.defs>. */
kern_return_t
diskfs_S_io_seek (struct protid *cred,
@@ -29,29 +26,36 @@ diskfs_S_io_seek (struct protid *cred,
int whence,
off_t *newoffset)
{
-
- CHANGE_NODE_FIELD (cred,
- ({
- iohelp_get_conch (&np->conch);
- switch (whence)
- {
- case SEEK_SET:
- err = 0;
- cred->po->filepointer = offset;
- break;
- case SEEK_CUR:
- err = 0;
- cred->po->filepointer += offset;
- break;
- case SEEK_END:
- err = 0;
- cred->po->filepointer = (np->dn_stat.st_size
- + offset);
- break;
- default:
- err = EINVAL;
- break;
- }
- *newoffset = cred->po->filepointer;
- }));
+ error_t err = 0;
+ struct node *np;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ np = cred->po->np;
+
+ mutex_lock (&np->lock);
+
+ iohelp_get_conch (&np->conch);
+ switch (whence)
+ {
+ case SEEK_CUR:
+ offset += cred->po->filepointer;
+ goto check;
+ case SEEK_END:
+ offset += np->dn_stat.st_size;
+ case SEEK_SET:
+ check:
+ if (offset >= 0)
+ {
+ *newoffset = cred->po->filepointer = offset;
+ break;
+ }
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ mutex_unlock (&np->lock);
+ return err;
}
diff --git a/libdiskfs/io-stat.c b/libdiskfs/io-stat.c
index df8b4291..59f3187e 100644
--- a/libdiskfs/io-stat.c
+++ b/libdiskfs/io-stat.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+/*
+ Copyright (C) 1994,95,96,97,2001 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
@@ -28,15 +28,24 @@ diskfs_S_io_stat (struct protid *cred,
if (!cred)
return EOPNOTSUPP;
-
+
np = cred->po->np;
mutex_lock (&np->lock);
+
iohelp_get_conch (&np->conch);
if (diskfs_synchronous)
diskfs_node_update (np, 1);
else
diskfs_set_node_times (np);
- bcopy (&np->dn_stat, statbuf, sizeof (struct stat));
+
+ memcpy (statbuf, &np->dn_stat, sizeof (struct stat));
+ statbuf->st_mode &= ~(S_IATRANS | S_IROOT);
+ if (fshelp_translated (&np->transbox))
+ statbuf->st_mode |= S_IATRANS;
+ if (cred->po->shadow_root == np || np == diskfs_root_node)
+ statbuf->st_mode |= S_IROOT;
+
mutex_unlock (&np->lock);
+
return 0;
}
diff --git a/libdiskfs/io-version.c b/libdiskfs/io-version.c
index a1f12d79..b19dd0d1 100644
--- a/libdiskfs/io-version.c
+++ b/libdiskfs/io-version.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 1996 Free Software Foundation
This file is part of the GNU Hurd.
@@ -19,6 +19,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Michael I. Bushnell. */
+#include <stdio.h>
+
#include "priv.h"
#include "io_S.h"
@@ -31,10 +33,8 @@ diskfs_S_io_server_version (struct protid *cred,
{
if (cred)
{
- strcpy (server_name, diskfs_server_name);
- *major = diskfs_major_version;
- *minor = diskfs_minor_version;
- *edit = diskfs_edit_version;
+ snprintf (server_name, sizeof (string_t), "%s %s",
+ diskfs_server_name, diskfs_server_version);
return 0;
}
else
diff --git a/libdiskfs/io-write.c b/libdiskfs/io-write.c
index 8b68e1a1..a3c4199e 100644
--- a/libdiskfs/io-write.c
+++ b/libdiskfs/io-write.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1994,95,96,97,2001 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
@@ -29,7 +29,7 @@ diskfs_S_io_write (struct protid *cred,
{
struct node *np;
error_t err;
- int off = offset;
+ off_t off = offset;
if (!cred)
return EOPNOTSUPP;
@@ -50,6 +50,11 @@ diskfs_S_io_write (struct protid *cred,
cred->po->filepointer = np->dn_stat.st_size;
off = cred->po->filepointer;
}
+ if (off < 0)
+ {
+ err = EINVAL;
+ goto out;
+ }
err = 0;
while (off + (off_t) datalen > np->allocsize)
@@ -59,6 +64,8 @@ diskfs_S_io_write (struct protid *cred,
diskfs_node_update (np, 1);
if (err)
goto out;
+ if (np->filemod_reqs)
+ diskfs_notice_filechange (np, FILE_CHANGED_EXTEND, 0, off + datalen);
}
if (off + (off_t) datalen > np->dn_stat.st_size)
@@ -79,6 +86,8 @@ diskfs_S_io_write (struct protid *cred,
&& ((cred->po->openstat & O_FSYNC) || diskfs_synchronous))
diskfs_file_update (np, 1);
+ if (!err && np->filemod_reqs)
+ diskfs_notice_filechange (np, FILE_CHANGED_WRITE, off, off + *amt);
out:
mutex_unlock (&np->lock);
return err;
diff --git a/libdiskfs/lithp.h b/libdiskfs/lithp.h
index fa312fd2..be56377d 100644
--- a/libdiskfs/lithp.h
+++ b/libdiskfs/lithp.h
@@ -22,9 +22,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Hmm. */
#define dithkfth_TH_file_chauthor diskfs_S_file_chauthor
-#define dithkfth_ithowner diskfs_isowner
+#define fthhelp_ithowner fshelp_isowner
#define dithkfth_validate_author_change diskfs_validate_author_change
#define dn_thtat dn_stat
#define tht_author st_author
#define dn_thet_theetime dn_set_ctime
#define fth_TH_dot_h "fs_S.h"
+#define uther user
diff --git a/libdiskfs/lookup.c b/libdiskfs/lookup.c
index 40ce8937..1f2a2588 100644
--- a/libdiskfs/lookup.c
+++ b/libdiskfs/lookup.c
@@ -1,5 +1,5 @@
/* Wrapper for diskfs_lookup_hard
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -19,11 +19,28 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include "priv.h"
+#include <string.h>
+
+static struct
+{
+ int present;
+ int absent;
+ int errors;
+ int dot;
+ int dotdot;
+} cache_misses;
+static spin_lock_t cm_lock = SPIN_LOCK_INITIALIZER;
+
/* Lookup in directory DP (which is locked) the name NAME. TYPE will
either be LOOKUP, CREATE, RENAME, or REMOVE. CRED identifies the
user making the call.
+ NAME will have leading and trailing slashes stripped. It is an
+ error if there are internal slashes. NAME will be modified in
+ place if there are slashes in it; it is therefore an error to
+ specify a constant NAME which contains slashes.
+
If the name is found, return zero, and (if NP is nonzero) set *NP
to point to the node for it, locked. If the name is not found,
return ENOENT, and (if NP is nonzero) set *NP to zero. If NP is
@@ -62,16 +79,15 @@
Return ENOENT if NAME isn't in the directory.
Return EAGAIN if NAME refers to the `..' of this filesystem's root.
Return EIO if appropriate.
-
- This function is a wrapper for diskfs_lookup_hard.
-*/
-error_t
-diskfs_lookup (struct node *dp, char *name, enum lookup_type type,
- struct node **np, struct dirstat *ds,
- struct protid *cred)
+
+ This function is a wrapper for diskfs_lookup_hard. */
+error_t
+diskfs_lookup (struct node *dp, const char *name, enum lookup_type type,
+ struct node **np, struct dirstat *ds, struct protid *cred)
{
error_t err;
-
+ struct node *cached;
+
if (type == REMOVE || type == RENAME)
assert (np);
@@ -81,7 +97,37 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type,
diskfs_null_dirstat (ds);
return ENOTDIR;
}
- err = diskfs_access (dp, S_IEXEC, cred);
+
+ /* Strip leading and trailing slashes. */
+ while (*name == '/')
+ name++;
+
+ if (name[0] == '\0')
+ {
+ if (ds)
+ diskfs_null_dirstat (ds);
+ return EINVAL;
+ }
+ else
+ {
+ char *p = strchr (name, '/');
+ if (p != 0)
+ {
+ *p = '\0';
+ do
+ ++p;
+ while (*p == '/');
+ if (*p != '\0')
+ {
+ if (ds)
+ diskfs_null_dirstat (ds);
+ return EINVAL;
+ }
+ }
+ }
+
+
+ err = fshelp_access (&dp->dn_stat, S_IEXEC, cred->user);
if (err)
{
if (ds)
@@ -89,55 +135,100 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type,
return err;
}
+ if (dp == cred->po->shadow_root
+ && name[0] == '.' && name[1] == '.' && name[2] == '\0')
+ /* Ran into the root. */
+ {
+ if (ds)
+ diskfs_null_dirstat (ds);
+ return EAGAIN;
+ }
+
if (type == LOOKUP)
+ /* Check the cache first */
+ cached = diskfs_check_lookup_cache (dp, name);
+ else
+ cached = 0;
+
+ if (cached == (struct node *)-1)
+ /* Negative lookup cached. */
+ {
+ if (np)
+ *np = 0;
+ return ENOENT;
+ }
+ else if (cached)
{
- /* Check the cache first */
- struct node *cached = diskfs_check_lookup_cache (dp, name);
+ if (np)
+ *np = cached; /* Return what we found. */
+ else
+ /* Ick, the user doesn't want the result, we have to drop our
+ reference. */
+ if (cached == dp)
+ diskfs_nrele (cached);
+ else
+ diskfs_nput (cached);
- if (cached == (struct node *)-1)
- /* Negative lookup cached. */
- {
- if (np)
- *np = 0;
- return ENOENT;
- }
- else if (cached)
+ if (ds)
+ diskfs_null_dirstat (ds);
+ }
+ else
+ {
+ err = diskfs_lookup_hard (dp, name, type, np, ds, cred);
+
+ spin_lock (&cm_lock);
+ if (type == LOOKUP)
{
- if (np)
- *np = cached; /* Return what we found. */
+ if (err == ENOENT)
+ cache_misses.absent++;
+ else if (err)
+ cache_misses.errors++;
else
- /* Ick, the user doesn't want the result, we have to drop our
- reference. */
- if (cached == dp)
- diskfs_nrele (cached);
- else
- diskfs_nput (cached);
- if (ds)
- diskfs_null_dirstat (ds);
- return 0;
+ cache_misses.present++;
+ if (name[0] == '.')
+ {
+ if (name[1] == '\0')
+ cache_misses.dot++;
+ else if (name[1] == '.' && name[2] == '\0')
+ cache_misses.dotdot++;
+ }
}
- }
-
- err = diskfs_lookup_hard (dp, name, type, np, ds, cred);
- if (err && err != ENOENT)
- return err;
-
- if (type == RENAME
- || (type == CREATE && err == ENOENT)
- || (type == REMOVE && err != ENOENT))
- {
- error_t err2 = diskfs_checkdirmod (dp, (err || !np) ? 0 : *np, cred);
- if (err2)
+ spin_unlock (&cm_lock);
+
+ if (err && err != ENOENT)
+ return err;
+
+ if (type == RENAME
+ || (type == CREATE && err == ENOENT)
+ || (type == REMOVE && err != ENOENT))
{
- if (np && !err)
- diskfs_nput (*np);
- return err2;
+ error_t err2;
+
+ if (diskfs_name_max > 0 && strlen (name) > diskfs_name_max)
+ err2 = ENAMETOOLONG;
+ else
+ err2 = fshelp_checkdirmod (&dp->dn_stat,
+ (err || !np) ? 0 : &(*np)->dn_stat,
+ cred->user);
+ if (err2)
+ {
+ if (np && !err)
+ {
+ if (*np == dp)
+ diskfs_nrele (*np);
+ else
+ diskfs_nput (*np);
+ *np = 0;
+ }
+ return err2;
+ }
}
+
+ if ((type == LOOKUP || type == CREATE) && !err && np)
+ diskfs_enter_lookup_cache (dp, *np, name);
+ else if (type == LOOKUP && err == ENOENT)
+ diskfs_enter_lookup_cache (dp, 0, name);
}
- if ((type == LOOKUP || type == CREATE) && !err && np)
- diskfs_enter_lookup_cache (dp, *np, name);
-
return err;
}
-
diff --git a/libdiskfs/machdev.c b/libdiskfs/machdev.c
deleted file mode 100644
index 786bf0ab..00000000
--- a/libdiskfs/machdev.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Get mach device info
-
- 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 <stdio.h>
-
-#include <device/device.h>
-
-#include "priv.h"
-
-/* Returns a send right to for the mach device called NAME, and returns it in
- PORT. Other values returned are START, the first valid offset, SIZE, the
- the number of blocks after START, and BLOCK_SIZE, the units in which the
- device is addressed.
-
- The device is opened for reading, and if the diskfs global variable
- DISKFS_READ_ONLY is false, writing.
-
- If NAME cannot be opened and this is a bootstrap filename, the user will
- be prompted for new names until a valid one is found. */
-error_t
-diskfs_get_mach_device (char *name,
- mach_port_t *port,
- off_t *start, off_t *size, size_t *block_size)
-{
- error_t err = 0;
-
- do
- {
- mach_port_t dev_master;
-
- err = get_privileged_ports (0, &dev_master);
- if (err)
- return err;
-
- err = device_open (dev_master,
- (diskfs_readonly ? 0 : D_WRITE) | D_READ,
- name, port);
-
- if (err == D_NO_SUCH_DEVICE && diskfs_boot_flags)
- /* If this is a bootstrap filesystem, prompt the user to give us
- another name rather than just crashing. */
- {
- char *line = 0;
- size_t linesz = 0;
- ssize_t len;
-
- printf ("Cannot open device %s\n", name);
- printf ("Open instead: ");
- fflush (stdout);
- len = getline (&line, &linesz, stdin);
- if (len > 2)
- name = line;
- }
-
- mach_port_deallocate (mach_task_self (), dev_master);
- }
- while (err == D_NO_SUCH_DEVICE && diskfs_boot_flags);
-
- if (!err)
- {
- unsigned sizes_len = DEV_GET_SIZE_COUNT;
- size_t sizes[DEV_GET_SIZE_COUNT];
-
- err = device_get_status (*port, DEV_GET_SIZE, sizes, &sizes_len);
- assert (sizes_len == DEV_GET_SIZE_COUNT);
-
- *start = 0;
- *size = sizes[DEV_GET_SIZE_DEVICE_SIZE];
- *block_size = sizes[DEV_GET_SIZE_RECORD_SIZE];
- if (*block_size > 1)
- *size /= *block_size;
- }
-
- return err;
-}
diff --git a/libdiskfs/name-cache.c b/libdiskfs/name-cache.c
index 2cf1ed8b..f31482d4 100644
--- a/libdiskfs/name-cache.c
+++ b/libdiskfs/name-cache.c
@@ -1,6 +1,6 @@
/* Directory name lookup caching
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG, & Miles Bader.
This file is part of the GNU Hurd.
@@ -24,7 +24,7 @@
#include <cacheq.h>
/* Maximum number of names to cache at once */
-#define MAXCACHE 256
+#define MAXCACHE 200
/* Maximum length of file name we bother caching */
#define CACHE_NAME_LEN 100
@@ -44,7 +44,10 @@ struct lookup_cache
char name[CACHE_NAME_LEN];
/* Strlen of NAME. If this is zero, it's an unused entry. */
- size_t name_len;
+ size_t name_len;
+
+ /* XXX */
+ int stati;
};
/* The contents of the cache in no particular order */
@@ -53,28 +56,39 @@ static struct cacheq lookup_cache = { sizeof (struct lookup_cache) };
static spin_lock_t cache_lock = SPIN_LOCK_INITIALIZER;
/* Buffer to hold statistics */
-static struct
+static struct stats
{
long pos_hits;
long neg_hits;
long miss;
long fetch_errors;
} statistics;
+
+#define PARTIAL_THRESH 100
+#define NPARTIALS MAXCACHE / PARTIAL_THRESH
+struct stats partial_stats [NPARTIALS];
+
/* If there's an entry for NAME, of length NAME_LEN, in directory DIR in the
- cache, return it's entry, otherwise 0. CACHE_LOCK must be held. */
+ cache, return its entry, otherwise 0. CACHE_LOCK must be held. */
static struct lookup_cache *
find_cache (struct node *dir, const char *name, size_t name_len)
{
struct lookup_cache *c;
+ int i;
/* Search the list. All unused entries are contiguous at the end of the
list, so we can stop searching when we see the first one. */
- for (c = lookup_cache.mru; c && c->name_len; c = c->hdr.next)
+ for (i = 0, c = lookup_cache.mru;
+ c && c->name_len;
+ c = c->hdr.next, i++)
if (c->name_len == name_len
&& c->dir_cache_id == dir->cache_id
&& c->name[0] == name[0] && strcmp (c->name, name) == 0)
- return c;
+ {
+ c->stati = i / 100;
+ return c;
+ }
return 0;
}
@@ -82,19 +96,12 @@ find_cache (struct node *dir, const char *name, size_t name_len)
/* Node NP has just been found in DIR with NAME. If NP is null, that
means that this name has been confirmed as absent in the directory. */
void
-diskfs_enter_lookup_cache (struct node *dir, struct node *np, char *name)
+diskfs_enter_lookup_cache (struct node *dir, struct node *np, const char *name)
{
struct lookup_cache *c;
size_t name_len = strlen (name);
-
- if (name_len > CACHE_NAME_LEN - 1)
- return;
- /* Never cache . or ..; it's too much trouble to get the locking
- order right. */
- if (name[0] == '.'
- && (name[1] == '\0'
- || (name[1] == '.' && name[2] == '\0')))
+ if (name_len > CACHE_NAME_LEN - 1)
return;
spin_lock (&cache_lock);
@@ -120,13 +127,13 @@ diskfs_enter_lookup_cache (struct node *dir, struct node *np, char *name)
spin_unlock (&cache_lock);
}
-/* Purge all references in the cache to NP as a node inside
+/* Purge all references in the cache to NP as a node inside
directory DP. */
void
diskfs_purge_lookup_cache (struct node *dp, struct node *np)
{
struct lookup_cache *c, *next;
-
+
spin_lock (&cache_lock);
for (c = lookup_cache.mru; c; c = next)
{
@@ -145,15 +152,56 @@ diskfs_purge_lookup_cache (struct node *dp, struct node *np)
spin_unlock (&cache_lock);
}
+/* Register a negative hit for an entry in the Nth stat class */
+void
+register_neg_hit (int n)
+{
+ int i;
+
+ statistics.neg_hits++;
+
+ for (i = 0; i < n; i++)
+ partial_stats[i].miss++;
+ for (; i < NPARTIALS; i++)
+ partial_stats[i].neg_hits++;
+}
+
+/* Register a positive hit for an entry in the Nth stat class */
+void
+register_pos_hit (int n)
+{
+ int i;
+
+ statistics.pos_hits++;
+
+ for (i = 0; i < n; i++)
+ partial_stats[i].miss++;
+ for (; i < NPARTIALS; i++)
+ partial_stats[i].pos_hits++;
+}
+
+/* Register a miss */
+void
+register_miss ()
+{
+ int i;
+
+ statistics.miss++;
+ for (i = 0; i < NPARTIALS; i++)
+ partial_stats[i].miss++;
+}
+
+
+
/* Scan the cache looking for NAME inside DIR. If we don't know
anything entry at all, then return 0. If the entry is confirmed to
not exist, then return -1. Otherwise, return NP for the entry, with
a newly allocated reference. */
struct node *
-diskfs_check_lookup_cache (struct node *dir, char *name)
+diskfs_check_lookup_cache (struct node *dir, const char *name)
{
struct lookup_cache *c;
-
+
spin_lock (&cache_lock);
c = find_cache (dir, name, strlen (name));
@@ -163,15 +211,18 @@ diskfs_check_lookup_cache (struct node *dir, char *name)
cacheq_make_mru (&lookup_cache, c); /* Record C as recently used. */
- statistics.pos_hits++;
- spin_unlock (&cache_lock);
-
if (id == 0)
/* A negative cache entry. */
- return (struct node *)-1;
+ {
+ register_neg_hit (c->stati);
+ spin_unlock (&cache_lock);
+ return (struct node *)-1;
+ }
else if (id == dir->cache_id)
/* The cached node is the same as DIR. */
{
+ register_pos_hit (c->stati);
+ spin_unlock (&cache_lock);
diskfs_nref (dir);
return dir;
}
@@ -179,12 +230,35 @@ diskfs_check_lookup_cache (struct node *dir, char *name)
/* Just a normal entry in DIR; get the actual node. */
{
struct node *np;
- error_t err = diskfs_cached_lookup (id, &np);
+ error_t err;
+
+ register_pos_hit (c->stati);
+ spin_unlock (&cache_lock);
+
+ if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
+ {
+ mutex_unlock (&dir->lock);
+ err = diskfs_cached_lookup (id, &np);
+ mutex_lock (&dir->lock);
+
+ /* In the window where DP was unlocked, we might
+ have lost. So check the cache again, and see
+ if it's still there; if so, then we win. */
+ c = find_cache (dir, "..", 2);
+ if (!c || c->node_cache_id != id)
+ {
+ /* Lose */
+ mutex_unlock (&np->lock);
+ return 0;
+ }
+ }
+ else
+ err = diskfs_cached_lookup (id, &np);
return err ? 0 : np;
}
}
-
- statistics.miss++;
+
+ register_miss ();
spin_unlock (&cache_lock);
return 0;
diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c
index 3f8dc4c1..4a7d108d 100644
--- a/libdiskfs/node-create.c
+++ b/libdiskfs/node-create.c
@@ -1,5 +1,5 @@
/* Making new files
- Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation
+ Copyright (C) 1992,93,94,96,98,2001 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,6 +17,11 @@
#include "priv.h"
+/* This enables SysV style group behaviour. New nodes inherit the GID
+ of the user creating them unless the SGID bit is set of the parent
+ directory. */
+int _diskfs_no_inherit_dir_group;
+
/* Create a new node. Give it MODE; if that includes IFDIR, also
initialize `.' and `..' in the new directory. Return the node in NPP.
CRED identifies the user responsible for the call. If NAME is nonzero,
@@ -26,7 +31,7 @@
strategies. */
error_t
diskfs_create_node (struct node *dir,
- char *name,
+ const char *name,
mode_t mode,
struct node **newnode,
struct protid *cred,
@@ -36,9 +41,12 @@ diskfs_create_node (struct node *dir,
error_t err;
uid_t newuid;
gid_t newgid;
-
+
if (diskfs_check_readonly ())
- return EROFS;
+ {
+ *newnode = NULL;
+ return EROFS;
+ }
/* Make the node */
err = diskfs_alloc_node (dir, mode, newnode);
@@ -46,14 +54,15 @@ diskfs_create_node (struct node *dir,
{
if (name)
diskfs_drop_dirstat (dir, ds);
+ *newnode = NULL;
return err;
}
np = *newnode;
/* Initialize the on-disk fields. */
- if (cred->nuids)
- newuid = cred->uids[0];
+ if (cred->user->uids->num)
+ newuid = cred->user->uids->ids[0];
else
{
newuid = dir->dn_stat.st_uid;
@@ -63,16 +72,43 @@ diskfs_create_node (struct node *dir,
if (err)
goto change_err;
np->dn_stat.st_uid = newuid;
+ if (np->author_tracks_uid)
+ np->dn_stat.st_author = newuid;
- if (diskfs_groupmember (dir->dn_stat.st_gid, cred))
- newgid = dir->dn_stat.st_gid;
- else if (cred->ngids)
- newgid = cred->gids[0];
- else
+ if (!_diskfs_no_inherit_dir_group)
{
newgid = dir->dn_stat.st_gid;
- mode &= ~S_ISGID;
+ if (!idvec_contains (cred->user->gids, newgid))
+ mode &= ~S_ISGID;
+ }
+ else
+ {
+ if (dir->dn_stat.st_mode & S_ISGID)
+ {
+ /* If the parent dir has the sgid bit set, inherit its gid.
+ If the new node is a directory, also inherit the sgid bit
+ set. */
+ newgid = dir->dn_stat.st_gid;
+ if (S_ISDIR (mode))
+ mode |= S_ISGID;
+ else
+ {
+ if (!idvec_contains (cred->user->gids, newgid))
+ mode &= ~S_ISGID;
+ }
+ }
+ else
+ {
+ if (cred->user->gids->num)
+ newgid = cred->user->gids->ids[0];
+ else
+ {
+ newgid = dir->dn_stat.st_gid;
+ mode &= ~S_ISGID;
+ }
+ }
}
+
err = diskfs_validate_group_change (np, newgid);
if (err)
goto change_err;
@@ -94,7 +130,7 @@ diskfs_create_node (struct node *dir,
if (S_ISDIR (mode))
err = diskfs_init_dir (np, dir, cred);
-
+
diskfs_node_update (np, 1);
if (err)
@@ -104,9 +140,10 @@ diskfs_create_node (struct node *dir,
np->dn_stat.st_nlink = 0;
if (name)
diskfs_drop_dirstat (dir, ds);
+ *newnode = NULL;
return err;
}
-
+
if (name)
{
err = diskfs_direnter (dir, name, np, ds, cred);
@@ -119,5 +156,8 @@ diskfs_create_node (struct node *dir,
diskfs_nput (np);
}
}
+ if (err)
+ *newnode = NULL;
+
return err;
}
diff --git a/libdiskfs/node-drop.c b/libdiskfs/node-drop.c
index d24bd86d..f44966ba 100644
--- a/libdiskfs/node-drop.c
+++ b/libdiskfs/node-drop.c
@@ -17,6 +17,20 @@
#include "priv.h"
+/* Free the list of modification requests MR */
+static void
+free_modreqs (struct modreq *mr)
+{
+ struct modreq *tmp;
+ for (; mr; mr = tmp)
+ {
+ mach_port_deallocate (mach_task_self (), mr->port);
+ tmp = mr->next;
+ free (mr);
+ }
+}
+
+
/* Node NP now has no more references; clean all state. The
diskfs_node_refcnt_lock must be held, and will be released
upon return. NP must be locked. */
@@ -30,7 +44,7 @@ diskfs_drop_node (struct node *np)
diskfs_check_readonly ();
assert (!diskfs_readonly);
- if (np->istranslated)
+ if (np->dn_stat.st_mode & S_IPTRANS)
diskfs_set_translator (np, 0, 0, 0);
if (np->allocsize != 0
@@ -73,15 +87,9 @@ diskfs_drop_node (struct node *np)
fshelp_drop_transbox (&np->transbox);
if (np->dirmod_reqs)
- {
- struct dirmod *dm, *tmp;
- for (dm = np->dirmod_reqs; dm; dm = tmp)
- {
- mach_port_deallocate (mach_task_self (), dm->port);
- tmp = dm->next;
- free (dm);
- }
- }
+ free_modreqs (np->dirmod_reqs);
+ if (np->filemod_reqs)
+ free_modreqs (np->filemod_reqs);
assert (!np->sockaddr);
diff --git a/libdiskfs/node-make.c b/libdiskfs/node-make.c
index 972167a2..74fdda19 100644
--- a/libdiskfs/node-make.c
+++ b/libdiskfs/node-make.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+/*
+ Copyright (C) 1994,95,96,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
@@ -25,13 +25,16 @@ struct node *
diskfs_make_node (struct disknode *dn)
{
struct node *np = malloc (sizeof (struct node));
-
+
+ if (np == 0)
+ return 0;
+
np->dn = dn;
np->dn_set_ctime = 0;
np->dn_set_atime = 0;
np->dn_set_mtime = 0;
np->dn_stat_dirty = 0;
-
+
mutex_init (&np->lock);
np->references = 1;
np->light_references = 0;
@@ -39,11 +42,13 @@ diskfs_make_node (struct disknode *dn)
np->sockaddr = MACH_PORT_NULL;
np->dirmod_reqs = 0;
-
+ np->dirmod_tick = 0;
+ np->filemod_reqs = 0;
+ np->filemod_tick = 0;
+
fshelp_transbox_init (&np->transbox, &np->lock, np);
iohelp_initialize_conch (&np->conch, &np->lock);
fshelp_lock_init (&np->userlock);
-
return np;
}
diff --git a/libdiskfs/node-nput.c b/libdiskfs/node-nput.c
new file mode 100644
index 00000000..2aad1b66
--- /dev/null
+++ b/libdiskfs/node-nput.c
@@ -0,0 +1,75 @@
+/*
+ Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, 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"
+
+/* Unlock node NP and release a hard reference; if this is the last
+ hard reference and there are no links to the file then request
+ weak references to be dropped. */
+void
+diskfs_nput (struct node *np)
+{
+ int tried_drop_softrefs = 0;
+
+ loop:
+ spin_lock (&diskfs_node_refcnt_lock);
+ assert (np->references);
+ np->references--;
+ if (np->references + np->light_references == 0)
+ diskfs_drop_node (np);
+ else if (np->references == 0 && !tried_drop_softrefs)
+ {
+ spin_unlock (&diskfs_node_refcnt_lock);
+
+ /* This is our cue that something akin to "last process closes file"
+ in the POSIX.1 sense happened, so make sure any pending node time
+ updates now happen in a timely fashion. */
+ diskfs_set_node_times (np);
+
+ diskfs_lost_hardrefs (np);
+ if (!np->dn_stat.st_nlink)
+ {
+ /* There are no links. If there are soft references that
+ can be dropped, we can't let them postpone deallocation.
+ So attempt to drop them. But that's a user-supplied
+ routine, which might result in further recursive calls to
+ the ref-counting system. So we have to reacquire our
+ reference around the call to forestall disaster. */
+ spin_lock (&diskfs_node_refcnt_lock);
+ np->references++;
+ spin_unlock (&diskfs_node_refcnt_lock);
+
+ diskfs_try_dropping_softrefs (np);
+
+ /* But there's no value in looping forever in this
+ routine; only try to drop soft refs once. */
+ tried_drop_softrefs = 1;
+
+ /* Now we can drop the reference back... */
+ goto loop;
+ }
+ mutex_unlock (&np->lock);
+ }
+ else
+ {
+ spin_unlock (&diskfs_node_refcnt_lock);
+ mutex_unlock (&np->lock);
+ }
+}
diff --git a/libdiskfs/node-nputl.c b/libdiskfs/node-nputl.c
new file mode 100644
index 00000000..45b109ea
--- /dev/null
+++ b/libdiskfs/node-nputl.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, 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"
+
+/* Unlock node NP and release a light reference */
+void
+diskfs_nput_light (struct node *np)
+{
+ spin_lock (&diskfs_node_refcnt_lock);
+ assert (np->light_references);
+ np->light_references--;
+ if (np->references + np->light_references == 0)
+ diskfs_drop_node (np);
+ else
+ {
+ spin_unlock (&diskfs_node_refcnt_lock);
+ mutex_unlock (&np->lock);
+ }
+}
diff --git a/libdiskfs/node-nref.c b/libdiskfs/node-nref.c
new file mode 100644
index 00000000..753de65f
--- /dev/null
+++ b/libdiskfs/node-nref.c
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, 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"
+
+/* Add a hard reference to a node. If there were no hard
+ references previously, then the node cannot be locked
+ (because you must hold a hard reference to hold the lock). */
+void
+diskfs_nref (struct node *np)
+{
+ int new_hardref;
+ spin_lock (&diskfs_node_refcnt_lock);
+ np->references++;
+ new_hardref = (np->references == 1);
+ spin_unlock (&diskfs_node_refcnt_lock);
+ if (new_hardref)
+ {
+ mutex_lock (&np->lock);
+ diskfs_new_hardrefs (np);
+ mutex_unlock (&np->lock);
+ }
+}
diff --git a/libdiskfs/opts-runtime-parse.c b/libdiskfs/node-nrefl.c
index 00ec2fc0..ce3b39dd 100644
--- a/libdiskfs/opts-runtime-parse.c
+++ b/libdiskfs/node-nrefl.c
@@ -1,6 +1,6 @@
-/* A default diskfs_parse_runtime_options routine
-
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/*
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, BSG.
This file is part of the GNU Hurd.
@@ -16,15 +16,15 @@
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. */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include "priv.h"
-error_t
-diskfs_parse_runtime_options (int argc, char **argv,
- const struct argp *standard_argp)
+/* Add a light reference to a node. */
+void
+diskfs_nref_light (struct node *np)
{
- return argp_parse (standard_argp, argc, argv,
- ARGP_NO_ERRS | ARGP_NO_HELP | ARGP_PARSE_ARGV0,
- 0, 0);
+ spin_lock (&diskfs_node_refcnt_lock);
+ np->light_references++;
+ spin_unlock (&diskfs_node_refcnt_lock);
}
diff --git a/libdiskfs/node-nrele.c b/libdiskfs/node-nrele.c
new file mode 100644
index 00000000..9dbc5d8c
--- /dev/null
+++ b/libdiskfs/node-nrele.c
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, 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"
+
+/* Release a hard reference on NP. If NP is locked by anyone, then
+ this cannot be the last hard reference (because you must hold a
+ hard reference in order to hold the lock). If this is the last
+ hard reference and there are no links, then request soft references
+ to be dropped. */
+void
+diskfs_nrele (struct node *np)
+{
+ int tried_drop_softrefs = 0;
+
+ loop:
+ spin_lock (&diskfs_node_refcnt_lock);
+ assert (np->references);
+ np->references--;
+ if (np->references + np->light_references == 0)
+ {
+ mutex_lock (&np->lock);
+ diskfs_drop_node (np);
+ }
+ else if (np->references == 0)
+ {
+ mutex_lock (&np->lock);
+ spin_unlock (&diskfs_node_refcnt_lock);
+ diskfs_lost_hardrefs (np);
+ if (!np->dn_stat.st_nlink && !tried_drop_softrefs)
+ {
+ /* Same issue here as in nput; see that for explanation */
+ spin_lock (&diskfs_node_refcnt_lock);
+ np->references++;
+ spin_unlock (&diskfs_node_refcnt_lock);
+
+ diskfs_try_dropping_softrefs (np);
+ tried_drop_softrefs = 1;
+
+ /* Now we can drop the reference back... */
+ mutex_unlock (&np->lock);
+ goto loop;
+ }
+ mutex_unlock (&np->lock);
+ }
+ else
+ spin_unlock (&diskfs_node_refcnt_lock);
+}
diff --git a/libdiskfs/node-nrelel.c b/libdiskfs/node-nrelel.c
new file mode 100644
index 00000000..e61f6378
--- /dev/null
+++ b/libdiskfs/node-nrelel.c
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, 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"
+
+/* Release a light reference on NP. If NP is locked by anyone, then
+ this cannot be the last reference (because you must hold a
+ hard reference in order to hold the lock). */
+void
+diskfs_nrele_light (struct node *np)
+{
+ spin_lock (&diskfs_node_refcnt_lock);
+ assert (np->light_references);
+ np->light_references--;
+ if (np->references + np->light_references == 0)
+ {
+ mutex_lock (&np->lock);
+ diskfs_drop_node (np);
+ }
+ else
+ spin_unlock (&diskfs_node_refcnt_lock);
+}
diff --git a/libdiskfs/node-rdwr.c b/libdiskfs/node-rdwr.c
index 319a985c..ed94df44 100644
--- a/libdiskfs/node-rdwr.c
+++ b/libdiskfs/node-rdwr.c
@@ -45,6 +45,8 @@ diskfs_node_rdwr (struct node *np,
err = diskfs_grow (np, off + amt, cred);
if (err)
return err;
+ if (np->filemod_reqs)
+ diskfs_notice_filechange (np, FILE_CHANGED_EXTEND, 0, off + amt);
}
if (off + amt > np->dn_stat.st_size)
diff --git a/libdiskfs/node-times.c b/libdiskfs/node-times.c
index 720c85e0..67f0142e 100644
--- a/libdiskfs/node-times.c
+++ b/libdiskfs/node-times.c
@@ -1,5 +1,7 @@
-/*
- Copyright (C) 1994, 1996 Free Software Foundation
+/* Process st_?tim updates marked for a diskfs node.
+
+ Copyright (C) 1994, 1996, 1999, 2000, 2007, 2009 Free Software Foundation,
+ Inc.
This file is part of the GNU Hurd.
@@ -8,7 +10,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.
@@ -22,47 +24,51 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "priv.h"
#include <maptime.h>
-/* If NP->dn_set_ctime is set, then modify NP->dn_stat.st_ctime
+/* If disk is not readonly and the noatime option is not enabled, set
+ NP->dn_set_atime. */
+void
+diskfs_set_node_atime (struct node *np)
+{
+ if (!_diskfs_noatime && !diskfs_check_readonly ())
+ np->dn_set_atime = 1;
+}
+
+/* If NP->dn_set_ctime is set, then modify NP->dn_stat.st_ctim
appropriately; do the analogous operation for atime and mtime as well. */
void
diskfs_set_node_times (struct node *np)
{
struct timeval t;
+ if (!np->dn_set_mtime && !np->dn_set_atime && !np->dn_set_ctime)
+ return;
+
maptime_read (diskfs_mtime, &t);
+ /* We are careful to test and reset each of these individually, so there
+ is no race condition where a dn_set_?time flag setting gets lost. It
+ is not a problem to have the kind of race where the flag is set after
+ we've tested it and done nothing--as long as the flag remains set so
+ the update will happen at the next call. */
if (np->dn_set_mtime)
{
-#ifdef notyet
- np->dn_stat.st_mtimespec.ts_sec = t.tv_sec;
- np->dn_stat.st_mtimespec.ts_nsec = t.tv_usec * 1000;
-#else
- np->dn_stat.st_mtime = t.tv_sec;
- np->dn_stat.st_mtime_usec = t.tv_usec;
-#endif
+ np->dn_stat.st_mtim.tv_sec = t.tv_sec;
+ np->dn_stat.st_mtim.tv_nsec = t.tv_usec * 1000;
+ np->dn_stat_dirty = 1;
+ np->dn_set_mtime = 0;
}
if (np->dn_set_atime)
{
-#ifdef notyet
- np->dn_stat.st_atimespec.ts_sec = t.tv_sec;
- np->dn_stat.st_atimespec.ts_nsec = t.tv_usec * 1000;
-#else
- np->dn_stat.st_atime = t.tv_sec;
- np->dn_stat.st_atime_usec = t.tv_usec;
-#endif
+ np->dn_stat.st_atim.tv_sec = t.tv_sec;
+ np->dn_stat.st_atim.tv_nsec = t.tv_usec * 1000;
+ np->dn_stat_dirty = 1;
+ np->dn_set_atime = 0;
}
if (np->dn_set_ctime)
{
-#ifdef notyet
- np->dn_stat.st_ctimespec.ts_sec = t.tv_sec;
- np->dn_stat.st_ctimespec.ts_nsec = t.tv_usec * 1000;
-#else
- np->dn_stat.st_ctime = t.tv_sec;
- np->dn_stat.st_ctime_usec = t.tv_usec;
-#endif
+ np->dn_stat.st_ctim.tv_sec = t.tv_sec;
+ np->dn_stat.st_ctim.tv_nsec = t.tv_usec * 1000;
+ np->dn_stat_dirty = 1;
+ np->dn_set_ctime = 0;
}
-
- if (np->dn_set_mtime || np->dn_set_atime || np->dn_set_ctime)
- np->dn_stat_dirty = 1;
- np->dn_set_mtime = np->dn_set_atime = np->dn_set_ctime = 0;
}
diff --git a/libdiskfs/notify-nosenders.c b/libdiskfs/notify-nosenders.c
deleted file mode 100644
index 7e6a504f..00000000
--- a/libdiskfs/notify-nosenders.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Copyright (C) 1994, 1995 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. */
-
-#include "priv.h"
-#include <hurd/pager.h>
-
-/* Called by the kernel when a port has no more senders. We arrange
- to have this sent to the port which is out of senders (NOTIFY). MSCOUNT
- is the make-send count of the port when the notification was generated;
- SEQNO is the sequence number of the message dequeue. */
-error_t
-diskfs_do_seqnos_mach_notify_no_senders (mach_port_t notify,
- mach_port_seqno_t seqno __attribute__ ((unused)),
- mach_port_mscount_t mscount)
-{
- struct port_info *pt;
-
- pt = ports_lookup_port (diskfs_port_bucket, notify, 0);
-
- ports_no_senders (pt, mscount);
-
- ports_port_deref (pt);
-
- return 0;
-}
diff --git a/libdiskfs/notify-stubs.c b/libdiskfs/notify-stubs.c
deleted file mode 100644
index a9177f81..00000000
--- a/libdiskfs/notify-stubs.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- Copyright (C) 1994, 1995 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. */
-
-#include "priv.h"
-
-error_t
-diskfs_do_seqnos_mach_notify_port_deleted (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
- mach_port_t name
- __attribute__ ((unused)))
-{
- return 0;
-}
-
-error_t
-diskfs_do_seqnos_mach_notify_msg_accepted (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
- mach_port_t name
- __attribute__ ((unused)))
-{
- return 0;
-}
-
-error_t
-diskfs_do_seqnos_mach_notify_port_destroyed (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
- mach_port_t name
- __attribute__ ((unused)))
-{
- return 0;
-}
-
-error_t
-diskfs_do_seqnos_mach_notify_send_once (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)))
-{
- return 0;
-}
-
-error_t
-diskfs_do_seqnos_mach_notify_dead_name (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
- mach_port_t name
- __attribute__ ((unused)))
-{
- return 0;
-}
diff --git a/libdiskfs/opts-append-std.c b/libdiskfs/opts-append-std.c
index 505752d5..b951bf93 100644
--- a/libdiskfs/opts-append-std.c
+++ b/libdiskfs/opts-append-std.c
@@ -1,8 +1,8 @@
/* Get standard diskfs run-time options
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96,97,98,99,2002 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -20,12 +20,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <stdio.h>
#include <argz.h>
#include "priv.h"
error_t
-diskfs_append_std_options (char **argz, unsigned *argz_len)
+diskfs_append_std_options (char **argz, size_t *argz_len)
{
error_t err;
extern int diskfs_sync_interval;
@@ -34,21 +35,32 @@ diskfs_append_std_options (char **argz, unsigned *argz_len)
err = argz_add (argz, argz_len, "--readonly");
else
err = argz_add (argz, argz_len, "--writable");
- if (err)
- return err;
- if (diskfs_synchronous)
- err = argz_add (argz, argz_len, "--sync");
- else if (diskfs_sync_interval == 0)
- err = argz_add (argz, argz_len, "--nosync");
- else
+ if (!err && _diskfs_nosuid)
+ err = argz_add (argz, argz_len, "--no-suid");
+ if (!err && _diskfs_noexec)
+ err = argz_add (argz, argz_len, "--no-exec");
+ if (!err && _diskfs_noatime)
+ err = argz_add (argz, argz_len, "--no-atime");
+ if (!err && _diskfs_no_inherit_dir_group)
+ err = argz_add (argz, argz_len, "--no-inherit-dir-group");
+
+ if (! err)
{
- char buf[80];
- sprintf (buf, "--sync=%d", diskfs_sync_interval);
- err = argz_add (argz, argz_len, buf);
+ if (diskfs_synchronous)
+ err = argz_add (argz, argz_len, "--sync");
+ else if (DEFAULT_SYNC_INTERVAL != diskfs_sync_interval)
+ {
+ if (diskfs_sync_interval == 0)
+ err = argz_add (argz, argz_len, "--no-sync");
+ else
+ {
+ char buf[80];
+ sprintf (buf, "--sync=%d", diskfs_sync_interval);
+ err = argz_add (argz, argz_len, buf);
+ }
+ }
}
- if (err)
- free (argz); /* Free the first option allocated. */
return err;
}
diff --git a/libdiskfs/opts-common.c b/libdiskfs/opts-common.c
index 5d94f7b4..d37c2868 100644
--- a/libdiskfs/opts-common.c
+++ b/libdiskfs/opts-common.c
@@ -1,6 +1,6 @@
/* Options common to both startup and runtime
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -21,17 +21,39 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <argp.h>
+#include "priv.h"
const struct argp_option diskfs_common_options[] =
{
{"readonly", 'r', 0, 0, "Never write to disk or allow opens for writing"},
{"rdonly", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"ro", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
{"writable", 'w', 0, 0, "Use normal read/write behavior"},
{"rdwr", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"rw", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
{"sync", 's', "INTERVAL", OPTION_ARG_OPTIONAL,
"If INTERVAL is supplied, sync all data not actually written to disk"
" every INTERVAL seconds, otherwise operate in synchronous mode (the"
- " default is to sync every 30 seconds)"},
- {"nosync", 'n', 0, 0, "Don't automatically sync data to disk"},
+ " default is to sync every " DEFAULT_SYNC_INTERVAL_STRING " seconds)"},
+ {"no-sync", 'n', 0, 0, "Don't automatically sync data to disk"},
+ {"nosync", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"no-suid", 'S', 0, 0, "Don't permit set-uid or set-gid execution"},
+ {"nosuid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"suid-ok", OPT_SUID_OK, 0, 0, "Enable set-uid execution"},
+ {"no-exec", 'E', 0, 0, "Don't permit any execution of files on this filesystem"},
+ {"noexec", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"exec-ok", OPT_EXEC_OK, 0, 0, "Enable execution of files"},
+ {"no-atime", 'A', 0, 0,
+ "Do not update file access times on disk for reads"},
+ {"noatime", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"atime", OPT_ATIME, 0, 0, "Do update file access times for reads normally"},
+ {"no-inherit-dir-group", OPT_NO_INHERIT_DIR_GROUP, 0, 0,
+ "Create new nodes with gid of the process"},
+ {"nogrpid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"sysvgroups", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"inherit-dir-group", OPT_INHERIT_DIR_GROUP, 0, 0,
+ "Create new nodes with gid of parent dir (default)"},
+ {"grpid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"bsdgroups", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
{0, 0}
};
diff --git a/libdiskfs/opts-get.c b/libdiskfs/opts-get.c
index 26558212..c23e4bec 100644
--- a/libdiskfs/opts-get.c
+++ b/libdiskfs/opts-get.c
@@ -1,8 +1,7 @@
/* Get run-time options
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Copyright (C) 1995,96,2002 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -23,9 +22,7 @@
#include "priv.h"
error_t
-diskfs_get_options (char **argz, unsigned *argz_len)
+diskfs_append_args (char **argz, size_t *argz_len)
{
- *argz = 0;
- *argz_len = 0;
return diskfs_append_std_options (argz, argz_len);
}
diff --git a/libdiskfs/opts-runtime.c b/libdiskfs/opts-runtime.c
index d7264069..f0d1a382 100644
--- a/libdiskfs/opts-runtime.c
+++ b/libdiskfs/opts-runtime.c
@@ -1,6 +1,6 @@
/* Default definition for diskfs_runtime_argp
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 2004 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -19,5 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "priv.h"
+#include <argp.h>
struct argp *diskfs_runtime_argp = (struct argp *)&diskfs_std_runtime_argp;
diff --git a/libdiskfs/opts-set.c b/libdiskfs/opts-set.c
index 72af4ef1..3cfe3f6b 100644
--- a/libdiskfs/opts-set.c
+++ b/libdiskfs/opts-set.c
@@ -1,6 +1,6 @@
/* Set run-time options
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -25,7 +25,7 @@
#include "priv.h"
error_t
-diskfs_set_options (char *argz, size_t argz_len)
+diskfs_set_options (const char *argz, size_t argz_len)
{
if (diskfs_runtime_argp)
return fshelp_set_options (diskfs_runtime_argp, 0, argz, argz_len, 0);
diff --git a/libdiskfs/opts-std-runtime.c b/libdiskfs/opts-std-runtime.c
index 9a3ee80a..177dfaf6 100644
--- a/libdiskfs/opts-std-runtime.c
+++ b/libdiskfs/opts-std-runtime.c
@@ -1,6 +1,6 @@
/* Parse standard run-time options
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -18,18 +18,22 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <argp.h>
+
#include "priv.h"
static const struct argp_option
std_runtime_options[] =
{
- {"remount", 'u', 0, 0, "Flush any meta-data cached in core"},
+ {"update", 'u', 0, 0, "Flush any meta-data cached in core"},
+ {"remount", 0, 0, OPTION_HIDDEN | OPTION_ALIAS}, /* deprecated */
{0, 0}
};
struct parse_hook
{
- int readonly, sync, sync_interval, remount;
+ int readonly, sync, sync_interval, remount, nosuid, noexec, noatime,
+ noinheritdirgroup;
};
/* Implement the options in H, and free H. */
@@ -50,10 +54,12 @@ set_opts (struct parse_hook *h)
}
if (h->readonly != diskfs_readonly)
- if (err)
- diskfs_set_readonly (h->readonly); /* keep the old error. */
- else
- err = diskfs_set_readonly (h->readonly);
+ {
+ if (err)
+ diskfs_set_readonly (h->readonly); /* keep the old error. */
+ else
+ err = diskfs_set_readonly (h->readonly);
+ }
/* Change sync mode. */
if (h->sync)
@@ -68,6 +74,15 @@ set_opts (struct parse_hook *h)
diskfs_set_sync_interval (h->sync_interval);
}
+ if (h->nosuid != -1)
+ _diskfs_nosuid = h->nosuid;
+ if (h->noexec != -1)
+ _diskfs_noexec = h->noexec;
+ if (h->noatime != -1)
+ _diskfs_noatime = h->noatime;
+ if (h->noinheritdirgroup != -1)
+ _diskfs_no_inherit_dir_group = h->noinheritdirgroup;
+
free (h);
return err;
@@ -83,10 +98,21 @@ parse_opt (int opt, char *arg, struct argp_state *state)
case 'r': h->readonly = 1; break;
case 'w': h->readonly = 0; break;
case 'u': h->remount = 1; break;
+ case 'S': h->nosuid = 1; break;
+ case 'E': h->noexec = 1; break;
+ case 'A': h->noatime = 1; break;
+ case OPT_SUID_OK: h->nosuid = 0; break;
+ case OPT_EXEC_OK: h->noexec = 0; break;
+ case OPT_ATIME: h->noatime = 0; break;
+ case OPT_NO_INHERIT_DIR_GROUP: h->noinheritdirgroup = 1; break;
+ case OPT_INHERIT_DIR_GROUP: h->noinheritdirgroup = 0; break;
case 'n': h->sync_interval = 0; h->sync = 0; break;
case 's':
if (arg)
- h->sync_interval = atoi (arg);
+ {
+ h->sync = 0;
+ h->sync_interval = atoi (arg);
+ }
else
h->sync = 1;
break;
@@ -103,6 +129,7 @@ parse_opt (int opt, char *arg, struct argp_state *state)
h->sync = diskfs_synchronous;
h->sync_interval = -1;
h->remount = 0;
+ h->nosuid = h->noexec = h->noatime = h->noinheritdirgroup = -1;
/* We know that we have one child, with which we share our hook. */
state->child_inputs[0] = h;
@@ -127,8 +154,8 @@ parse_opt (int opt, char *arg, struct argp_state *state)
static const struct argp common_argp = { diskfs_common_options, parse_opt };
-static const struct argp *parents[] = { &common_argp, 0 };
+static const struct argp_child children[] = { {&common_argp}, {0} };
const struct argp diskfs_std_runtime_argp =
{
- std_runtime_options, parse_opt, 0, 0, parents
+ std_runtime_options, parse_opt, 0, 0, children
};
diff --git a/libdiskfs/opts-std-startup.c b/libdiskfs/opts-std-startup.c
index 8eb51e7c..6fe28758 100644
--- a/libdiskfs/opts-std-startup.c
+++ b/libdiskfs/opts-std-startup.c
@@ -1,8 +1,9 @@
/* Standard startup-time command line parser
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2007
+ Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -22,9 +23,14 @@
#include <stdio.h>
#include <argp.h>
+#include <hurd/store.h>
+#include <hurd/paths.h>
#include "priv.h"
-char *diskfs_boot_flags = 0;
+const char *diskfs_boot_command_line;
+char **_diskfs_boot_command;
+
+int _diskfs_boot_pause;
extern char **diskfs_argv;
@@ -35,16 +41,33 @@ mach_port_t diskfs_exec_server_task = MACH_PORT_NULL;
#define OPT_HOST_PRIV_PORT (-1)
#define OPT_DEVICE_MASTER_PORT (-2)
#define OPT_EXEC_SERVER_TASK (-3)
-#define OPT_BOOTFLAGS (-4)
+#define OPT_BOOT_CMDLINE (-4)
+#define OPT_BOOT_COMMAND (-5)
+#define OPT_BOOT_INIT_PROGRAM (-6)
+#define OPT_BOOT_PAUSE (-7)
static const struct argp_option
startup_options[] =
{
+ {"directory", 'C', "DIRECTORY", 0,
+ "Use DIRECTORY as the root of the filesystem"},
+ {"virtual-root", 0, 0, OPTION_ALIAS},
+ {"chroot", 0, 0, OPTION_ALIAS},
+
{0,0,0,0, "Boot options:", -2},
+ {"multiboot-command-line", OPT_BOOT_CMDLINE, "ARGS", 0,
+ "Required for bootstrap filesystem, the multiboot kernel command line"},
+ {"bootflags", 0, 0, OPTION_ALIAS|OPTION_HIDDEN},
+ {"boot-init-program", OPT_BOOT_INIT_PROGRAM, "FILE", 0,
+ "For bootstrap filesystem, init program to run (default " _HURD_INIT ")"},
+ {"boot-debug-pause", OPT_BOOT_PAUSE, 0, 0,
+ "Pause for keystroke before starting bootstrap programs"},
+ {"boot-command", OPT_BOOT_COMMAND, 0, 0,
+ "Remaining arguments form command line to run"
+ " at bootstrap instead of init"},
{"host-priv-port", OPT_HOST_PRIV_PORT, "PORT"},
{"device-master-port", OPT_DEVICE_MASTER_PORT, "PORT"},
{"exec-server-task", OPT_EXEC_SERVER_TASK, "PORT"},
- {"bootflags", OPT_BOOTFLAGS, "FLAGS"},
{0}
};
@@ -54,10 +77,17 @@ parse_startup_opt (int opt, char *arg, struct argp_state *state)
{
switch (opt)
{
- case 'r':
- diskfs_readonly = 1; break;
- case 'w':
- diskfs_readonly = 0; break;
+#define TOGGLE(var, on, off) \
+ case on: var = 1; break; \
+ case off: var = 0; break;
+ TOGGLE (diskfs_readonly, 'r', 'w');
+ TOGGLE (_diskfs_nosuid, 'S', OPT_SUID_OK);
+ TOGGLE (_diskfs_noexec, 'E', OPT_EXEC_OK);
+ TOGGLE (_diskfs_noatime, 'A', OPT_ATIME);
+ TOGGLE (_diskfs_no_inherit_dir_group, OPT_NO_INHERIT_DIR_GROUP,
+ OPT_INHERIT_DIR_GROUP);
+#undef TOGGLE
+
case 's':
if (arg == NULL)
diskfs_synchronous = 1;
@@ -76,8 +106,22 @@ parse_startup_opt (int opt, char *arg, struct argp_state *state)
_hurd_host_priv = atoi (arg); break;
case OPT_EXEC_SERVER_TASK:
diskfs_exec_server_task = atoi (arg); break;
- case OPT_BOOTFLAGS:
- diskfs_boot_flags = arg; break;
+ case OPT_BOOT_CMDLINE:
+ diskfs_boot_command_line = arg; break;
+ case OPT_BOOT_INIT_PROGRAM:
+ diskfs_boot_init_program = arg; break;
+ case OPT_BOOT_PAUSE:
+ _diskfs_boot_pause = 1; break;
+ case 'C':
+ _diskfs_chroot_directory = arg; break;
+
+ case OPT_BOOT_COMMAND:
+ if (state->next == state->argc)
+ argp_error (state, "Command line must follow --boot-command option");
+ _diskfs_boot_command = state->argv + state->next;
+ state->next = state->argc; /* stop parsing */
+ {char **p; for (p = _diskfs_boot_command; *p; ++p) printf("BC %s\n",*p);}
+ break;
case ARGP_KEY_END:
diskfs_argv = state->argv; break;
@@ -92,50 +136,26 @@ parse_startup_opt (int opt, char *arg, struct argp_state *state)
/* Suck in the common arguments. */
static const struct argp startup_common_argp =
{ diskfs_common_options, parse_startup_opt };
+static const struct argp_child startup_argp_children[] =
+ { {&startup_common_argp}, {0} };
/* This may be used with argp_parse to parse standard diskfs startup
options, possible chained onto the end of a user argp structure. */
-static const struct argp *startup_argp_parents[] = { &startup_common_argp, 0 };
-
const struct argp
-diskfs_std_startup_argp =
+diskfs_startup_argp =
{
- startup_options, parse_startup_opt, 0, 0, startup_argp_parents
+ startup_options, parse_startup_opt, 0, 0, startup_argp_children
};
-/* ---------------------------------------------------------------- */
-
-int diskfs_use_mach_device = 0;
-char *diskfs_device_arg = 0;
-
-static const struct argp_option
-dev_startup_options[] =
-{
- {"machdev", 'm', 0, 0, "DEVICE is a mach device, not a file"},
- {0, 0}
-};
-
static error_t
-parse_dev_startup_opt (int opt, char *arg, struct argp_state *state)
+parse_store_startup_opt (int opt, char *arg, struct argp_state *state)
{
switch (opt)
{
- case 'm':
- diskfs_use_mach_device = 1;
- break;
- case ARGP_KEY_ARG:
- diskfs_device_arg = arg;
- break;
-
- case ARGP_KEY_END:
- if (diskfs_boot_flags)
- diskfs_use_mach_device = 1; /* Can't do much else... */
- break;
-
- case ARGP_KEY_NO_ARGS:
- argp_error (state, "No device specified");
- return EINVAL;
-
+ case ARGP_KEY_INIT:
+ /* Propagate our input to our STORE_ARGP child , which it will use to
+ return what it parses. */
+ state->child_inputs[1] = state->input; break;
default:
return ARGP_ERR_UNKNOWN;
}
@@ -143,9 +163,16 @@ parse_dev_startup_opt (int opt, char *arg, struct argp_state *state)
return 0;
}
-static const struct argp *dev_startup_argp_parents[] =
- { &diskfs_std_startup_argp, 0 };
+static const struct argp_child store_argp_children[] =
+ { {&diskfs_startup_argp}, {&store_argp}, {0} };
-const struct argp diskfs_std_device_startup_argp =
- { dev_startup_options, parse_dev_startup_opt, "DEVICE", 0,
- dev_startup_argp_parents };
+/* An argp structure for the standard diskfs command line arguments plus a
+ store specification. The address of a location in which to return the
+ resulting struct store_parsed structure should be passed as the input
+ argument to argp_parse; see the declaration for STORE_ARGP in
+ <hurd/store.h> for more information. */
+const struct argp
+diskfs_store_startup_argp =
+{
+ 0, parse_store_startup_opt, 0, 0, store_argp_children
+};
diff --git a/libdiskfs/opts-version.c b/libdiskfs/opts-version.c
index 0e9d4098..c26334b2 100644
--- a/libdiskfs/opts-version.c
+++ b/libdiskfs/opts-version.c
@@ -20,6 +20,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <stdio.h>
+#include <argp.h>
+#include <version.h>
+
#include "priv.h"
static void
@@ -28,12 +32,15 @@ _print_version (FILE *stream, struct argp_state *state)
if (argp_program_version)
/* If this is non-zero, then the program's probably defined it, so let
that take precedence over the default. */
- fprintf (stream, "%s\n", argp_program_version);
+ fputs (argp_program_version, stream);
+ else if (diskfs_extra_version && *diskfs_extra_version)
+ fprintf (stream, "%s (%s) %s\n",
+ diskfs_server_name, diskfs_extra_version, diskfs_server_version);
else
- /* Construct a version using the standard diskfs variables. */
- fprintf (stream, "%s %d.%d (GNU %s)\n",
- diskfs_server_name, diskfs_major_version, diskfs_minor_version,
- HURD_RELEASE);
+ fprintf (stream, "%s %s\n", diskfs_server_name, diskfs_server_version);
+
+ /* And because diskfs is big and huge, put our information out too. */
+ fputs (STANDARD_HURD_VERSION (libdiskfs) "\n", stream);
}
void (*argp_program_version_hook) (FILE *stream, struct argp_state *state)
diff --git a/libdiskfs/ourfs_notify.defs b/libdiskfs/ourfs_notify.defs
deleted file mode 100644
index 64127fe6..00000000
--- a/libdiskfs/ourfs_notify.defs
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Private specialized presentation of fs_notify.defs for diskfs library. */
-
-#define routine simpleroutine
-#define USERPREFIX nowait_
-#include <hurd/fs_notify.defs>
diff --git a/libdiskfs/peropen-make.c b/libdiskfs/peropen-make.c
index de483f26..d37516c1 100644
--- a/libdiskfs/peropen-make.c
+++ b/libdiskfs/peropen-make.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994,97,99,2001,02 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
@@ -20,19 +20,45 @@
/* Create and return a new peropen structure on node NP with open
flags FLAGS. */
-struct peropen *
-diskfs_make_peropen (struct node *np, int flags, mach_port_t dotdotport)
+error_t
+diskfs_make_peropen (struct node *np, int flags, struct peropen *context,
+ struct peropen **ppo)
{
- struct peropen *po = malloc (sizeof (struct peropen));
+ struct peropen *po = *ppo = malloc (sizeof (struct peropen));
+
+ if (! po)
+ return ENOMEM;
+
po->filepointer = 0;
po->lock_status = LOCK_UN;
po->refcnt = 0;
po->openstat = flags;
po->np = np;
- po->dotdotport = dotdotport;
- if (dotdotport != MACH_PORT_NULL)
- mach_port_mod_refs (mach_task_self (), dotdotport,
- MACH_PORT_RIGHT_SEND, 1);
+
+ if (context)
+ {
+ po->root_parent = context->root_parent;
+ if (po->root_parent != MACH_PORT_NULL)
+ mach_port_mod_refs (mach_task_self (), po->root_parent,
+ MACH_PORT_RIGHT_SEND, 1);
+
+ po->shadow_root = context->shadow_root;
+ if (po->shadow_root)
+ diskfs_nref (po->shadow_root);
+
+ po->shadow_root_parent = context->shadow_root_parent;
+ if (po->shadow_root_parent != MACH_PORT_NULL)
+ mach_port_mod_refs (mach_task_self (), po->shadow_root_parent,
+ MACH_PORT_RIGHT_SEND, 1);
+ }
+ else
+ {
+ po->root_parent = MACH_PORT_NULL;
+ po->shadow_root_parent = MACH_PORT_NULL;
+ po->shadow_root = _diskfs_chroot_directory ? diskfs_root_node : 0;
+ }
+
diskfs_nref (np);
- return po;
+
+ return 0;
}
diff --git a/libdiskfs/peropen-rele.c b/libdiskfs/peropen-rele.c
index b38b2af6..6974e86a 100644
--- a/libdiskfs/peropen-rele.c
+++ b/libdiskfs/peropen-rele.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1996 Free Software Foundation
+ Copyright (C) 1994, 1996, 1997 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
@@ -15,6 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <sys/file.h>
#include "priv.h"
/* Decrement the reference count on a peropen structure. */
@@ -22,14 +23,27 @@ void
diskfs_release_peropen (struct peropen *po)
{
mutex_lock (&po->np->lock);
+
if (--po->refcnt)
{
mutex_unlock (&po->np->lock);
return;
}
- mach_port_deallocate (mach_task_self (), po->dotdotport);
+
+ if (po->root_parent)
+ mach_port_deallocate (mach_task_self (), po->root_parent);
+
+ if (po->shadow_root && po->shadow_root != po->np)
+ diskfs_nrele (po->shadow_root);
+
+ if (po->shadow_root_parent)
+ mach_port_deallocate (mach_task_self (), po->shadow_root_parent);
+
+ if (po->lock_status != LOCK_UN)
+ fshelp_acquire_lock (&po->np->userlock, &po->lock_status,
+ &po->np->lock, LOCK_UN);
+
diskfs_nput (po->np);
+
free (po);
}
-
-
diff --git a/libdiskfs/ports-clean.c b/libdiskfs/ports-clean.c
deleted file mode 100644
index 01a50dc5..00000000
--- a/libdiskfs/ports-clean.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Copyright (C) 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. */
-
-#include "priv.h"
-#include <hurd/pager.h>
-
-/* Indexed by port type (PT_*); called when the last reference goes
- away on a port. */
-void (*ports_cleanroutines[])(void *)=
-{
- [PT_PROTID] = diskfs_protid_rele,
- [PT_PAGER] = pager_clean,
- [PT_TRANSBOOT] = fshelp_transboot_clean,
- [PT_CTL] = _diskfs_control_clean,
-};
diff --git a/libdiskfs/ports-idle.c b/libdiskfs/ports-idle.c
deleted file mode 100644
index 9da021d5..00000000
--- a/libdiskfs/ports-idle.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- Copyright (C) 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. */
-
-#include "priv.h"
-
-/* Called by the ports library when we have been idle for
- ten minutes. */
-void
-ports_notice_idle (int nhard, int nsoft)
-{
- spin_lock (&_diskfs_control_lock);
- if (nhard > _diskfs_ncontrol_ports)
- {
- spin_unlock (&_diskfs_control_lock);
- return;
- }
- spin_unlock (&_diskfs_control_lock);
-
- /* XXX
- Here should actually drop control ports and exit. */
- return;
-}
diff --git a/libdiskfs/ports-soft.c b/libdiskfs/ports-soft.c
deleted file mode 100644
index 11ff1379..00000000
--- a/libdiskfs/ports-soft.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- Copyright (C) 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. */
-
-#include "priv.h"
-
-/* Called by ports library when there are only soft ports left. */
-void
-ports_no_hard_ports ()
-{
- diskfs_shutdown_soft_ports ();
-}
diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h
index 0f14ca3a..07464d56 100644
--- a/libdiskfs/priv.h
+++ b/libdiskfs/priv.h
@@ -1,5 +1,7 @@
/* Private declarations for fileserver library
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2006, 2009 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
@@ -20,18 +22,51 @@
#include <mach.h>
#include <hurd.h>
+#include <sys/mman.h>
#include <hurd/ports.h>
#include <hurd/fshelp.h>
#include <hurd/iohelp.h>
+#include <hurd/port.h>
#include <assert.h>
+#include <argp.h>
#include "diskfs.h"
-extern mach_port_t fs_control_port; /* receive right */
+/* These inhibit setuid or exec. */
+extern int _diskfs_nosuid, _diskfs_noexec;
+
+/* This relaxes the requirement to set `st_atim'. */
+extern int _diskfs_noatime;
+
+/* This enables SysV style group behaviour. New nodes inherit the GID
+ of the user creating them unless the SGID bit is set of the parent
+ directory. */
+extern int _diskfs_no_inherit_dir_group;
+
+/* This is the -C argument value. */
+extern char *_diskfs_chroot_directory;
+
+/* If --boot-command is given, this points to the program and args. */
+extern char **_diskfs_boot_command;
+
+/* Port cell holding a cached port to the exec server. */
+extern struct hurd_port _diskfs_exec_portcell;
volatile struct mapped_time_value *_diskfs_mtime;
-extern struct argp_option diskfs_common_options[];
+extern const struct argp_option diskfs_common_options[];
+/* Option keys for long-only options in diskfs_common_options. */
+#define OPT_SUID_OK 600 /* --suid-ok */
+#define OPT_EXEC_OK 601 /* --exec-ok */
+#define OPT_ATIME 602 /* --atime */
+#define OPT_NO_INHERIT_DIR_GROUP 603 /* --no-inherit-dir-group */
+#define OPT_INHERIT_DIR_GROUP 604 /* --inherit-dir-group */
+
+/* Common value for diskfs_common_options and diskfs_default_sync_interval. */
+#define DEFAULT_SYNC_INTERVAL 5
+#define DEFAULT_SYNC_INTERVAL_STRING STRINGIFY(DEFAULT_SYNC_INTERVAL)
+#define STRINGIFY(x) STRINGIFY_1(x)
+#define STRINGIFY_1(x) #x
/* Diskfs thinks the disk is dirty if this is set. */
extern int _diskfs_diskdirty;
@@ -39,25 +74,6 @@ extern int _diskfs_diskdirty;
/* Needed for MiG. */
typedef struct protid *protid_t;
-/* Called by MiG to translate ports into struct protid *.
- fsmutations.h arranges for this to happen for the io and
- fs interfaces. */
-extern inline struct protid *
-begin_using_protid_port (file_t port)
-{
- return ports_lookup_port (diskfs_port_bucket, port, diskfs_protid_class);
-}
-
-/* Called by MiG after server routines have been run; this
- balances begin_using_protid_port, and is arranged for the io
- and fs interfaces by fsmutations.h. */
-extern inline void
-end_using_protid_port (struct protid *cred)
-{
- if (cred)
- ports_port_deref (cred);
-}
-
/* Actually read or write a file. The file size must already permit
the requested access. NP is the file to read/write. DATA is a buffer
to write from or fill on read. OFFSET is the absolute address (-1
@@ -72,6 +88,9 @@ error_t _diskfs_rdwr_internal (struct node *np, char *data, off_t offset,
and auth ports). */
void _diskfs_init_completed (void);
+/* Called in a bootstrap filesystem only, to get the privileged ports. */
+void _diskfs_boot_privports (void);
+
/* Clean routine for control port. */
void _diskfs_control_clean (void *);
@@ -97,7 +116,7 @@ extern fshelp_fetch_root_callback2_t _diskfs_translator_callback2;
if (!(PROTID)) \
return EOPNOTSUPP; \
\
- if (diskfs_readonly) \
+ if (diskfs_check_readonly ()) \
return EROFS; \
\
np = (PROTID)->po->np; \
@@ -114,6 +133,7 @@ extern fshelp_fetch_root_callback2_t _diskfs_translator_callback2;
#define HONORED_STATE_MODES (O_APPEND|O_ASYNC|O_FSYNC|O_NONBLOCK|O_NOATIME)
/* Bits that are turned off after open */
-#define OPENONLY_STATE_MODES (O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS|O_NONBLOCK)
+#define OPENONLY_STATE_MODES \
+ (O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS|O_NONBLOCK|O_EXLOCK|O_SHLOCK)
#endif
diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c
index c67bd41b..9b78a37f 100644
--- a/libdiskfs/protid-make.c
+++ b/libdiskfs/protid-make.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,2001 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,6 +17,7 @@
#include "priv.h"
#include <string.h>
+#include <assert.h>
/* Build and return in CRED a protid which has no user identification, for
peropen PO. The node PO->np must be locked. */
@@ -37,45 +38,32 @@ diskfs_start_protid (struct peropen *po, struct protid **cred)
}
/* Finish building protid CRED started with diskfs_start_protid;
- the uid set is UID (length NUIDS); the gid set is GID (length NGIDS). */
+ the user to install is USER. */
void
-diskfs_finish_protid (struct protid *cred, uid_t *uids, int nuids,
- gid_t *gids, int ngids)
+diskfs_finish_protid (struct protid *cred, struct iouser *user)
{
- if (!uids)
- nuids = 1;
- if (!gids)
- ngids = 1;
+ error_t err;
- cred->uids = malloc (nuids * sizeof (uid_t));
- cred->gids = malloc (ngids * sizeof (uid_t));
- cred->nuids = nuids;
- cred->ngids = ngids;
-
- if (uids)
- bcopy (uids, cred->uids, nuids * sizeof (uid_t));
- else
- *cred->uids = 0;
-
- if (gids)
- bcopy (gids, cred->gids, ngids * sizeof (uid_t));
+ if (!user)
+ err = iohelp_create_simple_iouser (&cred->user, 0, 0);
else
- *cred->gids = 0;
+ err = iohelp_dup_iouser (&cred->user, user);
+ assert_perror (err);
- mach_port_move_member (mach_task_self (), cred->pi.port_right,
- diskfs_port_bucket->portset);
+ err = mach_port_move_member (mach_task_self (), cred->pi.port_right,
+ diskfs_port_bucket->portset);
+ assert_perror (err);
}
-/* Create and return a protid for an existing peropen PO in CRED. The uid
- set is UID (length NUIDS); the gid set is GID (length NGIDS). The node
- PO->np must be locked. */
+/* Create and return a protid for an existing peropen PO in CRED for USER.
+ The node PO->np must be locked. */
error_t
-diskfs_create_protid (struct peropen *po, uid_t *uids, int nuids,
- uid_t *gids, int ngids, struct protid **cred)
+diskfs_create_protid (struct peropen *po, struct iouser *user,
+ struct protid **cred)
{
error_t err = diskfs_start_protid (po, cred);
if (! err)
- diskfs_finish_protid (*cred, uids, nuids, gids, ngids);
+ diskfs_finish_protid (*cred, user);
return err;
}
diff --git a/libdiskfs/protid-rele.c b/libdiskfs/protid-rele.c
index 0c5d40ed..be74056a 100644
--- a/libdiskfs/protid-rele.c
+++ b/libdiskfs/protid-rele.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 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,7 +17,7 @@
#include "priv.h"
-/* Called when a protid CRED has no more references. (Because references\
+/* Called when a protid CRED has no more references. (Because references
to protids are maintained by the port management library, this is
installed in the clean routines list.) The ports library will
free the structure for us. */
@@ -26,11 +26,11 @@ diskfs_protid_rele (void *arg)
{
struct protid *cred = arg;
+ iohelp_free_iouser (cred->user);
if (cred->shared_object)
mach_port_deallocate (mach_task_self (), cred->shared_object);
if (cred->mapped)
- vm_deallocate (mach_task_self (), (vm_address_t) cred->mapped,
- vm_page_size);
+ munmap (cred->mapped, vm_page_size);
diskfs_release_peropen (cred->po);
}
diff --git a/libdiskfs/rdwr-internal.c b/libdiskfs/rdwr-internal.c
index 9fe42ade..18a4ae1e 100644
--- a/libdiskfs/rdwr-internal.c
+++ b/libdiskfs/rdwr-internal.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,97,99,2000 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
@@ -41,16 +41,23 @@ _diskfs_rdwr_internal (struct node *np,
if (dir)
assert (!diskfs_readonly);
+ if (*amt == 0)
+ /* Zero-length writes do not update mtime or anything else, by POSIX. */
+ return 0;
+
if (!diskfs_check_readonly () && !notime)
{
if (dir)
np->dn_set_mtime = 1;
- else
+ else if (! _diskfs_noatime)
np->dn_set_atime = 1;
}
memobj = diskfs_get_filemap (np, prot);
+ if (memobj == MACH_PORT_NULL)
+ return errno;
+
err = pager_memcpy (diskfs_get_filemap_pager_struct (np), memobj,
offset, data, amt, prot);
@@ -58,7 +65,7 @@ _diskfs_rdwr_internal (struct node *np,
{
if (dir)
np->dn_set_mtime = 1;
- else
+ else if (!_diskfs_noatime)
np->dn_set_atime = 1;
}
diff --git a/libdiskfs/readonly-changed.c b/libdiskfs/readonly-changed.c
new file mode 100644
index 00000000..44ee9225
--- /dev/null
+++ b/libdiskfs/readonly-changed.c
@@ -0,0 +1,31 @@
+/* Default hook for change to/from read-only
+
+ Copyright (C) 2001 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 this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "diskfs.h"
+
+/* The user may define this function. It is called when the disk has been
+ changed from read-only to read-write mode or vice-versa. READONLY is the
+ new state (which is also reflected in DISKFS_READONLY). This function is
+ also called during initial startup if the filesystem is to be writable. */
+void
+diskfs_readonly_changed (int readonly)
+{
+ /* By default do nothing at all. */
+}
diff --git a/libdiskfs/readonly.c b/libdiskfs/readonly.c
index 18ade09a..02f583c8 100644
--- a/libdiskfs/readonly.c
+++ b/libdiskfs/readonly.c
@@ -1,6 +1,6 @@
/* Change to/from read-only
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -21,21 +21,34 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <fcntl.h>
+#include <error.h>
#include "priv.h"
int _diskfs_diskdirty;
+int diskfs_readonly = 0;
+int diskfs_hard_readonly = 0;
int
diskfs_check_readonly ()
{
+ error_t err;
+
if (diskfs_readonly)
return 1;
else
{
if (!_diskfs_diskdirty)
{
- diskfs_set_hypermetadata (1, 0);
+ err = diskfs_set_hypermetadata (1, 0);
+ if (err)
+ {
+ error (0, 0,
+ "%s: MEDIA NOT WRITABLE; switching to READ-ONLY",
+ diskfs_disk_name ?: "-");
+ diskfs_hard_readonly = diskfs_readonly = 1;
+ return 1;
+ }
_diskfs_diskdirty = 1;
}
return 0;
@@ -51,6 +64,9 @@ diskfs_set_readonly (int readonly)
{
error_t err = 0;
+ if (diskfs_hard_readonly)
+ return readonly ? 0 : EROFS;
+
if (readonly != diskfs_readonly)
{
err = ports_inhibit_class_rpcs (diskfs_protid_class);
@@ -60,15 +76,13 @@ diskfs_set_readonly (int readonly)
{
error_t peropen_writable (void *pi)
{
- if (((struct port_info *)pi)->class == diskfs_protid_class
- && (((struct protid *)pi)->po->openstat & O_WRITE))
- return EBUSY;
- else
- return 0;
+ struct protid *const cred = pi;
+ return (cred->po->openstat & O_WRITE) ? EBUSY : 0;
}
/* Any writable open files? */
- err = ports_bucket_iterate (diskfs_port_bucket, peropen_writable);
+ err = ports_class_iterate (diskfs_protid_class,
+ peropen_writable);
/* Any writable pagers? */
if (!err && (diskfs_max_user_pager_prot () & VM_PROT_WRITE))
diff --git a/libdiskfs/shutdown.c b/libdiskfs/shutdown.c
index a3f96e22..f9bc4b57 100644
--- a/libdiskfs/shutdown.c
+++ b/libdiskfs/shutdown.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1993,94,95,96,98,99,2001 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.
@@ -22,10 +22,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "priv.h"
#include <hurd/fsys.h>
-struct rwlock diskfs_fsys_lock = RWLOCK_INITIALIZER;
-
/* Shutdown the filesystem; flags are as for fsys_goaway. */
-error_t
+error_t
diskfs_shutdown (int flags)
{
int nports = -1;
@@ -47,13 +45,13 @@ diskfs_shutdown (int flags)
else
error = 0;
mutex_lock (&np->lock);
-
+
if ((error == MIG_SERVER_DIED) || (error == MACH_SEND_INVALID_DEST))
error = 0;
-
+
return error;
}
-
+
if ((flags & FSYS_GOAWAY_UNLINK)
&& S_ISDIR (diskfs_root_node->dn_stat.st_mode))
return EBUSY;
@@ -66,7 +64,7 @@ diskfs_shutdown (int flags)
}
rwlock_writer_lock (&diskfs_fsys_lock);
-
+
/* Permit all the current RPC's to finish, and then
suspend new ones. */
err = ports_inhibit_class_rpcs (diskfs_protid_class);
@@ -76,9 +74,16 @@ diskfs_shutdown (int flags)
return err;
}
+ /* Write everything out and set "clean" state. Even if we don't in fact
+ shut down now, this has the nice effect that a disk that has not been
+ written for a long time will not need checking after a crash. */
+ diskfs_sync_everything (1);
+ diskfs_set_hypermetadata (1, 1);
+ _diskfs_diskdirty = 0;
+
/* First, see if there are outstanding user ports. */
nports = ports_count_class (diskfs_protid_class);
- if (((flags & FSYS_GOAWAY_FORCE) == 0)
+ if (((flags & FSYS_GOAWAY_FORCE) == 0)
&& (nports || diskfs_pager_users ()))
{
ports_enable_class (diskfs_protid_class);
diff --git a/libdiskfs/sync-default.c b/libdiskfs/sync-default.c
index cdcfde98..0d1fd93b 100644
--- a/libdiskfs/sync-default.c
+++ b/libdiskfs/sync-default.c
@@ -1,6 +1,6 @@
/* A variable holding the initial sync interval
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1999 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -18,4 +18,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-int diskfs_default_sync_interval = 30;
+#include "priv.h"
+
+int diskfs_default_sync_interval = DEFAULT_SYNC_INTERVAL;
diff --git a/libdiskfs/sync-interval.c b/libdiskfs/sync-interval.c
index acdb0842..20b9fbb4 100644
--- a/libdiskfs/sync-interval.c
+++ b/libdiskfs/sync-interval.c
@@ -1,8 +1,7 @@
/* Support for periodic syncing
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Copyright (C) 1995,96,99,2002 Free Software Foundation, Inc.
+ 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
@@ -68,11 +67,11 @@ diskfs_set_sync_interval (int interval)
else
{
periodic_sync_thread =
- cthread_fork ((cthread_fn_t)periodic_sync, (any_t)interval);
+ cthread_fork ((cthread_fn_t)periodic_sync, (any_t)(intptr_t)interval);
if (periodic_sync_thread)
cthread_detach (periodic_sync_thread);
else
- err = EIEIO;
+ err = ENOMEM;
}
if (!err)
@@ -112,8 +111,14 @@ periodic_sync (int interval)
if (! diskfs_readonly)
{
rwlock_reader_lock (&diskfs_fsys_lock);
- diskfs_sync_everything (0);
- diskfs_set_hypermetadata (0, 0);
+ /* Only sync if we need to, to avoid clearing the clean flag
+ when it's just been set. Any other thread doing a sync
+ will have held the lock while it did its work. */
+ if (_diskfs_diskdirty)
+ {
+ diskfs_sync_everything (0);
+ diskfs_set_hypermetadata (0, 0);
+ }
rwlock_reader_unlock (&diskfs_fsys_lock);
}
ports_end_rpc (pi, &link);
diff --git a/libdiskfs/trans-callback.c b/libdiskfs/trans-callback.c
index 7701199b..283b184f 100644
--- a/libdiskfs/trans-callback.c
+++ b/libdiskfs/trans-callback.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/*
+ Copyright (C) 1995,96,97,98,2001,02 Free Software Foundation, Inc.
Written by Michael I. Bushnell.
This file is part of the GNU Hurd.
@@ -26,17 +26,20 @@
static error_t
_diskfs_translator_callback1_fn (void *cookie1, void *cookie2,
uid_t *uid, gid_t *gid,
- char **argz, int *argz_len)
+ char **argz, size_t *argz_len)
{
error_t err;
struct node *np = cookie1;
- if (!np->istranslated)
+ if (! (np->dn_stat.st_mode & S_IPTRANS))
return ENOENT;
err = diskfs_get_translator (np, argz, (u_int *) argz_len);
if (err)
- return err;
+ {
+ assert (err != EOPNOTSUPP);
+ return err;
+ }
*uid = np->dn_stat.st_uid;
*gid = np->dn_stat.st_gid;
@@ -53,12 +56,26 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2,
mach_msg_type_name_t *underlying_type)
{
struct node *np = cookie1;
- mach_port_t *dotdot = cookie2;
struct protid *cred;
- error_t err =
- diskfs_create_protid (diskfs_make_peropen (np, flags, *dotdot),
- &np->dn_stat.st_uid, 1, &np->dn_stat.st_gid, 1,
- &cred);
+ struct peropen *po;
+ error_t err;
+ struct iouser *user;
+
+ err = iohelp_create_simple_iouser (&user, np->dn_stat.st_uid,
+ np->dn_stat.st_gid);
+ if (err)
+ return err;
+
+ err = diskfs_make_peropen (np, flags, cookie2, &po);
+ if (! err)
+ {
+ err = diskfs_create_protid (po, user, &cred);
+ if (err)
+ diskfs_release_peropen (po);
+ }
+
+ iohelp_free_iouser (user);
+
if (! err)
{
*underlying = ports_get_right (cred);