diff options
Diffstat (limited to 'libdiskfs')
107 files changed, 2446 insertions, 5342 deletions
diff --git a/libdiskfs/ChangeLog b/libdiskfs/ChangeLog deleted file mode 100644 index 086fadb9..00000000 --- a/libdiskfs/ChangeLog +++ /dev/null @@ -1,3031 +0,0 @@ -Fri Jun 6 11:42:14 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * Makefile (LCLHDRS): Add fhandle.h. - -Tue May 27 11:55:56 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * file-chmod.c (diskfs_S_file_chmod): Turn off S_ITRANS bits too. - -Mon Feb 24 17:22:05 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * io-identity.c (diskfs_S_io_identity): Pass CRED's shadow root - inode number to fshelp_get_identity when creating a shadow root - fsid, not INUM. - -Mon Feb 24 14:40:02 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dir-rmdir.c (diskfs_S_dir_rmdir): Check EBUSY-when-translated - error before ENOTDIR-when-not-dir. - -Sat Feb 22 00:00:32 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * io-stat.c (diskfs_S_io_stat): Mark shadow roots with S_IROOT. - * io-identity.c (diskfs_S_io_identity): Return different fsys ids - for different shadow roots. - - * peropen-rele.c (diskfs_release_peropen): Don't deadlock if PO's - shadow_root is also it's node. - * file-reparent.c (diskfs_S_file_reparent): Don't release a - reference to any old shadow_root if it was == NODE. Don't aquire - a new reference for NODE. - -Fri Feb 21 17:12:04 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-init.c (diskfs_init_dir): Use CRED->po as LOOKUPCRED's po, - so that root detection works (and doesn't crash). - -Thu Feb 20 00:43:38 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * io-read.c (diskfs_S_io_read): Support reading from sylinks. - * dir-lookup.c (diskfs_S_dir_lookup): Allow symlinks to be opened - for O_READ. - -Thu Feb 13 19:27:16 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-rename.c (diskfs_S_dir_rename): Return EXDEV if FROMCRED and - TOCRED are in different shadow trees. - - * file-reparent.c (diskfs_S_file_reparent): New function, from - dir-reparent.c. - * dir-reparent.c: File removed. - * Makefile (FSSRCS): dir-reparent.c replaced by file-reparent.c. - -Wed Feb 12 14:23:15 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * peropen-make.c (diskfs_make_peropen): Add & use CONTEXT param. - Remove DOTDOT & DEPTH params. - * fsys-getroot.c (diskfs_S_fsys_getroot): Pass a prototype peropen - instead of the dotdotport and depth to diskfs_make_peropen. - * fsys-getfile.c (diskfs_S_fsys_getfile): Likewise. - * file-exec.c (diskfs_S_file_exec): Likewise. - * dir-reparent.c (diskfs_S_dir_reparent): Likewise. - * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise. - * dir-lookup.c (diskfs_S_dir_lookup): Likewise. - * boot-start.c (diskfs_start_bootstrap): Likewise. - (diskfs_S_exec_startup_get_info): Likewise. - (diskfs_execboot_fsys_startup): Likewise. - (diskfs_S_fsys_init): Likewise. - * trans-callback.c (_diskfs_translator_callback2_fn): Pass COOKIE - directly to diskfs_make_peropen instead of unpacking each arg. - * priv.h (struct diskfs_trans_callback_cookie2): Type removed. - * dir-lookup.c (diskfs_S_dir_lookup): Use DIRCRED->po as the - cookie for fshelp_fetch_root instead of a local structure. - * diskfs.h (diskfs_lookup): Remove DEPTH & NEW_DEPTH params. - * dir-lookup.c (diskfs_S_dir_lookup): Get rid of DEPTH variable. - Get rid of depth parameters to diskfs_lookup. - Deal properly with EAGAIN return from diskfs_lookup. - Replace references to dotdotport with root_parent. - * dir-unlink.c (diskfs_S_dir_unlink): Don't pass depth args to - diskfs_lookup. - * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise. - * dir-renamed.c (diskfs_rename_dir, checkpath): Likewise. - * dir-rename.c (diskfs_S_dir_rename): Likewise. - * dir-mkdir.c (diskfs_S_dir_mkdir): Likewise. - * dir-link.c (diskfs_S_dir_link): Likewise. - * dir-init.c (diskfs_init_dir): Likewise. - * dir-clear.c (diskfs_clear_directory): Likewise. - * lookup.c (diskfs_lookup): Remove DEPTH & NEW_DEPTH params. - Check CRED->po->shadow_root for root traversals, and get rid of assert - that EAGAIN isn't returned from diskfs_lookup_hard. - * diskfs.h (struct peropen): - Add shadow_root_parent & shadow_root fields. - Removed depth field. - Rename dotdotnode field to root_parent. - * peropen-rele.c (diskfs_release_peropen): Finalize new state. - - * dir-lookup.c (diskfs_S_dir_lookup): Remove O_EXLOCK & O_SHLOCK - from FLAGS mask, now that they're included in O_HURD. - -Thu Feb 6 02:17:35 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * io-write.c (diskfs_S_io_write): Check OFF for validity and - return EINVAL if it's bogus. - * io-read.c (diskfs_S_io_read): Likewise. - - * dir-mkfile.c (diskfs_S_dir_mkfile): New file's depth is one - greater than CRED's. - - * file-getfh.c (diskfs_S_file_getfh): Implement (code from ufs). - * fsys-getfile.c (diskfs_S_fsys_getfile): Likewise. - * fhandle.h: New file. - -Wed Feb 5 16:06:26 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-reparent.c (diskfs_S_dir_reparent): Implement. - - * lookup.c (diskfs_lookup): Add DEPTH & NEW_DEPTH arguments. - Implement new fs-root detection using them. - * diskfs.h (diskfs_lookup): Add DEPTH & NEW_DEPTH arguments. - * dir-link.c (diskfs_S_dir_link): Supply DEPTH & NEW_DEPTH - arguments to diskfs_lookup. - * dir-clear.c (diskfs_clear_directory): Likewise. - * dir-init.c (diskfs_init_dir): Likewise. - * dir-renamed.c (checkpath, diskfs_rename_dir): Likewise. - * dir-rename.c (diskfs_S_dir_rename): Likewise. - * dir-mkdir.c (diskfs_S_dir_mkdir): Likewise. - * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise. - * dir-unlink.c (diskfs_S_dir_unlink): Likewise. - * dir-lookup.c (diskfs_S_dir_lookup): Likewise. - Add DEPTH variable. - * dir-link.c (diskfs_S_dir_link): Translate EAGAIN (meaning root's - parent) to EINVAL. - * dir-rename.c (diskfs_S_dir_rename): Likewise. - - * diskfs.h (struct peropen): Add DEPTH field. - (diskfs_make_peropen): Add DEPTH argument. - * peropen-make.c (diskfs_make_peropen): Add & use DEPTH argument. - * boot-start.c (diskfs_start_bootstrap, - diskfs_S_exec_startup_get_info, diskfs_execboot_fsys_startup, - diskfs_S_fsys_init): Supply DEPTH argument to diskfs_make_peropen. - * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. - * file-exec.c (diskfs_S_file_exec): Likewise. - * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise. - * dir-lookup.c (diskfs_S_dir_lookup): Likewise. - * priv.h (struct diskfs_trans_callback_cookie2): New type. - * trans-callback.c (_diskfs_translator_callback2_fn): Expect - COOKIE2 to be a pointer to a struct diskfs_trans_callback_cookie2, - and use that to pass args to diskfs_make_peropen. - * fsys-getroot.c (diskfs_S_fsys_getroot): Pass new type of cookie2 to - fshelp_fetch_root, as expected by _diskfs_translator_callback2. - * dir-lookup.c (diskfs_S_dir_lookup): Likewise. - -Mon Jan 20 16:18:00 1997 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-reparent.c (diskfs_S_dir_reparent): New file. - * Makefile (FSSRCS): Add dir-reparent.c. - - * disk-pager.c (preemptor): Renamed from `preempter'; type & init - changed as well. - (diskfs_start_disk_pager): `preempter' -> `preemptor'. - * diskfs-pager.h: Doc fix. - -Tue Nov 19 18:21:12 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * diskfs.h (struct node): Add author_tracks_uid field. - * file-chown.c (diskfs_S_file_chown): If NP->author_tracks_uid, - modify NP->dn_stat.st_author as well. - * node-create.c (diskfs_create_node): Likewise. - -Mon Nov 18 17:02:22 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * diskfs.h (struct node): Remove istranslated field. - * io-stat.c (diskfs_S_io_stat): Set S_IATRANS & S_IROOT bits in - st_mode field of returned buffer if appropiate. - * dir-lookup.c (diskfs_S_dir_lookup): Use S_IPTRANS bit in dn_stat - st_mode field rather than istranslated field. - * file-get-trans.c (diskfs_S_file_get_translator): Likewise. - * file-set-trans.c (diskfs_S_file_set_translator): Likewise. - * file-inv-trans.c (diskfs_S_file_invoke_translator): Likewise. - * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. - * node-drop.c (diskfs_drop_node): Likewise. - * trans-callback.c (_diskfs_translator_callback1_fn): Likewise. - * dir-rmdir.c (diskfs_S_dir_rmdir): Likewise. - - * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): Use - MACH_MSG_TYPE_MOVE_SEND to return *ctl, rather than COPY. - (diskfs_S_file_get_translator_cntl): Correctly test for errors - from fshelp_fetch_control. - -Fri Nov 15 14:06:16 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * protid-make.c (diskfs_finish_protid): Fix typo. - - * file-chown.c (diskfs_S_file_chown): Look for UID, not CRED in - the uid set. - - * dir-lookup.c (diskfs_S_dir_lookup): Make the unauthenticated - port correctly. - -Thu Nov 14 13:07:37 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dir-init.c (diskfs_init_dir): New vars VEC and USER; fabricate - LOOKUPCRED to correspond to new structure definitions. - - * io-restrict-auth.c (diskfs_S_io_restrict_auth): Declare I and - add a missing semicolon. - - * fsys-getroot.c (diskfs_S_fsys_getroot): Eliminate PSEUDOCRED - entirely. Fix unrelated typo. - - * file-chauthor.c (dithkfth_TH_file_chauthor): Fix first arg in - call to fthhelp_ithowner. - -Tue Nov 12 22:45:07 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * diskfs.h: Correctly close comment. - -Thu Nov 7 14:49:19 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * io-restrict-auth.c (diskfs_S_io_restrict_auth): If CRED has - root, use the requested id sets verbatim. - -Thu Nov 7 01:03:11 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * protid-rele.c (diskfs_protid_rele): Free CRED->user. - -Wed Nov 6 17:55:17 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * diskfs.h (diskfs_isuid, diskfs_groupmember, diskfs_isowner, - diskfs_access, diskfs_checkdirmod): Delete functions. - * fsys-getroot.c (diskfs_S_fsys_getroot): Replace PSEUDOCRED with - a real iouser and specify that in the relevant calls. - * io-restrict-auth.c (diskfs_S_io_restrict_auth): Reworked to use - idvecs. - * file-chmod.c (diskfs_S_file_chmod): diskfs_isuid -> - idvec_contains. - * file-chown.c (diskfs_S_file_chown): Likewise. - * file-getcontrol.c (diskfs_S_file_getcontrol): Likewise. - * file-chmod.c (diskfs_S_file_chmod): diskfs_groupmember -> - idvec_contains. - * file-chown.c (diskfs_S_file_chown): Likewise. - * node-create.c (diskfs_create_node): Likewise. - * dir-lookup.c (diskfs_S_dir_lookup): diskfs_isowner -> - fshelp_isowner. - * file-chflags.c (diskfs_S_file_chflags): Likewise. - * file-chmod.c (diskfs_S_file_chmod): Likewise. - * file-chown.c (diskfs_S_file_chown): Likewise. - * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): - Likewise. - * file-set-trans.c (diskfs_S_file_set_translator): Likewise. - * file-utimes.c (diskfs_S_file_utimes): Likewise. - * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. - * lithp.h (dithkfth_ithowner): Deleted macro. - (fthhelp_ithowner, uther): New macros. - * file-chauthor.c (dithkfth_TH_file_chauthor): dthkfth_ithowner -> - fthhelp_ithowner. - * dir-lookup.c (diskfs_S_dir_lookup): diskfs_access -> - fshelp_access. - * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise. - * file-access.c (diskfs_S_file_check_access): Likewise. - * file-exec.c (diskfs_S_file_exec): Likewise (in dead code). - * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. - * ifsock.c (diskfs_S_ifsock_getsockaddr): Likewise. - * lookup.c (diskfs_lookup): Likewise. - (diskfs_lookup): diskfs_checkdirmod -> fshelp_checkdirmod. - * dir-lookup.c (diskfs_S_dir_lookup): New arg format for - fshelp_fetch_root. - * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. - * diskfs.h, protid-make.c (diskfs_create_protid): Delete args - `uids', `gids', `nuids', and `ngids'. Replace with new arg - `user'. All callers changed. - (diskfs_finish_protid): Likewise. - * file-inv-trans.c (diskfs_S_file_invoke_translator): Use - CRED->user instead of old fields. - * io-restrict-auth.c (diskfs_S_io_restrict_auth): Likewise. - * node-create.c (diskfs_create_node): Likewise. - * file-exec.c (diskfs_S_file_exec): Likewise. Use idvec_merge - instead of idvec_merge_ids, now that it's convenient. - * io-reauthenticate.c (diskfs_S_io_reauthenticate): Use new - iohelp_reauthenticate. - -Tue Nov 5 21:10:18 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * diskfs.h: Include <idvec.h>. - (struct protid): Delete members `uids', `gids', `nuids' and - `ngids'. New member `user'. - -Thu Oct 24 15:56:30 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * opts-std-startup.c (store_argp_children, startup_argp_children): - New variables. - (store_argp_parents, startup_argp_children): Variable removed. - (diskfs_store_startup_argp): Use STORE_ARGP_CHILDREN instead of - STORE_ARGP_PARENTS. - (diskfs_startup_argp): Use STARTUP_ARGP_CHILDREN instead of - STARTUP_ARGP_PARENTS. - * opts-std-runtime.c (children): New variable. - (parents): Variable removed. - (diskfs_std_runtime_argp): Use CHILDREN instead of PARENTS. - -Mon Oct 21 21:54:34 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * diskfs.h: Add extern inline protection. - * diskfs.c: New file. - * Makefile (OTHERSRCS): Add diskfs.c. - -Fri Oct 11 21:55:45 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-lookup.c (diskfs_S_dir_lookup): Temporarily add O_EXLOCK and - O_SHLOCK to the set of retained flags, until they get added to O_HURD. - Turn off OPENONLY_STATE_MODES bits in the flags we pass to - diskfs_make_peropen, not everything *but* them! - * priv.h (OPENONLY_STATE_MODES): Add O_EXLOCK & O_SHLOCK. - -Thu Oct 10 17:22:06 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-lookup.c (diskfs_S_dir_lookup): Frob lock in NEWPI->po, not PO. - Free NEWPI if we get an error trying to lock it. - <sys/file.h>: New include. - -Thu Oct 10 17:11:05 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * dir-lookup.c (diskfs_S_dir_lookup): Implement O_SHLOCK and - O_EXLOCK directly here. - -Thu Oct 10 10:53:28 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * peropen-rele.c (diskfs_release_peropen): Before freeing PO, - release any user lock it's holding. - <sys/file.h>: New include. - -Tue Oct 8 15:01:32 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * ifsock.c (diskfs_S_ifsock_getsockaddr): Write permission governs - access to sockets, not read permission. - -Mon Oct 7 14:50:04 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * dir-rmdir.c (diskfs_S_dir_rmdir): Return ENOTDIR if NP isn't a dir. - -Tue Sep 24 23:51:37 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * opts-version.c (_print_version): Follow version string with newline. - -Thu Sep 19 17:59:37 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * Makefile (HURDLIBS): Add store. - -Wed Sep 18 15:02:31 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * opts-version.c (_print_version): Change to use new version - format from the coding standards. - - * opts-std-runtime.c (std_runtime_options): Change --remount to - --update (keep --remount as a deprecated alias). - <argp.h>: New include. - * opts-append-std.c <stdio.h>: New include. - * dir-lookup.c <stdio.h>: New include. - -Fri Sep 13 19:15:45 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * file-get-fs-opts.c (diskfs_S_file_get_fs_options): Free ARGZ if - diskfs_append_args returns an error. - * fsys-options.c (diskfs_S_fsys_get_options): Likewise. - -1996-09-12 Miles Bader <miles@gnu.ai.mit.edu> - - * diskfs.h (diskfs_disk_name): New declaration. - * readonly.c (diskfs_check_readonly): Use DISKFS_DISK_NAME - instead of DISKFS_DEVICE_ARG. - * init-startup.c (_diskfs_init_completed): Likewise. - -Wed Sep 11 17:25:14 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * disk-pager.c (diskfs_start_disk_pager): Renamed from - setup_disk_pager. - Add PAGER_BUCKET, IMAGE, and SIZE arguments. - Pass in PAGER_BUCKET to thread routine, and don't create it. - (diskfs_disk_pager): Renamed from disk_pager. - (disk_image): Variable removed. - (pager_bucket): Declaration removed. - (service_paging_requests): Get PAGER_BUCKET from argument. - * diskfs-pager.h (diskfs_start_disk_pager): Renamed from - disk_pager_setup. - Add PAGER_BUCKET, IMAGE, and SIZE arguments. - (diskfs_disk_pager): Renamed from disk_pager. - (disk_image, pager_bucket): Declarations removed. - -Mon Sep 9 10:54:58 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * fsys-options.c (diskfs_S_fsys_get_options): Initialize ARGZ & - ARGZ_LEN to the program name, and call diskfs_append_args instead - of diskfs_get_options. - * file-get-fs-opts.c (diskfs_S_file_get_fs_options): Likewise. - <argz.h>: New include. - * diskfs.h (diskfs_append_args): Renamed from diskfs_get_options. - * opts-get.c (diskfs_append_args): Likewise. - * opts-std-startup.c <hurd/store.h>: New include. - (store_argp_parents): Use diskfs_startup_argp, not - diskfs_std_startup_argp. - * Makefile (libdiskfs.so): Depend on libstore.so. - - * opts-version.c <argp.h>, <stdio.h>: New includes. - (_print_version): Test diskfs_extra_version against 0 too. - * io-version.c <stdio.h>: New include. - (diskfs_S_io_server_version): Use snprintf instead of sprintf. - -Sun Sep 8 18:19:50 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * diskfs.h <argp.h>: Include removed. - (struct argp): New (incomplete) declaration. - (diskfs_get_file_device, diskfs_get_mach_device): Declarations removed. - (diskfs_startup_argp): Renamed from diskfs_std_startup_argp. - (diskfs_store_startup_argp): Renamed from - diskfs_std_device_startup_argp. - (diskfs_device_arg, diskfs_use_mach_device, diskfs_device_open, - 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_read_sync): Declarations - removed. - * opts-std-startup.c (diskfs_use_mach_device, diskfs_device_arg, - dev_startup_options, dev_startup_argp_parents, - diskfs_std_device_startup_argp): Variables removed. - (parse_dev_startup_opt): Function removed. - (diskfs_startup_argp): Renamed from diskfs_std_startup_argp. - * Makefile (OTHERSRCS): Remove filedev.c, machdev.c, dev-open.c, - dev-io.c, & dev-globals.c. - -Thu Sep 12 16:22:27 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * Makefile: New variable. - (libdiskfs.so): Delete special depedency. - -Thu Sep 5 11:13:54 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * io-version.c (diskfs_S_io_server_version): Only fill in - SERVER_NAME; ignore the rest. - - * diskfs.h (diskfs_major_version, diskfs_minor_version, - diskfs_edit_version): Delete variables. - (diskfs_server_version, diskfs_extra_version): New variables. - * boot-start.c (diskfs_S_fsys_init): Register version from - diskfs_server_version; pass empty string as release. - * extra-version.c: New file. - * Makefile (OTHERSRCS): Add extra-version.c. - * opts-version.c: Include <version.h>. - (diskfs_extra_version): Delete special declaration. - (_print_version): Use the user's provided version number, and also - give it our (libdiskfs) version number. - -Tue Sep 3 10:48:05 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * name-cache.c (diskfs_enter_lookup_cache): Cache `.' and `..' - just like other nodes. - (diskfs_check_lookup_cache): If we get a cache hit on `..', then - do the inverse locking semantic, and only return success if things - are stable around the call. - -Fri Aug 30 21:57:18 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * lookup.c (cache_misses): New variable, to find out what sort of - thing all the cache misses are. - (cm_lock): New variable. - (diskfs_lookup): Keep track of cache misses in cache_misses. - - * name-cache.c (MAXCACHE): 200 now. After experimentation, this - appears to be a pretty good value. Very little benefit after - this. - -Fri Aug 30 20:41:27 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * name-cache.c (struct lookup_cache): Delete member `hits'. - New member `stati'. - (diskfs_enter_lookup_cache): Don't initialize C->hits. - (find_cache): Set C->stati before returning. - (build_partial): Delete function. - (diskfs_check_lookup_cache): Delete calls to build_partial. - Register all statistics through register_neg_hit, - register_pos_hit, and register_miss. - (MAXCACHE): 2000 now. - -Wed Aug 28 12:20:53 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * name-cache.c (MAXCACHE): 500 for now. - -Mon Aug 26 15:10:55 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * name-cache.c (MAXCACHE): Increase to 50000. - (struct lookup_cache): New member `hits'. - (statistics): Name struct type `struct stats'. - (diskfs_enter_lookup_cache): Initialize C->hits. - (PARTIAL_THRESH, NPARTIALS): New macros. - (partial_stats): New variable. - (build_partial): New function. - (diskfs_check_lookup_cache): Call build_partial after statistics - frobbing. - - * name-cache.c (diskfs_check_lookup_cache): Increment members of - statistics while still holding CACHE_LOCK. - -Fri Aug 16 18:23:25 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * name-cache.c (diskfs_check_lookup_cache): Keep track of negative - hits properly. - * lookup.c (diskfs_lookup): On LOOKUPs that fail to find the node, - enter a negative cache entry. - -Thu Aug 15 16:07:23 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * opts-version.c (diskfs_extra_version): New (weak) reference. - (_print_version): Use DISKFS_EXTRA_VERSION. Tweak edit version. - Fix type of EV. - -Thu Aug 15 16:38:41 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * io-identity.c (diskfs_S_io_identity): Don't hold lock around - call to fshelp_get_identity. - -Mon Aug 12 15:54:27 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * opts-version.c (_print_version): Print the edit version too if - it's non-zero. - -Thu Aug 8 18:18:09 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * readonly.c: Include <error.h>. - -Wed Aug 7 13:53:56 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * readonly.c (diskfs_check_readonly): If we get an error from - diskfs_hypermetadata, then switch to readonly. - * diskfs.h (diskfs_set_hypermetadata): Require an error code return. - * dev-io.c (diskfs_device_write_sync): If we get D_READ_ONLY, then - return EROFS to the caller instead of EIO. - - * node-create.c (diskfs_create_node): New files always copy GID - from their parent; that's NetBSD's behavior, and it's good enough - for me. - -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 491e99a6..73686889 100644 --- a/libdiskfs/Makefile +++ b/libdiskfs/Makefile @@ -1,5 +1,6 @@ # -# Copyright (C) 1994, 1995, 1996, 1997 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 @@ -24,11 +25,11 @@ FSSRCS= dir-chg.c dir-link.c dir-lookup.c dir-mkdir.c dir-mkfile.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-inv-trans.c file-lock-stat.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-interrupt.c io-map-cntl.c io-map.c io-modes-get.c io-modes-off.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,31 @@ 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 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 extra-version.c diskfs.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 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 ports threads shouldbeinlibc +HURDLIBS = fshelp iohelp store threads ports shouldbeinlibc pager fsys-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h -DREPLY_PORTS fs-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h 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 711881a6..15563bdb 100644 --- a/libdiskfs/boot-start.c +++ b/libdiskfs/boot-start.c @@ -1,5 +1,6 @@ /* - Copyright (C) 1993, 1994, 1995, 1996, 1997 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,94 +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, 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; @@ -170,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); } @@ -227,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))) @@ -242,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 */ @@ -257,10 +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, 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; @@ -291,18 +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, 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, @@ -362,11 +460,11 @@ diskfs_S_fsys_init (mach_port_t port, { struct port_infe *pt; static int initdone = 0; - process_t execprocess; 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) @@ -380,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); @@ -390,35 +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, 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); @@ -432,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 { @@ -442,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; @@ -458,7 +602,7 @@ diskfs_S_fsys_init (mach_port_t port, if (err) return err; - proc_register_version (procserver, host, diskfs_server_name, "", + proc_register_version (procserver, host, diskfs_server_name, "", diskfs_server_version); err = proc_getmsgport (procserver, 1, &startup); @@ -470,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 (); @@ -490,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); @@ -507,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 d3be449f..00000000 --- a/libdiskfs/dev-io.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Device input and output - Copyright (C) 1992, 1993, 1994, 1995, 1996 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; - error_t err; - - assert (!diskfs_readonly); - err = device_write (diskfs_device, 0, diskfs_device_start + addr, - (io_buf_ptr_t) data, len, &written); - - if (err == D_READ_ONLY) - return EROFS; - else if (err || 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-link.c b/libdiskfs/dir-link.c index 7f1ab2f5..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, 1997 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); @@ -76,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); @@ -84,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) { @@ -102,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) { @@ -120,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 9946300c..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, 1997 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 @@ -25,10 +26,6 @@ #include "priv.h" #include "fs_S.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)) - /* Implement dir_lookup as described in <hurd/fs.defs>. */ kern_return_t diskfs_S_dir_lookup (struct protid *dircred, @@ -54,9 +51,10 @@ 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; @@ -76,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; @@ -96,7 +92,7 @@ diskfs_S_dir_lookup (struct protid *dircred, do { assert (!lastcomp); - + /* Find the name of the next pathname component */ nextname = index (path, '/'); @@ -118,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 @@ -136,44 +132,59 @@ diskfs_S_dir_lookup (struct protid *dircred, /* If we get an error we're done */ if (error == EAGAIN) - if (dnp == dircred->po->shadow_root) - /* We're at the root of a shadow tree. */ - { - *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->root_parent; - *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; - if (!lastcomp) - strcpy (retryname, nextname); - error = 0; - goto out; - } - else - /* We're at a REAL root, as in there's no way up from here. */ - { - error = 0; - np = dnp; - diskfs_nref (np); - } + { + 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->root_parent; + *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; + if (!lastcomp) + strcpy (retryname, nextname); + error = 0; + goto out; + } + else + /* We're at a REAL root, as in there's no way up from here. */ + { + error = 0; + np = dnp; + diskfs_nref (np); + } + } /* Create the new node if necessary */ if (lastcomp && create) { 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) @@ -186,7 +197,7 @@ diskfs_S_dir_lookup (struct protid *dircred, else diskfs_drop_dirstat (dnp, ds); } - + if (error) goto out; @@ -200,12 +211,13 @@ diskfs_S_dir_lookup (struct protid *dircred, || 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; @@ -238,18 +250,26 @@ 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), - iohelp_create_iouser (make_idvec (), - make_idvec ()), - &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); @@ -273,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; } @@ -295,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 */ @@ -306,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 { @@ -369,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. */ @@ -381,7 +423,7 @@ diskfs_S_dir_lookup (struct protid *dircred, error = ENOTDIR; goto out; } - + if (!newnode) /* Check permissions on existing nodes, but not new ones. */ { @@ -389,7 +431,7 @@ diskfs_S_dir_lookup (struct protid *dircred, type == S_IFIFO) && (flags & (O_READ|O_WRITE|O_EXEC))) || (type == S_IFLNK && (flags & (O_WRITE|O_EXEC)))) - error = EOPNOTSUPP; + error = EACCES; if (!error && (flags & O_READ)) error = fshelp_access (&np->dn_stat, S_IREAD, dircred->user); @@ -410,43 +452,50 @@ diskfs_S_dir_lookup (struct protid *dircred, if (error) goto out; } - - if ((flags & O_NOATIME) + + if ((flags & O_NOATIME) && (fshelp_isowner (&np->dn_stat, dircred->user) == EPERM)) flags &= ~O_NOATIME; - - error = - diskfs_create_protid (diskfs_make_peropen (np, - (flags &~OPENONLY_STATE_MODES), - dircred->po), - dircred->user, &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) - ports_port_deref (newpi); /* Get rid of NEWPI. */ } - + if (! error) { *returned_port = ports_get_right (newpi); ports_port_deref (newpi); + newpi = 0; } - + out: if (np) - if (dnp == np) - diskfs_nrele (np); - else - diskfs_nput (np); + { + if (dnp == np) + diskfs_nrele (np); + else + diskfs_nput (np); + } 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 1f4ff0ea..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, 1997 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; @@ -51,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 83158916..914b18fe 100644 --- a/libdiskfs/dir-mkfile.c +++ b/libdiskfs/dir-mkfile.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1995, 1996, 1997 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 ()) @@ -52,8 +53,8 @@ diskfs_S_dir_mkfile (struct protid *cred, 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,10 +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), - cred->user, &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); @@ -81,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 6fc7e0f5..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, 1997 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 @@ -42,6 +45,10 @@ diskfs_S_dir_rename (struct protid *fromcred, 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; @@ -138,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; } @@ -149,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 1847720f..79381b2c 100644 --- a/libdiskfs/dir-renamed.c +++ b/libdiskfs/dir-renamed.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1995, 1996, 1997 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,16 +80,16 @@ 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); @@ -99,15 +98,22 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, char *fromname, 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) { @@ -115,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; @@ -132,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) @@ -171,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); @@ -199,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 a6387023..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, 1997 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,51 +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 (np) - { - if ((np->dn_stat.st_mode & S_IPTRANS) - || fshelp_translated (&np->transbox)) - { - diskfs_nput (np); - error = EBUSY; - } - if (!S_ISDIR (np->dn_stat.st_mode)) - { - diskfs_nput (np); - error = ENOTDIR; - } - } 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; } - /* 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 ((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); + 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--; @@ -95,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 7a6ce5da..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, 1997 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 3dbb8ffc..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, 1997 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 @@ -40,8 +40,8 @@ service_paging_requests (any_t arg) for (;;) ports_manage_port_operations_multithread (pager_bucket, pager_demuxer, - 1000 * 60 * 2, 1000 * 60 * 10, - 1, MACH_PORT_NULL); + 1000 * 60 * 2, + 1000 * 60 * 10, 0); } void @@ -90,7 +90,21 @@ 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); diff --git a/libdiskfs/diskfs.c b/libdiskfs/diskfs.c deleted file mode 100644 index 934fd168..00000000 --- a/libdiskfs/diskfs.c +++ /dev/null @@ -1,2 +0,0 @@ -#define DISKFS_EI -#include "diskfs.h" diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h index e92158f4..2051e41d 100644 --- a/libdiskfs/diskfs.h +++ b/libdiskfs/diskfs.h @@ -1,5 +1,7 @@ /* Definitions for fileserver helper functions - Copyright (C) 1994, 1995, 1996, 1997 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 @@ -25,9 +27,12 @@ #include <hurd/fshelp.h> #include <hurd/iohelp.h> #include <idvec.h> +#include <features.h> -#ifndef DISKFS_EI -#define DISKFS_EI extern inline +#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 @@ -47,7 +52,7 @@ 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; @@ -75,11 +80,11 @@ struct node struct disknode *dn; - struct stat dn_stat; + 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; @@ -100,11 +105,15 @@ struct node struct conch conch; - struct dirmod *dirmod_reqs; + struct modreq *dirmod_reqs; + unsigned int dirmod_tick; + + struct modreq *filemod_reqs; + unsigned int filemod_tick; - off_t allocsize; + loff_t allocsize; - int cache_id; + ino64_t cache_id; int author_tracks_uid; }; @@ -118,11 +127,11 @@ 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; }; @@ -130,12 +139,13 @@ struct dirmod #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. */ @@ -146,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 @@ -168,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; @@ -191,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 @@ -199,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. */ @@ -262,7 +291,9 @@ extern int diskfs_default_sync_interval; 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 @@ -304,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); @@ -314,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); @@ -353,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 @@ -365,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 @@ -373,13 +406,13 @@ 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 @@ -484,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 @@ -524,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 @@ -548,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 @@ -569,156 +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). */ -DISKFS_EI 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. */ -DISKFS_EI 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. */ -DISKFS_EI 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. */ -DISKFS_EI 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 */ -DISKFS_EI 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). */ -DISKFS_EI 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); -} +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 @@ -730,7 +638,7 @@ diskfs_nrele_light (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); @@ -743,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. */ @@ -757,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 @@ -795,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); @@ -809,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 @@ -821,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 @@ -831,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. @@ -844,7 +767,7 @@ 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); @@ -861,12 +784,32 @@ error_t diskfs_start_protid (struct peropen *po, struct protid **cred); 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. The initial values for the root_parent, shadow_root, and - shadow_root_parent fields are copied from CONTEXT if it's non-zero, - otherwise zerod. */ -struct peropen *diskfs_make_peropen (struct node *np, int flags, - struct peropen *context); +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 @@ -874,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); @@ -889,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 @@ -902,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 @@ -925,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 @@ -960,12 +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); /* 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, unsigned *argz_len); +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 @@ -992,7 +948,7 @@ 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 *); @@ -1005,6 +961,27 @@ 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 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/fhandle.h b/libdiskfs/fhandle.h index 9b1c7105..bd827d84 100644 --- a/libdiskfs/fhandle.h +++ b/libdiskfs/fhandle.h @@ -1,6 +1,6 @@ /* File handle type (for nfs server support) - Copyright (C) 1997 Free Software Foundation + Copyright (C) 1997,99 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -9,7 +9,7 @@ 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,12 +22,15 @@ #define __FHANDLE_H__ /* Must be exactly 28 bytes long */ -struct diskfs_fhandle +union diskfs_fhandle { - int filler1; - int cache_id; - long gen; - int filler2[28 - sizeof (int) + sizeof (int) + sizeof (long)]; + unsigned char bytes[28]; + struct + { + int pad1; + int cache_id; + unsigned int gen; + } data; }; #endif /* __FHANDLE_H__ */ diff --git a/libdiskfs/file-chauthor.c b/libdiskfs/file-chauthor.c index 753ee561..6e49c53f 100644 --- a/libdiskfs/file-chauthor.c +++ b/libdiskfs/file-chauthor.c @@ -34,6 +34,9 @@ dithkfth_TH_file_chauthor (struct protid *cred, { 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 d70cc712..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 @@ -29,6 +29,12 @@ diskfs_S_file_chflags (struct protid *cred, 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 66c51a32..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, 1997 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 @@ -23,29 +23,34 @@ diskfs_S_file_chmod (struct protid *cred, mode_t mode) { mode &= ~(S_IFMT | S_ISPARE | S_ITRANS); - + CHANGE_NODE_FIELD (cred, - ({ - 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)); - 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 0a614338..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,26 +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 = fshelp_isowner (&np->dn_stat, cred->user); if (err - || ((!idvec_contains (cred->user->uids, uid) - || !idvec_contains (cred->user->gids, gid)) + || (((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 (np->author_tracks_uid) - np->dn_stat.st_author = uid; + 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 1482f1b0..452240c0 100644 --- a/libdiskfs/file-exec.c +++ b/libdiskfs/file-exec.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1993, 1994, 1995, 1996, 1997 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,37 +53,60 @@ 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) @@ -112,26 +135,69 @@ diskfs_S_file_exec (struct protid *cred, #endif if (! err) - err = diskfs_create_protid (diskfs_make_peropen (np, O_READ, cred->po), - cred->user, &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]); @@ -139,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 24f2f461..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. @@ -27,7 +26,7 @@ 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 = 0; @@ -46,7 +45,7 @@ diskfs_S_file_get_fs_options (struct protid *cred, 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); diff --git a/libdiskfs/file-get-trans.c b/libdiskfs/file-get-trans.c index a9a94e54..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, 1996 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,10 +104,10 @@ 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; @@ -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-getcontrol.c b/libdiskfs/file-getcontrol.c index 4f1ae23a..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 (!idvec_contains (cred->user->uids, 0)) - 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 1b23b80c..2dcf68e5 100644 --- a/libdiskfs/file-getfh.c +++ b/libdiskfs/file-getfh.c @@ -1,6 +1,6 @@ /* Return a file handle (for nfs server support) - Copyright (C) 1997 Free Software Foundation + Copyright (C) 1997,99,2002 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -9,7 +9,7 @@ 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,33 +26,33 @@ /* Return an NFS file handle for CRED in FH & FN_LEN. */ error_t -diskfs_S_file_getfh (struct protid *cred, char **fh, unsigned *fh_len) +diskfs_S_file_getfh (struct protid *cred, char **fh, size_t *fh_len) { struct node *node; - struct diskfs_fhandle *f; + 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 (struct diskfs_fhandle)) - vm_allocate (mach_task_self (), (vm_address_t *) fh, - sizeof (struct diskfs_fhandle), 1); - *fh_len = sizeof (struct diskfs_fhandle); - - f = (struct diskfs_fhandle *)*fh; + 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->cache_id = node->cache_id; - f->gen = node->dn_stat.st_gen; + f = (union diskfs_fhandle *) *fh; - f->filler1 = 0; - bzero (f->filler2, sizeof f->filler2); + bzero (f, sizeof *f); + f->data.cache_id = node->cache_id; + f->data.gen = node->dn_stat.st_gen; mutex_unlock (&node->lock); diff --git a/libdiskfs/file-inv-trans.c b/libdiskfs/file-inv-trans.c deleted file mode 100644 index d3014164..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->dn_stat.st_mode & S_IPTRANS) - || 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->user->uids->ids, cred->user->uids->num, - cred->user->gids->ids, cred->user->gids->num, - 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->user, &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 index 2520c8a2..e659bcf0 100644 --- a/libdiskfs/file-reparent.c +++ b/libdiskfs/file-reparent.c @@ -1,6 +1,6 @@ /* Reparent a file - Copyright (C) 1997 Free Software Foundation + Copyright (C) 1997,2002 Free Software Foundation Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -30,6 +30,7 @@ diskfs_S_file_reparent (struct protid *cred, mach_port_t parent, error_t err; struct node *node; struct protid *new_cred; + struct peropen *new_po; if (! cred) return EOPNOTSUPP; @@ -37,21 +38,23 @@ diskfs_S_file_reparent (struct protid *cred, mach_port_t parent, node = cred->po->np; mutex_lock (&node->lock); - err = diskfs_create_protid (diskfs_make_peropen (node, cred->po->openstat, - cred->po), - cred->user, &new_cred); + 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) - { - mutex_lock (&new_cred->po->shadow_root->lock); - diskfs_nput (new_cred->po->shadow_root); - } + 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); + mach_port_deallocate (mach_task_self (), + new_cred->po->shadow_root_parent); /* And install PARENT instead. */ new_cred->po->shadow_root = node; 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 8c1ccdfd..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; @@ -60,7 +57,8 @@ diskfs_S_file_set_translator (struct protid *cred, 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) @@ -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 6f4f53c5..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 @@ -28,10 +28,30 @@ diskfs_S_file_utimes (struct protid *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 56766ed4..2fe9495e 100644 --- a/libdiskfs/fsys-getfile.c +++ b/libdiskfs/fsys-getfile.c @@ -1,6 +1,6 @@ /* Return the file for a given handle (for nfs server support) - Copyright (C) 1997 Free Software Foundation + Copyright (C) 1997,99,2001,02 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -9,7 +9,7 @@ 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. @@ -37,45 +37,46 @@ diskfs_S_fsys_getfile (mach_port_t fsys, int flags; error_t err; struct node *node; - struct diskfs_fhandle *f; + const union diskfs_fhandle *f; struct protid *new_cred; - struct idvec *uvec, *gvec; + 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 (struct diskfs_fhandle)) + if (handle_len != sizeof *f) { ports_port_deref (pt); return EINVAL; } - f = (struct diskfs_fhandle *) handle; + f = (const union diskfs_fhandle *) handle; - err = diskfs_cached_lookup (f->cache_id, &node); + err = diskfs_cached_lookup (f->data.cache_id, &node); if (err) { ports_port_deref (pt); return err; } - if (node->dn_stat.st_gen != f->gen) + if (node->dn_stat.st_gen != f->data.gen) { diskfs_nput (node); ports_port_deref (pt); return ESTALE; } - - uvec = make_idvec (); - gvec = make_idvec (); - - idvec_set_ids (uvec, uids, nuids); - idvec_set_ids (gvec, gids, ngids); - user = iohelp_create_iouser (uvec, gvec); - + + 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; @@ -86,14 +87,19 @@ diskfs_S_fsys_getfile (mach_port_t fsys, && ! diskfs_check_readonly ()) flags |= O_WRITE; - err = diskfs_create_protid (diskfs_make_peropen (node, flags, 0), - user, &new_cred); - + 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); diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c index 2a18810c..e083032e 100644 --- a/libdiskfs/fsys-getroot.c +++ b/libdiskfs/fsys-getroot.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1993, 1994, 1995, 1996, 1997 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,22 +31,28 @@ 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 *newpi; + struct peropen *newpo; struct iouser user; - struct peropen peropen_context = { root_parent: dotdot }; + 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; @@ -61,9 +67,9 @@ diskfs_S_fsys_getroot (fsys_t controlport, 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; @@ -73,7 +79,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, && !(flags & O_NOTRANS)) { error = fshelp_fetch_root (&diskfs_root_node->transbox, - &peropen_context, dotdot, &user, flags, + &peropen_context, dotdot, &user, flags, _diskfs_translator_callback1, _diskfs_translator_callback2, retry, retryname, returned_port); @@ -86,17 +92,17 @@ diskfs_S_fsys_getroot (fsys_t controlport, *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) @@ -112,7 +118,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, drop_idvec (); return error; } - + if (pathbuf[0] == '/') { *retry = FS_RETRY_MAGICAL; @@ -134,24 +140,24 @@ diskfs_S_fsys_getroot (fsys_t controlport, } } - 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; - + if (!error && (flags & O_READ)) error = fshelp_access (&diskfs_root_node->dn_stat, S_IREAD, &user); - + if (!error && (flags & O_EXEC)) 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 + else error = fshelp_access (&diskfs_root_node->dn_stat, S_IWRITE, &user); } @@ -163,7 +169,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, drop_idvec (); return error; } - + if ((flags & O_NOATIME) && (fshelp_isowner (&diskfs_root_node->dn_stat, &user) == EPERM)) @@ -171,22 +177,25 @@ diskfs_S_fsys_getroot (fsys_t controlport, flags &= ~OPENONLY_STATE_MODES; - error = - diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, flags, - &peropen_context), - &user, &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); diff --git a/libdiskfs/fsys-options.c b/libdiskfs/fsys-options.c index 1a1786b9..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. @@ -107,7 +107,7 @@ diskfs_S_fsys_get_options (fsys_t fsys, 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); 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 d2802db5..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_disk_name ?: "-"); - err = startup_request_notification (init, notify, - MACH_MSG_TYPE_MAKE_SEND, 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-identity.c b/libdiskfs/io-identity.c index 39ca3706..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, 1997 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,7 +28,7 @@ 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; @@ -36,7 +36,7 @@ diskfs_S_io_identity (struct protid *cred, if (!cred) return EOPNOTSUPP; - + np = cred->po->np; mutex_lock (&np->lock); inum = np->dn_stat.st_ino; @@ -44,22 +44,24 @@ diskfs_S_io_identity (struct protid *cred, 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 (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; *fsystype = MACH_MSG_TYPE_MAKE_SEND; - *fileno = np->dn_stat.st_ino; + *fileno = inum; } - + 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 80c103d8..787c0eae 100644 --- a/libdiskfs/io-read.c +++ b/libdiskfs/io-read.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996, 1997 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; @@ -60,7 +60,7 @@ 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 @@ -71,21 +71,23 @@ diskfs_S_io_read (struct protid *cred, 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); - } - } + { + /* 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. */ @@ -100,7 +102,7 @@ diskfs_S_io_read (struct protid *cred, 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 3fc780d2..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 @@ -26,11 +26,12 @@ diskfs_S_io_reauthenticate (struct protid *cred, struct protid *newcred; error_t err; mach_port_t newright; + struct iouser *user; if (cred == 0) return EOPNOTSUPP; - /* 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); @@ -43,19 +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); + 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); + } - diskfs_finish_protid (newcred, iohelp_reauth (diskfs_auth_server_port, - rend_port, newright, 1)); - mach_port_deallocate (mach_task_self (), rend_port); mach_port_deallocate (mach_task_self (), newright); - + mutex_unlock (&cred->po->np->lock); ports_port_deref (newcred); - return 0; + return err; } diff --git a/libdiskfs/io-restrict-auth.c b/libdiskfs/io-restrict-auth.c index 0a3a5021..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,41 +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; - struct idvec *uvec, *gvec; + struct iouser *user; struct protid *newpi; - int i; - + if (!cred) return EOPNOTSUPP; - uvec = make_idvec (); - gvec = make_idvec (); - - if (idvec_contains (cred->user->uids, 0)) - { - /* CRED has root access, and so may use any ids. */ - idvec_set_ids (uvec, uids, nuids); - idvec_set_ids (gvec, gids, ngids); - } - else - { - /* Otherwise, use any of the requested ids that CRED already has. */ - for (i = 0; i < cred->user->uids->num; i++) - if (listmember (uids, cred->user->uids->ids[i], nuids)) - idvec_add (uvec, cred->user->uids->ids[i]); - for (i = 0; i < cred->user->gids->num; i++) - if (listmember (gids, cred->user->gids->ids[i], ngids)) - idvec_add (gvec, cred->user->gids->ids[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, iohelp_create_iouser (uvec, gvec), - &newpi); + err = diskfs_create_protid (cred->po, user, &newpi); if (! err) { *newport = ports_get_right (newpi); @@ -78,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 fb84fa68..59f3187e 100644 --- a/libdiskfs/io-stat.c +++ b/libdiskfs/io-stat.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1995, 1996, 1997 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 @@ -25,11 +25,10 @@ diskfs_S_io_stat (struct protid *cred, io_statbuf_t *statbuf) { struct node *np; - mach_port_t atrans; if (!cred) return EOPNOTSUPP; - + np = cred->po->np; mutex_lock (&np->lock); @@ -39,17 +38,13 @@ diskfs_S_io_stat (struct protid *cred, 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_fetch_control (&np->transbox, &atrans) == 0 - && atrans != MACH_PORT_NULL) - { - statbuf->st_mode |= S_IATRANS; - mach_port_deallocate (mach_task_self (), atrans); - } + 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-write.c b/libdiskfs/io-write.c index e84bdecb..a3c4199e 100644 --- a/libdiskfs/io-write.c +++ b/libdiskfs/io-write.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996, 1997 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; @@ -64,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) @@ -84,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/lookup.c b/libdiskfs/lookup.c index df8b4bff..1f2a2588 100644 --- a/libdiskfs/lookup.c +++ b/libdiskfs/lookup.c @@ -1,5 +1,5 @@ /* Wrapper for diskfs_lookup_hard - Copyright (C) 1996, 1997 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,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ #include "priv.h" +#include <string.h> static struct { @@ -35,6 +36,11 @@ static spin_lock_t cm_lock = SPIN_LOCK_INITIALIZER; 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 @@ -73,11 +79,10 @@ static spin_lock_t cm_lock = SPIN_LOCK_INITIALIZER; 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, + + 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; @@ -93,6 +98,35 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, return ENOTDIR; } + /* 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) { @@ -139,7 +173,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, diskfs_null_dirstat (ds); } else - { + { err = diskfs_lookup_hard (dp, name, type, np, ds, cred); spin_lock (&cm_lock); @@ -149,7 +183,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, cache_misses.absent++; else if (err) cache_misses.errors++; - else + else cache_misses.present++; if (name[0] == '.') { @@ -163,18 +197,29 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, if (err && err != ENOENT) return err; - + if (type == RENAME || (type == CREATE && err == ENOENT) || (type == REMOVE && err != ENOENT)) { - error_t err2 = fshelp_checkdirmod (&dp->dn_stat, - (err || !np) ? 0 : &(*np)->dn_stat, - cred->user); + 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) - diskfs_nput (*np); + { + if (*np == dp) + diskfs_nrele (*np); + else + diskfs_nput (*np); + *np = 0; + } return err2; } } @@ -183,8 +228,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, diskfs_enter_lookup_cache (dp, *np, name); else if (type == LOOKUP && err == ENOENT) diskfs_enter_lookup_cache (dp, 0, 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 808c16f4..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. @@ -70,7 +70,7 @@ 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) { @@ -79,8 +79,8 @@ find_cache (struct node *dir, const char *name, size_t name_len) /* 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 (i = 0, c = lookup_cache.mru; - c && c->name_len; + 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 @@ -89,18 +89,18 @@ find_cache (struct node *dir, const char *name, size_t name_len) c->stati = i / 100; return c; } - + return 0; } /* 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; @@ -127,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) { @@ -179,13 +179,13 @@ register_pos_hit (int n) 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++; @@ -198,10 +198,10 @@ register_miss () 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)); @@ -231,10 +231,10 @@ diskfs_check_lookup_cache (struct node *dir, char *name) { struct node *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); @@ -257,7 +257,7 @@ diskfs_check_lookup_cache (struct node *dir, char *name) return err ? 0 : np; } } - + register_miss (); spin_unlock (&cache_lock); diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c index 06a484d8..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,6 +54,7 @@ diskfs_create_node (struct node *dir, { if (name) diskfs_drop_dirstat (dir, ds); + *newnode = NULL; return err; } @@ -66,9 +75,40 @@ diskfs_create_node (struct node *dir, if (np->author_tracks_uid) np->dn_stat.st_author = newuid; - newgid = dir->dn_stat.st_gid; - if (!idvec_contains (cred->user->gids, newgid)) - mode &= ~S_ISGID; + if (!_diskfs_no_inherit_dir_group) + { + newgid = dir->dn_stat.st_gid; + 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; @@ -90,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) @@ -100,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); @@ -115,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 7c30f946..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. */ @@ -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 d3da031d..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. @@ -26,7 +26,7 @@ #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; @@ -35,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 91ec169b..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,7 +22,7 @@ #include "priv.h" error_t -diskfs_append_args (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, size_t *argz_len) { 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 47cebeb7..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. @@ -32,7 +32,8 @@ std_runtime_options[] = 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. */ @@ -53,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) @@ -71,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; @@ -86,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; @@ -106,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; diff --git a/libdiskfs/opts-std-startup.c b/libdiskfs/opts-std-startup.c index 1488fdb5..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. @@ -23,9 +24,13 @@ #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; @@ -36,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} }; @@ -55,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; @@ -77,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; 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 62a5a13b..d37516c1 100644 --- a/libdiskfs/peropen-make.c +++ b/libdiskfs/peropen-make.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1997 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,10 +20,14 @@ /* Create and return a new peropen structure on node NP with open flags FLAGS. */ -struct peropen * -diskfs_make_peropen (struct node *np, int flags, struct peropen *context) +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; @@ -47,8 +51,14 @@ diskfs_make_peropen (struct node *np, int flags, struct peropen *context) 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 4b90aef5..6974e86a 100644 --- a/libdiskfs/peropen-rele.c +++ b/libdiskfs/peropen-rele.c @@ -34,10 +34,8 @@ diskfs_release_peropen (struct peropen *po) mach_port_deallocate (mach_task_self (), po->root_parent); if (po->shadow_root && po->shadow_root != po->np) - { - mutex_lock (&po->shadow_root->lock); - diskfs_nput (po->shadow_root); - } + diskfs_nrele (po->shadow_root); + if (po->shadow_root_parent) mach_port_deallocate (mach_task_self (), po->shadow_root_parent); 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-noports.c b/libdiskfs/ports-noports.c deleted file mode 100644 index cddd8f00..00000000 --- a/libdiskfs/ports-noports.c +++ /dev/null @@ -1,27 +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 no ports outstanding. */ -void -ports_no_live_ports () -{ - diskfs_sync_everything (1); - exit (0); -} 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 eab1ed43..07464d56 100644 --- a/libdiskfs/priv.h +++ b/libdiskfs/priv.h @@ -1,5 +1,7 @@ /* Private declarations for fileserver library - Copyright (C) 1994, 1995, 1996, 1997 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; \ diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c index 8f45cfd5..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. */ @@ -41,20 +42,17 @@ diskfs_start_protid (struct peropen *po, struct protid **cred) void diskfs_finish_protid (struct protid *cred, struct iouser *user) { + error_t err; + if (!user) - { - uid_t zero = 0; - /* Create one for root */ - user = iohelp_create_iouser (make_idvec (), make_idvec ()); - idvec_set_ids (user->uids, &zero, 1); - idvec_set_ids (user->gids, &zero, 1); - cred->user = user; - } + err = iohelp_create_simple_iouser (&cred->user, 0, 0); else - cred->user = iohelp_dup_iouser (user); + 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 for USER. diff --git a/libdiskfs/protid-rele.c b/libdiskfs/protid-rele.c index 10ff6890..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. */ @@ -30,8 +30,7 @@ diskfs_protid_rele (void *arg) 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 5d5d9ba0..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> @@ -26,12 +26,14 @@ #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 @@ -41,10 +43,10 @@ diskfs_check_readonly () err = diskfs_set_hypermetadata (1, 0); if (err) { - error (0, 0, + error (0, 0, "%s: MEDIA NOT WRITABLE; switching to READ-ONLY", diskfs_disk_name ?: "-"); - diskfs_readonly = 1; + diskfs_hard_readonly = diskfs_readonly = 1; return 1; } _diskfs_diskdirty = 1; @@ -62,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); @@ -71,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 9a78efa1..283b184f 100644 --- a/libdiskfs/trans-callback.c +++ b/libdiskfs/trans-callback.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1995, 1996, 1997 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,7 +26,7 @@ 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; @@ -36,7 +36,10 @@ _diskfs_translator_callback1_fn (void *cookie1, void *cookie2, 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; @@ -54,17 +57,25 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2, { struct node *np = cookie1; struct protid *cred; + struct peropen *po; error_t err; - struct idvec *uids, *gids; + 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); + } - uids = make_idvec (); - gids = make_idvec (); - idvec_set_ids (uids, &np->dn_stat.st_uid, 1); - idvec_set_ids (gids, &np->dn_stat.st_gid, 1); + iohelp_free_iouser (user); - err = - diskfs_create_protid (diskfs_make_peropen (np, flags, cookie2), - iohelp_create_iouser (uids, gids), &cred); if (! err) { *underlying = ports_get_right (cred); |