diff options
Diffstat (limited to 'ufs')
-rw-r--r-- | ufs/ChangeLog | 1591 | ||||
-rw-r--r-- | ufs/Makefile | 17 | ||||
-rw-r--r-- | ufs/alloc.c | 101 | ||||
-rw-r--r-- | ufs/consts.c | 10 | ||||
-rw-r--r-- | ufs/devio.c | 70 | ||||
-rw-r--r-- | ufs/dir.c | 314 | ||||
-rw-r--r-- | ufs/dir.h | 13 | ||||
-rw-r--r-- | ufs/hyper.c | 85 | ||||
-rw-r--r-- | ufs/inode.c | 335 | ||||
-rw-r--r-- | ufs/main.c | 105 | ||||
-rw-r--r-- | ufs/mapbuf.c | 36 | ||||
-rw-r--r-- | ufs/pager.c | 90 | ||||
-rw-r--r-- | ufs/pokeloc.c | 2 | ||||
-rw-r--r-- | ufs/sizes.c | 40 | ||||
-rw-r--r-- | ufs/ufs.h | 60 | ||||
-rw-r--r-- | ufs/xinl.c | 2 |
16 files changed, 640 insertions, 2231 deletions
diff --git a/ufs/ChangeLog b/ufs/ChangeLog deleted file mode 100644 index 2ccd6c11..00000000 --- a/ufs/ChangeLog +++ /dev/null @@ -1,1591 +0,0 @@ -Tue Jul 23 15:58:28 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (write_node, read_disknode): `struct timespec' now uses - a field prefix of `tv_'. - -Sat Jul 6 16:14:10 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (ufs_version): Variable removed. - -Sat Jul 6 12:45:36 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (read_disknode): Don't set allocsize based on st->size - for kludged symlinks. - - * sizes.c (diskfs_truncate): Call record_poke after truncating a - kludged symlink. - -Wed Jul 3 13:27:04 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * main.c: Include <argz.h>. - (startup_parents, runtime_parents): Declare const. - -Tue Jun 25 14:02:02 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (diskfs_get_options): Include `--compat=' in options. - -Mon Jun 24 16:59:12 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): Use diskfs_check_readonly instead of - diskfs_readonly. - (diskfs_dirempty): Likewise. - - * dir.c (diskfs_lookup_hard): Use diskfs_check_readonly instead of - diskfs_readonly. - (diskfs_dirempty): Likewise. - * inode.c (diskfs_cached_lookup): Likewise. - (read_symlink_hook): Likewise. - * sizes.c (diskfs_truncate): Call diskfs_check_readonly. - (diskfs_grow): Likewise. - * hyper.c (diskfs_set_hypermetadata): If CLEAN is not set, make - sure we clear the clean bit on disk. Always call sync_disk (with - appropriate WAIT). - (diskfs_readonly_changed): Don't do set_hypermetadata here. - (copy_sblock): Don't track clean state here. - - * pager.c (diskfs_shutdown_pager): Don't shutdown DISKPAGER ever, - just sync it instead. - -Sat Jun 22 17:45:34 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (diskfs_get_options): New function. - (options): Make const. - -Fri Jun 21 01:32:09 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (parse_opt): Handle runtime invalid selection of 4.2 mode. - Save select mode until we're done to correctly deal with external - errors at runtime. - (startup_parents, startup_argp, runtime_parents, runtime_argp): - New variables. - (main): Argp vars made global. - (argp_parents): diskfs_device_startup_argp --> - &diskfs_std_device_startup_argp. - -Sat Jun 15 13:57:27 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (options): New variable. - (parse_opt): New function. - (main): Parse ufs-specific options too. - <string.h>: New include. - -Fri May 10 09:29:03 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (diskfs_set_statfs): Fix one reference to old name of ST - member. - -Thu May 9 11:54:13 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (ufs.static ufs): s/ioserver/iohelp/g - * ufs.h: ioserver.h -> iohelp.h. - - * inode.c (diskfs_set_statfs): Use and fill in new statfs - structure. - -Mon May 6 14:23:54 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * main.c (ufs_version): Upgrade to 0.0. - -Fri May 3 09:15:33 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (block_extended): Rewrite code that moves pages - to be more efficient, and not deadlock too, using unlocked - pagein permission feature (read "hack"). Return value - now indicates whether we expect a sync. - (diskfs_grow): If a call to block_extended returns nonzero, - then sync the file before returning. - * pager.c (diskfs_get_filemap): Initialize - UPI->allow_unlocked_pagein and UPI->unlocked_pagein_length. - (unlocked_pagein_lock): New variable. - (find_address): New parameter `isread'; all callers changed. - If ISREAD and we are in the unlocked pagein region, don't - attempt to acquire NP->dn->allocptrlock. - * ufs.h (struct user_pager_info): New members - `allow_unlocked_pagein' and `unlocked_pagein_length'. - (unlocked_pagein_lock): New variable. - -Thu May 2 10:56:10 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (offer_data): Offer pages at ADDR each time through the - loop, not the same page over and over. - (block_extended): When moving data, sync in-core pager both before - reading from disk and after providing data to kernel. - (diskfs_grow): Always call block_extended or offer_data before - adjusting block pointer. - -Tue Apr 30 13:38:42 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (diskfs_grow): In last offer_data, don't offer a block - number as an address. - -Fri Apr 26 15:35:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (makemode): Now `servers'. - (targets): Renamed from `target'; now include ufs.static. - (ufs.static-LDFLAGS): Renamed from `LDFLAGS'. - (ufs.static): Depend on same things as `ufs'. - (include ../Makeconf): Must come before dependency information. - -Wed Apr 24 14:05:48 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.h (DIRECT_NAMLEN) [! LITTLE_ENDIAN]: Deal correctly with the - case where it was written on a little endian machine without the - extension. - (DIRECT_NAMLEN) [LITTLE_ENDIAN]: Deal with case correctly where it - was written without the extension on a big endian machine. - * dir.c (dirscanblock): Use read/write_disk_entry when reading or - writing fields from directory entries. - (diskfs_direnter_hard): Likewise. - (diskfs_dirremove_hard): Likewise. - (diskfs_dirrewrite_hard): Likewise. - (diskfs_get_directs): Likewise. - (diskfs_dirempty): Likewise. - (count_dirents): Likewise. - -Tue Apr 23 11:28:42 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_dirempty): node_update -> diskfs_node_update. - - * hyper.c (swab_sblock, swab_csums): New functions. - (get_hypermetadata): If this is a swapped filesystem, set swab_disk. - Also swap csum and sblock after reading them. - (diskfs_set_hypermetadata): If swab_disk, swap the csums back before - writing them. - (copy_sblock): If swab_disk, swap the sblock before writing it. - * ufs.h (swab_disk): New variable. - (swab_short, swab_long, swab_long_long): New functions. - (read_disk_entry, write_disk_entry): New macros. - * alloc.c (ffs_realloccg): Use read/write_disk_entry when - reading/writing on-disk inode fields. - * bmap.c (fetch_indir_spec): Likewise. - * inode.c (read_disknode): Likewise. - (write_node): Likewise. - (diskfs_set_translator): Likewise. - (diskfs_get_translator): Likewise. - (diskfs_S_file_get_storage_info): Likewise. - * sizes.c (diskfs_truncate): Likewise. - (diskfs_grow): Likewise. - * pager.c (pager_unlock_page): Likewise. - * bmap.c (fetch_indir_spec): Use read/write_disk_entry when - reading/writing on-disk indirect blocks. - * sizes.c (diskfs_truncate): Likewise. - (indir_release): Likewise. - (diskfs_grow): Likewise. - * pager.c (pager_unlock_page): Likewise. - * alloc.c: Include <string.h> - (ffs_blkpref): Use read_disk_entry when reading from BAP array. - (swab_cg, read_cg, release_cg): New functions. - (ffs_fragextend, ffs_alloccg, ffs_nodealloccg, ffs_blkfree, - diskfs_free_node): Use new cg access functions. - -Thu Apr 18 14:50:30 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (diskfs_grow): New variable `pagerpt'. - (offer_zeroes, block_extended): New functions. - (diskfs_grow): In initializing newly allocated data disk blocks with - zeroes, use less aggressive offer_zeroes instead of immediate - synchronous writes. After ffs_realloccg succeeds, use - block_extended to handle the magic. Get rid of old poke calls. - * alloc.c (ffs_realloccg): If we are allocating a new block, don't - actually free the old one here. - * sizes.c (diskfs_grow): New variable `pagerpt'. - (offer_zeroes, block_extended): New functions. - (diskfs_grow): In initializing newly allocated data disk blocks - with zeroes, use less aggressive offer_zeroes instead of immediate - synchronous writes. After ffs_realloccg succeeds, use - block_extended to handle the magic. Get rid of old poke calls. - -Tue Apr 16 15:20:07 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): Set atime appropriately, and sync - the new atime if we are running synchronously (!). - (diskfs_dirempty): Likewise. - (diskfs_direnter_hard): Set mtime appropriately. - (diskfs_dirremove_hard): Likewise. - (diskfs_dirrewrite_hard): Likewise. - - * inode.c (diskfs_write_disknode): Only do sync if WAIT is set. - -Thu Apr 4 16:39:22 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_cached_lookup): Intialize NP->cache_id *after* - NP exists. - -Wed Apr 3 16:03:51 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c (diskfs_cached_lookup): Renamed from `iget'. All - callers changed. Initialize NP->cache_id. - -Fri Mar 29 16:52:31 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): Cast DI->di_shortlink to correct type - before adding a character count to it. - -Mon Mar 25 13:08:10 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_null_dirstat): New function. - -Fri Mar 22 23:43:53 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (read_symlink_hook): Only set NP's atime if !readonly. - -Wed Mar 20 14:36:31 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (diskfs_lookup_hard): Don't do initial or final permission - checking here. - * dir.c (diskfs_dirrewrite_hard): Renamed from diskfs_dirrewrite. - No longer call modification tracking routines. - (diskfs_dirremove_hard): Renamed from diskfs_dirremove. No longer call - modification tracking routines. - (diskfs_direnter_hard): Renamed from diskfs_direnter. No longer call - modification tracking routines. - (diskfs_lookup_hard): Renamed from diskfs_lookup. - -Mon Mar 18 19:50:41 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Pass new arg to argp_parse. - -Mon Mar 18 12:33:06 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pager.c (diskfs_max_user_pager_prot) [add_pager_max_prot]: - (a == b) ? 1 : 0 ====> (a == b). - -Fri Feb 23 15:27:05 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> - - * hyper.c (get_hypermetadata): Use diskfs_device_arg in unclean msgs. - -Wed Feb 21 05:57:12 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> - - * hyper.c: Implement proper handling of the filesystem `clean bit'. - (ufs_clean): New variable. - (get_hypermetadata): Set it from the fs_clean flag. If not clean, - complain and force read-only. Complain when ignoring COMPAT_BSD42. - (diskfs_set_hypermetadata): Set the clean flag in the superblock - when CLEAN and fs was clean to start with. - (copy_sblock): Remove bogus clean flag frobnication. - -Fri Feb 16 17:05:36 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Check error return from diskfs_init_diskfs. - -Sat Jan 6 11:50:14 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * ufs.h (diskpager, diskpagerport, disk_image): Variables removed. - Include <hurd/diskfs-pager.h> instead. - (sync_disk_blocks): Use `disk_pager' in place of `diskpager->p'. - * pager.c (diskfs_shutdown_pager, diskfs_sync_everything): Use - `disk_pager' in place of `diskpager->p'. - (create_disk_pager): Rewritten using disk_pager_setup. - * pokeloc.c (sync_disk): Use `disk_pager' in place of `diskpager->p'. - * sizes.c (indir_release): Likewise. - * main.c (diskfs_reload_global_state): Likewise. - -Thu Jan 4 19:10:11 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (main): Don't map disk image here; create_disk_pager now - does it. - - * hyper.c (get_hypermetadata, copy_sblock): Don't put - diskfs_catch_exception () inside assert, bonehead! Use - assert_perror on a variable of its result. - -Mon Jan 1 16:38:14 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * pager.c (pager_unlock_page): When allocating block in direct - array, clear it synchronously just like we do when it goes in the - indirect array. - -Thu Nov 9 14:01:30 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * dir.c (struct dirstat): New member `nbytes'. - (dirscanblock): If DS->type is COMPRESS, still look - for TAKE/SHRINK possibilities. Also, if it's COMPRESS, - still look to see if the current block can be compressed - with fewer byte copies. - -Sun Nov 5 02:08:38 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Add flags arg to diskfs_startup_diskfs call. - -Sat Nov 4 20:01:58 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_S_file_get_storage_info): Add FLAGS argument. - -Thu Oct 19 12:50:11 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * pager.c (diskfs_max_user_pager_prot): Return what we discovered, - instead of 1. - - * dir.c (diskfs_lookup, diskfs_dirempty): Give diskfs_get_filemap - a protection arg. - * sizes.c (diskfs_truncate, diskfs_grow): Ditto. - - * hyper.c (diskfs_readonly_changed): Give the 2nd arg to - vm_protect an appropiate type. - - * pager.c (diskfs_max_user_pager_prot): Stop iterating early if poss. - -Wed Oct 18 16:28:42 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * ufs.h (struct user_pager_info): Add max_prot field. - * pager.c (diskfs_get_filemap): Add PROT parameter, & use it. - (diskfs_pager_users): Split out block_caching & enable_caching. - (block_caching, enable_caching): New function. - (diskfs_max_user_pager_prot): New function. - - * main.c (main): Always include VM_PROT_WRITE in max prot. - * hyper.c (diskfs_readonly_changed): Change the protection of - DISK_IMAGE to reflect the new state. Clear SBLOCK_DIRTY if readonly. - - * inode.c (read_disknode): Bother to set the allocsize field. - - * ufs.h (struct rwlock): Structure deleted. - (rwlock_init, rwlock_reader_unlock, rwlock_reader_lock, - rwlock_writer_lock, rwlock_writer_unlock): Functions deleted. - - -Tue Oct 17 14:49:43 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_node_reload): New function. - (iget): Move allocsize setting into read_disknode. - * pager.c (flush_node_pager): New function. - * ufs.h (zeroblock, sblock, csum): Declare extern. - (flush_node_pager, flush_pokes): New declarations. - * pokeloc.c (flush_pokes): New function. - * hyper.c (diskfs_readonly_changed): New function. - (get_hypermetadata): Move compat_mode futzing & disk size - validation here from main. - (zeroblock, sblock, csum): Define (were common). - (get_hypermetadata): Only allocate SBLOCK if not already done. - Deallocate any old ZEROBLOCK and CSUM storage. - (diskfs_readonly_changed): New function. - * main.c (main): Move stuff into get_hypermetadata. - Writable init code moved to diskfs_readonly_changed. - (diskfs_reload_global_state): New function. - -Fri Oct 13 15:03:37 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (main): Use new handy diskfs routines and get rid of - tons of junk. Main should be almost all ufs-specific now. - (USAGE, usage, SHORT_OPTS, long_opts, parse_opt, trans_parse_arg): RIP. - (printf_lock): Initialize. - -Thu Oct 12 18:48:04 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * pager.c (pager_unlock_page, pager_write_page, pager_read_page): - Use diskfs_device_{read,write}_sync instead of dev_{read,write}_sync. - * hyper.c (diskfs_set_hypermetadata): Ditto. - * sizes.c (diskfs_grow): Ditto. - * pager.c (pager_report_extent): Calculate the pager size. - * ufs.h (dev_read_sync, dev_write_sync, dev_write, diskpagersize): - Decls removed. - - * Makefile (SRCS): Remove devio.c. - * ufs.h (ufs_device, ufs_device_name): Variables removed. - * inode.c (diskfs_S_file_get_storage_info): Use DISKFS_DEVICE - instead of UFS_DEVICE, and DISKFS_DEVICE_NAME instead of - UFS_DEVICE_NAME. - -Sat Oct 7 20:47:56 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * main.c (diskfs_init_completed): Function deleted (now in libdiskfs). - (thread_cancel): Function deleted. - -Fri Oct 6 17:30:23 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_S_file_get_storage_info): Change type of - ADDRESSES to off_t **, and add the BLOCK_SIZE parameter. - -Wed Oct 4 17:21:33 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * inode.c (diskfs_set_statfs): fsys_stb_bsize -> fsys_stb_iosize. - fsys_stb_fsize -> fsys_stb_bsize. - - * main.c (parse_opt): Rearrange slightly. - -Tue Sep 26 11:54:35 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * inode.c: Include <netinet/in.h>. - (diskfs_S_file_get_storage_info): New function. - * main.c (main): Delete var `devname'. Use `ufs_device_name' - throughout instead. - * ufs.h (ufs_device_name): New var. - -Fri Sep 22 13:22:42 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * hyper.c (get_hypermetadata): Use %Zd format for result of sizeof. - -Tue Sep 19 13:41:46 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (LDFLAGS): New variable. - -Wed Sep 13 12:30:23 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * dir.c (diskfs_lookup): Don't attempt to lock NP if NPP is not - set. Don't even set NP if NPP is not set; use INUM as "lookup - succeeded flag" instead. Lookups for REMOVE and RENAME now *must* - set NPP. - -Wed Sep 6 11:01:50 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * pager.c (diskfs_pager_users): Ignore the disk pager when seeing - if there are any active pagers. - -Mon Aug 28 17:07:36 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (ufs): Depend on ../libshouldbeinlibc/libshouldbeinlibc.a. - -Fri Aug 25 17:14:09 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): When freeing direct blocks mentioned - in a single indirect block, or single indirect blocks mentioned in - a double, only call the free routine (ffs_blkfree or - indir_release, respectively) if the block is actually allocated. - -Wed Aug 23 12:24:07 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (ufs): Add explicit dependencies. - (HURDLIBS, LDFLAGS, REMHDRS): Removed. - Rules associated with ../lib removed. - -Fri Jul 21 17:48:12 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * pager.c (diskfs_get_filemap): Drop initial reference created by - pager_create. - - * pager.c (diskfs_get_filemap): Avoid race with simultaneous - termination by looping until we win. - (pager_clear_user_data): Only clear UPI->np->dn->fileinfo if it - still points to us. - -Mon Jul 17 14:35:25 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * pager.c (thread_function): Don't have any global timeout here; - we don't use it anyhow. - -Thu Jul 6 15:42:52 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile: Removed dependencies that are now automatically - generated. - -Mon Jun 26 20:17:42 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c: Include <unistd.h>. - (diskfs_pager_users): New function. - -Thu Jun 22 11:41:04 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c (thread_function): Move thread_function to be non-local, - of course, because it needs to live even after create_disk_pager - returns. - - * main.c (thread_cancel): New function (HACK). - - * Makefile (HURDLIBS): Add libihash. - - * main.c (main): Have main thread exit when done instead of - calling a diskfs function. - -Wed Jun 21 12:20:01 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * ufs.h (user_pager_info): Removed members next and prevp. - * pager.c (pager_clear_user_data): Don't maintain pager linked - list. - (diskfs_get_filemap): Don't maintain pager linked list. - (pager_dropweak): New function. - (pager_traverse): Delete function. - (diskfs_shutdown_pager): Use ports_bucket_iterate instead of - pager_traverse. - (diskfs_sync_everything): Likewise. - - * pager.c (pager_bucket): New variable. - (create_disk_pager): Provide pager_bucket in call to pager_create. - (diskfs_get_filemap): Likewise. - (diskfs_file_update): Use ports reference calls directly instead - of pager wrappers. - (drop_pager_softrefs): Likewise. - (allow_pager_softrefs): Likewise. - (pager_traverse): Likewise. - (create_disk_pager): Initialize pager_bucket here and fork off - service thread for pager ports. - - * sizes.c (diskfs_truncate): Likewise. - - * dir.c (diskfs_lookup): Provide initialization for BUFLEN. - (diskfs_direnter): Move assignment out of if test. - -Tue Jun 20 11:48:06 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * sizes.c (diskfs_grow): Provide initialization of POKE_OFF. - * alloc.c (ffs_realloccg): Remove assignment from if tests. - * sizes.c (diskfs_truncate): Likewise. - * bmap.c (fetch_indir_spec): Likewise. - -Mon Jun 19 21:17:21 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * inode.c (diskfs_node_iterate): New function. - (write_all_disknodes): Use it. - -Wed Jun 14 16:18:55 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * inode.c (diskfs_get_translator): Conform to new memory usage - semantic. - -Sat May 20 00:17:30 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * main.c (trans_parse_args): Use options_parse & - diskfs_standard_startup_options to parse our translator options. - (usage): New function. - (parse_opt): New function. - - * Makefile (CPPFLAGS): Add -I../lib, to get include lib include files, - and $(CPPFLAGS-$(notdir $<)) to get file-specific cpp options. - Add a vpath for %.c to ../lib, so we can use source files from there. - -Mon May 15 13:14:48 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c (pager_clear_user_data): Doc fix. - -Sat May 13 05:04:11 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (OBJS): Remove exec_server_image.o. - (exec_server_image.o): Rule removed. - -Mon May 8 08:43:43 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * dir.c (diskfs_lookup): When looping back to try_again: because - we're looking up "..", be sure and trash the mapping we made of - the directory's pager -- otherwise the reference to the pager - never gets dropped and we can never free the node. - - * dir.c (diskfs_lookup): ds->type was being compared to LOOKING, which - value it can never have. Compare ds->stat against LOOKING instead. - - * pager.c (pager_clear_user_data): Don't die when called on the - disk pager. - - * inode.c (write_all_disknodes): Fix typo `alloc' --> `alloca'. - -Tue May 2 11:59:09 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * pager.c (pager_clear_user_data): Acquire pagerlistlock around - modifications to UPI->next/prevp list structure. - -Fri Apr 28 19:02:05 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (write_all_disknodes): We have to really lock the nodes - around the calls to diskfs_set_node_times and write_node; this in - turn forces us to have real refereces. - -Thu Apr 13 16:36:57 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * main.c (main): Don't abort if a std file descriptor is already open. - -Tue Apr 4 20:08:25 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_set_translator): When freeing passive - translator, account for blocks freed in NP->dn_stat.st_blocks. - -Fri Mar 31 13:43:27 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): Don't acquire writer lock on - NP->dn->allocptrlock until after forcing delayed copies through; - otherwise the pageins will deadlock attempting to get a reader - lock to service them. This is safe, because we only need - NP->allocsize here, and that can't change as long as we hold - NP->lock. - -Mon Mar 20 13:58:44 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * consts.c (diskfs_synchronous): New variable. - -Fri Mar 17 14:31:04 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * alloc.c (ffs_clusteracct): Make static. - (alloc_sync): New function. - (ffs_alloc): Call alloc_sync. - (ffs_realloccg): Likewise. - (diskfs_alloc_node): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - -Sat Jan 28 14:59:26 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (OBJS): Remove reference to libc's devstream.o. - -Fri Nov 11 11:45:38 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * hyper.c (diskfs_set_hypermetadata): Always use dev_write_sync to - avoid device_write bug that says you can't modify the buffer until - device_write returns. Also remember to deallocate BUF. - -Thu Nov 10 13:27:09 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * main.c (main): Issue decent prompt. - - * hyper.c (diskfs_set_hypermetadata): Copy CSUM into a - page-aligned page-sized buffer for disk write to avoid inane - kernel bug. - -Wed Nov 9 05:43:14 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * main.c (main): Behave more reasonably if we can't open DEVNAME. - -Tue Nov 8 00:03:20 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * pager.c (pager_write_page): Use %p for printing PAGER. - - * ufs.h: Declare copy_sblock. - -Wed Nov 2 16:06:10 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * hyper.c (copy_sblock): Don't copy csum here. - (diskfs_set_hypermetadata): Write csum directly to disk here. - -Thu Oct 27 20:58:08 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.c (diskfs_lookup): diskfs_get_filemap returns a send right, - so don't create an additional one here. - (diskfs_dirempty): Likewise. - * sizes.c (diskfs_truncate): Likewise. - (diskfs_grow): Likewise. - -Tue Oct 25 12:49:41 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * hyper.c (copy_sblock): Call record_poke for csum and superblock - after modifying them. - - * pager.c (diskfs_shutdown_pager): Call copy_sblock. - (diskfs_sync_everything): Likewise. - - * alloc.c (ffs_fragextend): Call record_poke for CG after - modifying it. Also set CSUM_DIRTY and SBLOCK_DIRTY. - (ffs_alloccg): Likewise. - (ffs_alloccgblk): Likewise. - (ffs_nodealloccg): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - -Fri Oct 7 01:32:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (diskfs_init_completed): Don't call _hurd_proc_init. - (saved_argv): Variable removed. - (main): Don't set saved_argv. Pass ARGV to diskfs_start_bootstrap. - -Wed Oct 5 22:18:46 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (read_disknode): If we are the bootstrap filesystem, - then getpid changes once proc starts up. So only call getpid - once, thus not allowing st_dev values to mysteriously change. - -Wed Oct 5 12:56:53 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * alloc.c (diskfs_alloc_node): Abort if free inode has - translator attached. - -Tue Oct 4 18:33:35 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * pager.c (pager_unlock_page): Call diskfs_catch_exception. - -Tue Oct 4 00:16:04 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_lost_hardrefs): Comment out body. - * ufs.h (node2pagelock): New variable. - * pager.c (node2pagelock): Initialize. - (diskfs_get_filemap): Don't let node hold a reference to the pager. - (pager_clear_user_data): Acquire node2pagelock and clear - the node's reference to the pager. - (diskfs_file_update): Hold node2pagelock for reference - of NP->dn->fileinfo. - (drop_pager_softrefs): Likewise. - (allow_pager_softrefs): Likewise. - (diskfs_get_filemap): Likewise. - * sizes.c (diskfs_truncate): Likewise. - - * Makefile (SRCS): Added pokeloc.c. - -Mon Oct 3 15:03:38 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * sizes.c (diskfs_truncate): Rewritten. - - * bmap.c (fetch_indir_spec): Initialize OFFSET values to -2, - meaning that the entry is not needed. If LBN is negative, - then don't set values for the data block. - - * inode.c (write_node): Call record_poke after writing - dinode. - (create_symlink_hook): Likewise. - (diskfs_set_translator): Likewise. - * pager.c (pager_unlock_page): Likewise. - * sizes.c (diskfs_truncate): Likewise. - * pager.c (pager_unlock_page): Call record_poke after writing - indirect block. - * sizes.c (diskfs_grow): Likewise. - (diskfs_grow): Likewise. - * pager.c (diskfs_sync_everything) [sync_one]: If this is the - disk pager, call sync_disk instead. - * pokeloc.c: New file. - -Fri Sep 30 11:25:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.h: Delete DT_* definitions; they are now in <dirent.h>. - * dir.c (diskfs_get_directs): Set USERP->d_type as DT_UNKNOWN. - When the bugs in the type fields are fixed (dealing with - multiple links and mode changes) then this can actually return - the value. - -Thu Sep 29 17:16:58 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (main): Test getpid()>0 to decide we are a normal - translator instead of the boot fs. Fetch bootstrap port after - possibly calling diskfs_parse_bootargs, not before. - -Tue Sep 27 15:24:58 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * sizes.c (diskfs_grow) [computation of newallocsize]: Last block - number is one less than the total number of blocks. - -Tue Sep 27 11:58:44 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * bmap.c (fetch_indir_spec): Single indirect block pointer is - in the INDIR_SINGLE slot, not the INDIR_DOUBLE slot. - -Mon Sep 26 20:47:30 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (SRCS): Added bmap.c. - - * main.c (main): Don't call pager_init. - - * inode.c (diskfs_get_translator): Repair to read translator - correctly. - - * sizes.c (diskfs_grow): Compute block numbers in a more clean - (and confidently correct) fashion. - (diskfs_truncate): Set NP->allocsize from a properly rounded - value. - -Mon Sep 26 12:50:38 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (diskfs_lost_hardrefs): "Know" that a pager starts - with a portinfo; we don't actually have access to the pager - struct here. - -Fri Sep 23 14:21:55 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - [ Continuing yesterday's changes. ] - * ufs.h (struct dirty_indir): New type. - (struct disknode): New member `dirty'. - * inode.c (iget): Initialize DN->dirty. - * bmap.c (mark_indir_dirty): New function. - * pager.c (pager_unlock_page): Call mark_indir_dirty before - writing into indirect blocks. - (diskfs_file_update): Sync indirect blocks here. - (pager_traverse): Simplify; do FILE_DATA and diskpager. - (pager_init): Removed function. - (create_disk_pager): New function. - * sizes.c: Completely rewritten. - * main.c (main): Spawn first thread sooner so we can - map and look at the disk image. - * hyper.c (get_hypermetadata): Moved firewall asserts - here from pager_init. - -Thu Sep 22 11:28:46 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - [This long series of changes deletes the DINODE, CG, SINDIR, - and DINDIR pagers and adds a new pager type DISK.] - * ufs.h (struct disknode) Removed DINLOCK, SINLOCK, and - SININFO members. New member ALLOCPTRLOCK renamed from DATALOCK. - Removed SINLOC, DINLOC, SINLOCLEN, and DINLOCLEN. - (struct user_pager_info) [enum pager_type]: Removed types - DINODE, CG, SINDIR and DINDIR; added type DISK. - (dinpager, dinodepager, cgpager): Deleted vars. - (diskpager): New var. - (dinmaplock, sinmaplock, pagernplock): Deleted vars. - (sblock_dirty, csum_dirty, cgs, dinodes): Deleted vars. - (fsaddr): New macro. - (dino, indir_block, cg_locate): New inline functions. - (sync_disk_blocks, sync_dinode): New inline functions. - (struct iblock_spec): New type. - * pager.c (dinport, dinodeport, cgport, sinlist): Deleted vars. - (filepagerlist): Renamed from filelist. - (pagernplock): Deleted variable. - (find_address): Removed switch; support only DISK and FILE_DATA. - (pager_report_extent): Likewise. - (pager_unlock_page): Removed switch. Return without comment for - DISK; allocate indirect blocks as necessary right here for - FILE_DATA. - (sin_map, sin_remap, sin_unmap, din_map, din_unmap): Deleted - functions. - (indir_alloc, sync_dinode): Deleted functions. - (enqueue_pager, dequeue_pager): Deleted functions. - (diskfs_file_update): No longer lock pagernplock; nothing - to do with sininfo. - (drop_pager_softrefs): Likewise. - (allow_pager_softrefs): Likewise. - (diskfs_get_filemap): Put pager on filepagerlist right here - instead of through pager_enqueue. - (pager_clear_user_data): Likewise, mutatis mutandis. - * main.c (main): Call create_disk_pager and then map the - entire disk into disk_image. - * hyper.c (get_hypermetadata): Use bcopy instead of dev_read_sync. - (diskfs_set_hypermetadata): NOP out function. - (copy_sblock): New function, substance of code is from old - diskfs_set_hypermetadata. - * inode.c (iget): Don't initialize deleted disknode fields. - (diskfs_node_norefs): Don't verify that deleted disknode - fields are not set. - (read_disknode): Get dinode from DINO, not DINODES array. - (write_node): Likewise. - (create_symlink_hook): Likewise. - (read_symlink_hook): Likewise. - (diskfs_set_translator): Likewise. - (diskfs_get_translator): Likewise. - (diskfs_node_translated): Likewise. - * alloc.c (ffs_realloccg): Likewise. - (ffs_fragextend): Use cg_locate instead of cgs array. - (ffs_alloccg): Likewise. - (ffs_nodealloccg): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - * inode.c (diskfs_set_translator): Use bcopy and sync_disk_blocks - instead of dev_write_sync. - (diskfs_get_translator): Likewise, mutatis mutandis. - (read_disknode): Initialize NP->istranslated. - (diskfs_set_translator): Set/clear NP->istranslated as appropriate. - (diskfs_node_translated): Removed function. - * bmap.c: New file. - - [This improves the RWLOCK mechanism and makes it more - orthogonal. It should probably be moved into a library.] - * ufs.h (struct rwlock): Added MASTER and WAKEUP members. - (struct disknode): Removed RWLOCK_MASTER and RWLOCK_WAKEUP - fields. - (rwlock_reader_lock): Ommitted arg DN; use new MASTER and WAKEUP - members inside LOCK instead. - (rwlock_writer_lock): Likewise. - (rwlock_reader_unlock): Likewise. - (rwlock_init): Initialize new MASTER and WAKEUP fields. - * inode.c (iget): Don't deal with RWLOCK_MASTER and RWLOCK_WAKEUP. - * pager.c (find_address): Deleted arg DNP. Only pass one - arg to rwlock functions. - (pager_read_page): Deleted var DN; only pass one arg to rwlock - functions. - (pager_write_page): Likewise. - -Wed Sep 21 00:26:25 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * pager.c (allow_pager_softrefs): Unlock PAGERNPLOCK when - we're done with it. - (sin_map): Hold PAGERNPLOCK all the way until we're done - with the sininfo pointer. - (pagernplock): No longer static. - * ufs.h (pagernplock): Declare here. - - * sizes.c (diskfs_grow): Don't call diskfs_file_update here. - This was done to prevent too much dirty data from accumulating - and then overwhelming the pager later. But that's really the - pager's responsibility. - - * ufs.h (struct disknode): New members `dinloclen' and `sinloclen'. - * inode.c (iget): Initialize DN->dinloclen and DN->sinloclen. - (diskfs_node_norefs): Verify that DN->dinloclen and DN->sinloclen - are both zero. - * pager.c (find_address) [SINDIR]: Verify that reference is - within bounds of NP->dn->dinloc. - (pager_unlock_page) [SINDIR]: Likewise. - (din_map): Set NP->dn->dinloclen. - (din_unmap): Clear NP->dn->dinloclen. - (find_address) [FILE_DATA]: Verify that reference is within - bounds of NP->dn->sinloc. - (pager_unlock_page) [FILE_DATE]: Likewise. - (sin_map): Set NP->dn->sinloclen. - (sin_remap): Reset NP->dn->sinloclen. - (sin_unmap): Clean NP->dn->sinloclen. - - * pager.c (pager_write_page): Flush stdout after printf. - (pager_unlock_page) [FILE_DATA]: Likewise. - - * sizes.c (diskfs_truncate): In all references to sinloc and - dinloc arrays, verify that references are within allocated bounds. - (diskfs_grow): Likewise. - (sindir_drop): Likewise. - - * pager.c: Create new mapping with extent NEWSIZE, not SIZE (which - was the old size of the mapping). - -Tue Sep 20 15:51:35 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * pager.c (pager_report_extent) [SINDIR]: Remove erroneous extra - division by block size. - (sin_remap): Likewise. - -Mon Sep 19 17:34:11 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (create_symlink_hook): Write assert test correctly. - - * dir.c (diskfs_direnter) [EXTEND]: Reference file size only - *once*; don't rely on the behavior if diskfs_grow vis a vis - file size. - -Fri Sep 16 10:29:42 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.c (dirscanblock): Compute offset correctly for mangled - entry notice. - - * dir.c (diskfs_direnter) [EXTEND]: Reference file size only - once before calling diskfs_grow in case diskfs_grow actually - increases the size. - - * inode.c (diskfs_set_statfs): Set fsid from getpid. - (read_disknode): Likewise. - - * dir.h (struct directory_entry): Renamed from struct direct. - * dir.c: All uses of struct direct changed to use - struct directory_entry. - (diskfs_get_directs): New var `userp'. Copy from *ENTRYP into - it (set at DATAP) more cleanly. - -Mon Sep 12 11:30:48 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * hyper.c (diskfs_set_hypermetadata): Don't frob clean and dirty - bits if we are readonly. - -Sat Sep 10 11:41:06 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * main.c (main): When started up as a passive translator, - open fds 0, 1, and 2 on /dev/console for debugging messages. - Call diskfs_init_diskfs with no args; after warp_root, call - diskfs_startup_diskfs on BOOTSTRAP. Compare BOOTSTRAP to - MACH_PORT_NULL instead of zero. - -Fri Sep 9 13:02:33 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * main.c (trans_parse_args): Fix and enable. - -Tue Sep 6 11:29:55 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * inode.c (iget): Remove old assert test that checked for bad - inode block allocations. - -Thu Sep 1 11:39:12 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * tables.c: Don't include "ufs.h"; include <sys/types.h>. Then - this file can be used unmodified by fsck. - -Tue Aug 30 13:36:37 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_set_translator): ffs_blkfree doesn't have - a return value. - -Mon Aug 29 12:49:17 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (diskfs_set_translator): If NAMELEN is zero, then - make the node have no translator. - -Fri Aug 26 12:28:20 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * inode.c (read_disknode): 4.4 fsck sometimes sets the author - field to -1 to mean "ignore old uid location"; take that to mean - "author == uid". - (diskfs_set_translator): If we are allocating a new block for - the translator, then account for it in st_blocks. - -Thu Aug 18 12:41:12 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (HURDLIBS): Use short version. - - * alloc.c (diskfs_alloc_node): Bother to set *NPP before - returning. - -Tue Aug 16 10:48:04 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (LDFLAGS): New variable. - -Fri Aug 5 15:51:09 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * dir.c (diskfs_direnter) [EXTEND]: Crash if the entry won't - fit in the new block. - (diskfs_lookup): Return ENAMETOOLONG if the name is bigger than - MAXNAMLEN. - - * dir.c (diskfs_get_directs): Set USERD->d_reclen correctly. - -Fri Jul 22 15:12:35 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile: Rewritten in accord with new scheme. - -Wed Jul 20 13:28:38 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * main.c (main): Don't set diskfs_dotdot_file. - -Tue Jul 19 21:51:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * ufs.h: Removed defns of u_quad_t, quad_t; now in <sys/types.h>. - Removed defn of struct timespec; now in <sys/time.h>. - -Tue Jul 19 12:47:31 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * main.c (main): Deleted var `diskfs_dotdot_file'. - (trans_parse_args): Don't set diskfs_dotdot_file; don't expect - dotdot from fsys_getroot. - - * Makefile (LDFLAGS): Moved to rule for `ufs' and commented out. - (ufs): Don't use variable $(link) anymore. - -Mon Jul 18 14:55:17 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_get_directs): Return data to user in old format. - Add new code for new format, maintaining compatibility correctly, - but comment it out until the library is ready. - - * hyper.c (diskfs_set_hypermetadata): If we presumed to - set new values of fs_maxfilesize, fs_qbmask, and fs_qfmask, - then restore the originals before writing out the superblock. - - * pager.c (diskfs_get_filemap): Test should be S_ISLNK, not - S_ISSOCK. - - * hyper.c (get_hypermetadata): Set new constants in filesystems - which don't have them yet. - (get_hypermetadata): Cast MAXSYMLINKLEN to long to avoid - converting sblock->fs_maxsymlinklen into an unsigned. - - * subr.c (scanc, skipc): New functions. - (ffs_setblock): Use assert instead of panic. - - * inode.c (read_disknode): Set old stat structure until the header - file gets changed. - -Fri Jul 15 12:07:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c: Include <string.h> for bzero. - * fs.h (blksize): Comment out dblksize macro. In blksize - macro, use NP->allocsize instead of IP->i_size. - - * dinode.h (INDIR_SINGLE, INDIR_DOUBLE, INDIR_TRIPLE): New macros. - - * inode.c (read_disknode, write_node): Use new stat and dinode - fields for times. - - * ufs.h: Change `nextgennumber' to be `u_long' instead of int. - Change prototypes of some alloc.c functions. - * alloc.c (ffs_alloc): Declare to return error_t. - (ffs_realloccg): Likewise. - (ffs_hashalloc, ffs_alloccg, ffs_fragextend, ffs_alloccg, - ffs_dirpref, ffs_nodealloccg, ffs_allccgblk, ffs_mapsearch, - ffs_clusteracct): Provide forward declarations. - (ffs_realloccg): Use printf instead of log. - Make BPREF volatile for setjmp safety. - (diskfs_alloc_node): Use diskfs global variable instead of TIME. - (ffs_nodealloccg): Likewise. - (ffs_blkfree): Likewise. - (diskfs_free_node): Likewise. - (ffs_blkfree, ffs_clusteracct): Declare as void. - (ffs_alloccg, ffs_nodealloccg): Declare as u_long. - - * ufs.h: Change prototypes of some subr.c functions. - * subr.c (ffs_isblock): Use assert instead of panic. - (ffs_clrblock): Likewise. - - * hyper.c: Include "dinode.h". - - * dinode.h (LINK_MAX): New macro, from BSD sys/sys/syslimits.h. - * fs.h (MAXBSIZE, MAXFRAG): New macros, from BSD sys/sys/param.h. - - * hyper.c (get_hypermetadata): Provide first arg in call to - fsbtodb. - (diskfs_set_hypermetadata): Likewise. - * inode.c (diskfs_set_translator): Likewise. - (diskfs_get_translator): Likewise. - * pager.c (find_address): Likewise. - (indir_alloc): Likewise. - * inode.c (iget): Provide first arg in call to lblkno. - * sizes.c (diskfs_truncate): Likewise. - * pager.c (find_address): Likewise. - * sizes.c (diskfs_grow): Likewise. - * inode.c (iget): Provide first arg in call to fragroundup. - * sizes.c (diskfs_trucate): Likewise. - * sizes.c (diskfs_grow): Likewise. - * inode.c (iget): Provide first arg in call to blkroundup. - * pager.c (pager_unlock_page): Likewise. - * sizes.c (diskfs_truncate): Likewise. - * sizes.c (diskfs_grow): Likewise. - * pager.c (find_address): Provide first arg in call to cgtod. - * pager.c (find_address): Provide first arg in call to cgimin. - * pager.c (find_address): Provide first arg in call to blktofrags. - * pager.c (find_address): Provide first arg in call to blkoff. - * sizes.c (diskfs_truncate): Likewise. - * sizes.c (diskfs_grow): Likewise. - * sizes.c (diskfs_truncate): Provide first arg in call to blksize. - * sizes.c (diskfs_grow): Likewise. - * sizes.c (diskfs_truncate): Provide first arg in call to numfrags. - - * ufs.h: Added temporary declarations of `u_quad_t', `quad_t', and - `struct timespec'. - - * pager.c (diskfs_get_filemap): Make sure that this is - a kind of node that can be validly read. - - * inode.c (create_symlink_hook): Renamed from symlink_hook. - (read_symlink_hook): New function. - (diskfs_read_symlink_hook): Initialize. - -Thu Jul 14 12:23:45 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * alloc.c: New from 4.4 BSD; BSD version `8.8 2/21/94'. - Remove old includes; include "ufs.h", "fs.h", "dinode.h", - and <stdio.h>. Replace panics with asserts and comment out - uprintfs. Use prototypes throughout. Replace calls - to ffs_fserr with printf. - (alloclock): New variable. - (ffs_alloc): Variable struct inode *IP is now struct node *NP; - refer to it appropriately. Initialize FS to sblock. - Lock alloclock around actual allocation steps. Reverse order - of BNP and CRED arguments; declare CRED as a protid and use - accordingly. Permit CRED to be null. - (ffs_realloccg): Variable struct inode *IP is now struct node *NP; - refer to it accordingly. Comment out U*x buffer management code. - Lock alloclock around actual allocation steps. Initialize FS - from sblock. Declare CRED as a protid and use it accordingly. - Change BUF arg to PBN (physical block number); return new block - there. - (ffs_reallocblks): Comment out. - (diskfs_alloc_node): Renamed from ialloc. Initialize FS from - sblock. Use calling sequence from <hurd/diskfs.h>. Acquire - alloclock aroud actual allocation steps. Deleted vars - `pip', `pvp' (use dir instead). Use iget instead of VFS_VGET. - Var struct inode *IP now struct node *NP. Lock gennumberlock - around frobbing of nextgennumber. - (ffs_blkpref): Arg struct inode *ip is now struct node *np; - refer to it accordingly. Initialize FS to sblock. Lock - alloclock during actual work. Use csum instead of fs_cs macro. - (ffs_hashalloc): Arg struct inode *IP is now struct node *NP; - use it accordingly. Initialize FS from sblock. - (ffs_fragextend): Arg struct inode *IP is now struct node *NP; - use it accordingly. Initialize FS from sblock. Initialize - CGP from cgs array; don't use bread. Comment out calls to brelse - and bdwrite. Set CGP->time from diskfs global var. Use csum - instead of fs_cs macro. - (ffs_alloccg): Arg struct inode *IP is now struct node *NP. - Initialize FS from sblock. Initialize CGP from cgs array; - don't use bread. Comment out calls to brelse and bdwrite. - Set CGP->time from diskfs global var. Use csum instead of - fs_cs macro. - (ffs_nodealloccg): Arg struct inode *IP is now struct node *NP. - Initialize FS from sblock. Initialize CGP from cgs array; - don't use bread. Comment out calls to brelse and bdwrite. Use - csum instead of fs_cs macro. - (ffs_blkfree): Arg struct inode *IP is now struct node *NP. - Initialize FS from sblock. Initialize CGP from cgs array; - don't use bread. Comment out calls to brelse and bdwrite. Use - csum instead of fs_cs macro. - (diskfs_free_node): Renamed from ffs_vfree. Use calling - sequence from <hurd/diskfs.h>. Initialize FS from sblock. - Deleted vars pip,pvp (use NP instead). Initialize CGP from - cgs array; don't use bread. Comment out calls to brelse and - bdwrite. Use csum instead of fs_cs macro. - (ffs_fserr): Commented out. - (ffs_dirpref): Use csum instead of fs_cs macro. - - * ufs.h (ffs_alloc): Renamed from alloc; all callers changed. - (ffs_blkfree): New arg NP; renamed from blkfree; all callers changed. - (ffs_blkpref): Renamed from blkpref; all callers changed. - (ffs_realloocg): Rename from realloccg; all callers changed. - - * fs.h: New from 4.4 BSD; BSD version `8.7 4/19/94'. - (fs_cs): Don't use fs_csp; use global csum instead. - - * subr.c: New from 4.4 BSD; BSD version `8.2 9/21/93'. - Remove old includes. Include "ufs.h" and "fs.h". - (ffs_blkatoff, ffs_checkoverlap): Comment out. - - * tables.c: New from 4.4 BSD; BSD version `8.1 6/11/93'. - Don't include <param.h>; do include "ufs.h" and "fs.h". - - * dinode.h: New from 4.4 BSD; BSD version `8.3 1/21/94'. - Remove oldids/inum union; replace with author. - Renamed di_mode to be di_model; allocated di_modeh from spare. - Allocate di_trans from spare. - (di_inumber): Remove macro. - * inode.c (read_disknode): Fetch uid and gid from new (long) - fields in dinode unless we are the old inode format, in which - case fetch them from the old fields. - (write_node): Only set new uid and gid fields if we are not - COMPAT_BSD4. Set old fields if the superblock says to. - (symlink_hook): New function. - (diskfs_create_symlink_hook): Initialize. - * sizes.c (diskfs_truncate): Deal with truncation of short - symlink properly. - - * dir.h: New from 4.4 BSD; BSD version `8.2 1/21/94'. - Substitute our version of DIRSIZ which uses the namelen. - Comment out declarations of struct dirtemplate and struct - odirtemplate. - (DIRECT_TYPE, DIRECT_NAMLEN): New macros. - * ufs.h (direct_symlink_extension): New variable. - * hyper.c (get_hypermetadata): Set direct_symlink_extension. - * dir.c (dirscanblock): Use DIRECT_NAMLEN instead of d_namlen. - (diskfs_direnter): Likewise. - (diskfs_dirempty): Likewise. - (diskfs_get_directs): Likewise. - (diskfs_direnter): Set d_type field of new slot if - direct_symlink_extension is set. - (diskfs_dirrewrite): Likewise. - - * ufs.h (compat_mode): New variable. - * main.c (main): Set compat_mode to zero if we are the bootstrap - filesystem. - * inode.c (diskfs_set_translator): Return error if compat_mode - is set. - (write_node): Don't set GNU dinode field extensions unless - compat_mode is COMPAT_GNU. - -Mon Jul 11 18:14:26 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_get_directs): When copying entries into DATAP, - set the d_reclen parameter of the copy to the minimum length - (because that's all we use) rather than the size that it had - in the directory itself. - -Wed Jul 6 14:41:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (dirscanblock): In main loop, initialize PREVOFF - to zero, not BLOCKADDR. Otherwise, the wrong value is - stored into DS->prevoff and then diskfs_dirremove crashes. - -Tue Jul 5 14:07:38 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dinode.h: Include <endian.h> before test of BYTE_ORDER. - - * Makefile (TAGSLIBS): New variable. - -Tue Jun 21 13:45:04 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_direnter): Update dirents of DP, not NP. - -Mon Jun 20 16:43:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * dir.c (diskfs_direnter) [case SHRINK]: NEW should be set to - OLDNEEDED past DS->entry, not to the start of the next entry. - - * dir.c (diskfs_direnter) [case EXTEND]: Cast in assignment - to NEW needs proper scope. - - * inode.c (diskfs_node_norefs): Free dirents list of structure - being deallocated. Also add assert checks to make sure other - state is already clean. - -Thu Jun 16 11:38:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * dir.c (diskfs_dirempty): Map directory contents ourselves - instead of using diskfs_node_rdwr. - (struct dirstat): New structure to cache mapping between - lookup and commit operation and avoid use of diskfs_node_rdwr. - (diskfs_lookup): Map directory ourselves. Keep mapping in - DS if DS is nonzero and we might use it in direnter, dirremove, - or dirrewrite. Deallocate mapped buffer if we return some - error (other than ENOENT), or if DS is zero, or if there is - no possible commit operation to follow. When setting DS->stat - to EXTEND, do it the new way. - (dirscanblock): Changed BLKOFF to be virtual address of mapped - block and renamed it BLKADDR. New arg IDX. Use mapped block - instead of calling diskfs_node_rdwr. Set DS according to the new - rules. - (diskfs_direnter): Interpret new dirstat format. - (diskfs_dirremove): Likewise. - (diskfs_dirrewrite): Likewise. - (diskfs_drop_dirstat): Deallocate cached mapping here. - - * dir.c (dirscanblock): When we find the node for type CREATE, - invalidate DS by setting type to LOOKUP, not LOOKING. - - * dir.c (diskfs_direnter, diskfs_dirremove, diskfs_dirrewrite): - Call diskfs_notice_dirchange when appropriate. - - * dir.c (diskfs_get_directs): Deal properly with case where - BUFSIZ==0 and where NENTRIES==-1. - -Wed Jun 15 16:40:12 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * main.c (main): Check device sector size and media size - on startup. - -Tue Jun 14 14:41:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * ufs.h (struct disknode) [dirents]: New member. - * inode.c (iget): Initialize DN->dirents. - * dir.c (diskfs_direnter, diskfs_dirremove): Keep track - of dirents member. - (dirscanblock): New var `nentries'; use it to count the - number of directory entries in this block and set it if - we end up scanning the entire block. - (count_dirents): New function. - (diskfs_get_directs): New function. - -Mon Jun 13 13:50:00 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * ufs.h (sinmaplock, dinmaplock): New global vars. - * inode.c (inode_init): Initialize sinmaplock and dinmaplock. - * pager.c (find_address, pager_unlock_page): Protect use - if dinloc array with dinmaplock. - (din_map, din_unmap): Doc fix. - (find_address, pager_unlock_page): Protect use of sinloc array - with sinmaplock. - (sin_map, sin_remap, sin_unmap): Doc fix. - (pager_clear_user_data): Acquire sinmaplock and dinmaplock - instead of NP->dn->datalock and NP->dn->sinlock respectively. - - * sizes.c (diskfs_truncate, diskfs_grow): Protect use of sinloc - and sindir mapping functions with sinmaplock. - (sindir_drop): Protect use of dinloc and dindir mapping functions - with dinmaplock. - - * ufs.h (struct rwlock): New type. - (struct disknode) [dinlock, sinlock, datalock]: Use read-write lock. - Change comments so that these don't lock dinloc and sinloc anymore. - [rwlock_master, rwlock_wakeup]: New members. - (rwlock_reader_lock, rwlock_writer_lock, rwlock_reader_unlock, - rwlock_writer_unlock, rwlock_init): New functions. - * inode.c (iget): Initialize DN->rwlock_master and - DN->rwlock_wakeup. Change initialization of DN->dinlock, - DN->sinlock, and DN->datalock to use rwlock_init. - * pager.c (find_address): Lock NP->dn->dinlock, NP->dn->sinlock, - and NP->dn->datalock with rwlock_reader_lock. Change type of - parameter NPLOCK to be a read-write lock. New parm DNP. Callers - changed. - (pager_read_page, pager_write_page): Change type of NPLOCK to be - read-write lock; call rwlock_reader_unlock instead of - mutex_unlock. New variable DN. - (pager_unlock_page): Use rwlock_writer_lock to lock - NP->dn->dinlock, NP->dn->sinlock, and NP->dn->datalock. - * sizes.c (diskfs_truncate, diskfs_grow): Change locks of DATALOCK - field to use rwlock_writer_{un,}lock. - (sindir_drop): Ditto for SINLOCK field. - (dindir_drop): Ditto for DINLOCK field. - -Mon Jun 6 19:23:26 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_grow): After realloccg, zero new data (which I'm - not sure is really necessary, but until I figure it out, this is - safest). Also poke old data (the latter only if the block has - moved)--otherwise the kernel won't know to page it out to the new - location. - (poke_pages): When poking, be careful not to actually change the data. - LEN should be end - start, not start - end. - -Fri Jun 3 12:37:27 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * inode.c (iget): When we find the node in the table, acquire the - mutex *after* incrementing NP->references and unlocking - diskfs_node_refcnt_lock; otherwise we can deadlock against - diskfs_nput. - -Thu Jun 2 12:16:09 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * ufs.h (sblock_dirty, csum_dirty, alloclock): New global variables. - * alloc.c (alloclock): Remove static keyword.. - * alloc.c (realloccg): Set sblock_dirty after changing sblock. - (blkpref): Likewise. - (fragextend): Likewise. - (alloccg): Likewise. - (alloccgblk): Likewise. - (ialloccg): Likewise. - (blkfree): Likewise. - (diskfs_free_node): Likewise. - * hyper.c (diskfs_set_hypermetadata): Likewise. - * alloc.c (fragextend): Set csum_dirty after changi csum. - (alloccg): Likewise. - (alloccgblk): Likewise. - (ialloccg): Likewise. - (blkfree): Likewise. - (diskfs_free_node): Likewise. - * hyper.c (diskfs_set_hypermetadata): Acquire alloclock while - writing hypermetadata. Only write csum and sblock if - csum_dirty or sblock_dirty, respectively, is set, and then - clear it after starting the write. - - * main.c (main): Likewise. - - * sizes.c (diskfs_truncate): Don't turn off caching; the new - light reference system takes care of this. - * pager.c (diskfs_get_filemap): No longer necessary to turn - on caching here, because truncate no longer turns it off. - - * inode.c (diskfs_lost_hardrefs, diskfs_new_hardrefs): New functions. - * pager.c (drop_pager_softrefs, allow_pager_softrefs): New functions. - (sin_map): Use diskfs_nref_light, not diskfs_nref. - (diskfs_get_filemap): Use diskfs_nref_light, not diskfs_nref. - (pager_clear_user_data): Use diskfs_nrele_light, not diskfs_nrele. - * ufs.h (drop_pager_softrefs, allow_pager_softrefs): New - declarations. - -Wed Jun 1 13:35:11 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): After calling sin_unmap, turn - off caching on the sininfo pager so that it gets freed promptly - (there's generally no value in keeping it around because there - is no live fileinfo pager). - * pager.c (diskfs_get_filemap): Make sure we turn caching back on - here, however, if we start using the file pager. - - * pager.c (sin_map): When np->dn->sininfo is set, we have - to insert a valid send right after fetching the receive name. - - * pager.c (sin_unmap, din_unmap): New functions. - (pager_clear_user_data): Call sin_unmap and din_unmap - instead of doing it right here. - - * sizes.c (diskfs_truncate): Call sin_unmap instead of - doing it right here. - (sindir_drop): Call din_unmap instead of doing it right - here. Also, call it always, not just when wo do dindir_drop. - - * sizes.c (diskfs_grow): After alloc into sindir area, - unmap it if we don't have an active data pager. - * ufs.h (sin_unmap, din_unmap): New declarations. - - * sizes.c (diskfs_grow): In computing OSIZE in the realloc - case of lbn < NDADDR, deal correctly with the case where - np->allocsize is already an integral number of blocks. - - * sizes.c (diskfs_grow): Compute SIZE correctly. - - * alloc.c (alloc, realloccg, blkfree): When checking validity - of size arguments, also make sure the size isn't zero. - - * alloc.c (diskfs_alloc_node): Lock ALLOCLOCK before checking - sblock->fs_cstotal.cs_nifree. - -Tue May 31 18:47:42 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * ufs.h (DONT_CACHE_MEMORY_OBJECTS): Define it. - - * dir.c (diskfs_direnter: case TAKE): Assert that OLD->d_reclen >= - NEEDED, not that it is strictly >. - -Tue May 31 11:10:28 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_grow): Call diskfs_node_update (but don't wait) - after successful completion to prevent old data from hanging around - too long and getting flushed all at once from the kernel. - - * sizes.c (diskfs_grow): Change SIZE to be the size of the last - block allocated. Delete variable NSIZE; use SIZE instead. - -Fri May 27 13:15:26 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): Set NP->dn_stat_dirty after each - modification of NP->dn_stat. - - * sizes.c (diskfs_truncate): Compute new value of NP->allocsize - correctly. - - * inode.c (iget): Set NP->allocsize to be the *actual* allocsize. - -Thu May 26 11:51:45 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): In blkfree loop of blocks past - NDADDR, subtract NDADDR from idx to index correctly into - sinloc array. Start this loop with idx not less than NDADDR. - (diskfs_truncate): If olastblock == NDADDR, then we also - need to truncate blocks (one) mapped by single indirect blocks. - (diskfs_truncate): New variable `first2free'. Use in place - of older losing calculations involving lastblock. - (sindir_drop): Rename parameters to be FIRST and LAST. Change - interpretation of FIRST by one to correspond with changed call - in diskfs_truncate. - - * pager.c (sin_remap): When computing NEWSIZE, round up to - a page boundary, thus mimicing the SINDIR computation in - pager_report_extent properly. - - * pager.c (pager_unlock_page) [case SINDIR; vblkno == 0]: Read - from ....di_ib[INDIR_SINGLE] rather than invalid data before - NP->dn->dinloc. - - * alloc.c (alloc) [nospace]: Unlock alloclock. - (realloccg): Unlock alloclock before jumping to nospace. - (blkpref) [!(lbn < NDADDR)]: Unlock alloclock before returning - success. - - * sizes.c (diskfs_grow): When allocing a block past NDADDR, the - tbl arg to blkpref is the table of direct block pointers - NP->dn->sinloc, not the table of indirect block pointers - ...->di_ib. - - * sizes.c (diskfs_grow): When writing into the SINDIR area, call - sin_map instead of sin_remap if the sindir isn't already mapped. - Also set np->allocsize *before* calling sin_map, but *after* - calling sin_remap, to meet the requirements of those separate - routines. - - * sizes.c (diskfs_grow): If END isn't bigger than NP->allocsize, - then don't try and do anything. In computation of LBN and the - first use of NB, round up to block boundary correctly. Don't - attempt to realloc an old block if the size is 0 (in which case - NB is -1 and unsigned comparison rules might foul things up). - -Mon May 23 13:18:33 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * Makefile (ufs): Give -n in the proper order to rsh. - - * main.c: Include <hurd/startup.h>. - - * ufs.h (DONT_CACHE_MEMORY_OBJECTS): New compilation flag. - * pager.c (pager_report_attributes): Deleted function. - (MAY_CACHE): New macro; more useful form for using - DONT_CACHE_MEMORY_OBJECTS. - (sin_map, pager_init, diskfs_get_filemap): Provide new - args in calls to pager_create. - * sizes.c (MAY_CACHE): New macro; more useful form for - using DONT_CACHE_MEMORY_OBJECTS. - (diskfs_truncate): Use MAY_CACHE in calls to pager_change_attributes. - -Fri May 20 18:52:41 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * sizes.c (diskfs_truncate): Force any delayed copies of the - vanishing region to be taken immediately before stopping, and - prevent any new delayed copies from being made until we are done - manipulating things. - (poke_pages): New function. - * pager.c (pager_report_attributes): New function. - -Wed May 18 15:51:40 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * alloc.c (alloc, realloccg, diskfs_alloc_node, alloccgblk, - blkfree, diskfs_free_node, mapsearch): Added helpful strings to - asserts. - (realloccg): Split up assert. - -Tue May 17 13:26:22 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * main.c (main): Delete unused variable PROC. - -Mon May 16 15:32:07 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * alloc.c (realloccg): When fragextend succeeds, bother to set - *PBN. - - * sizes.c (diskfs_grow): In fragment growth case, NSIZE should - not be the amount to hold SIZE (SIZE is the amount the file is - growing by), but rather the old size of the fragment plus the - SIZE. - - * dir.c (diskfs_direnter case COMPRESS): Rewrite loop to deal - properly with the case where from and to overlap. - -Mon May 9 16:51:44 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * main.c (ufs_version): New variable. - (save_argv): New variable. - (main): Set save_argv. - (diskfs_init_completed): New function. - -Thu May 5 19:06:54 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * Makefile (exec_server_image.o): Use -n when calling rsh. - -Thu May 5 07:39:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * Makefile ($(OBJS)): Use $(includedir) instead of $(headers) in deps. - diff --git a/ufs/Makefile b/ufs/Makefile index d9375989..cf5c40d7 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,5 +1,6 @@ - -# Copyright (C) 1994, 1995, 1996 Free Software Foundation +# Makefile for ufs +# +# Copyright (C) 1994,95,96,99,2000,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 @@ -16,18 +17,16 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dir := ufs -makemode := servers +makemode := server -targets = ufs ufs.static +target = ufs SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ - sizes.c subr.c tables.c bmap.c pokeloc.c + sizes.c subr.c tables.c bmap.c pokeloc.c xinl.c LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) - -ufs.static-LDFLAGS += -static +HURDLIBS = diskfs iohelp fshelp store pager threads ports ihash shouldbeinlibc include ../Makeconf -ufs.static ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libiohelp/libiohelp.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a - +ufs.static: $(boot-store-types:%=../libstore/libstore_%.a) diff --git a/ufs/alloc.c b/ufs/alloc.c index 90ce68f5..d8f92255 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,5 +1,5 @@ /* Disk allocation routines - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993,94,95,96,98,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. @@ -67,7 +67,7 @@ extern u_long nextgennumber; spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; /* Forward declarations */ -static u_long ffs_hashalloc (struct node *, int, long, int, +static u_long ffs_hashalloc (struct node *, int, long, int, u_long (*)(struct node *, int, daddr_t, int)); static u_long ffs_alloccg (struct node *, int, daddr_t, int); static daddr_t ffs_fragextend (struct node *, int, long, int, int); @@ -96,7 +96,7 @@ void swab_cg (struct cg *cg) { int i, j; - + if (swab_long (cg->cg_magic) == CG_MAGIC || cg->cg_magic == CG_MAGIC) { @@ -125,12 +125,12 @@ swab_cg (struct cg *cg) /* blktot map */ for (i = 0; i < cg->cg_ncyl; i++) cg_blktot(cg)[i] = swab_long (cg_blktot(cg)[i]); - + /* blks map */ for (i = 0; i < cg->cg_ncyl; i++) for (j = 0; j < sblock->fs_nrpos; j++) cg_blks(sblock, cg, i)[j] = swab_short (cg_blks (sblock, cg, i)[j]); - + for (i = 0; i < sblock->fs_contigsumsize; i++) cg_clustersum(cg)[i] = swab_long (cg_clustersum(cg)[i]); @@ -140,11 +140,11 @@ swab_cg (struct cg *cg) { /* Old format cylinder group... */ struct ocg *ocg = (struct ocg *) cg; - + if (swab_long (ocg->cg_magic) != CG_MAGIC && ocg->cg_magic != CG_MAGIC) return; - + ocg->cg_time = swab_long (ocg->cg_time); ocg->cg_cgx = swab_long (ocg->cg_cgx); ocg->cg_ncyl = swab_short (ocg->cg_ncyl); @@ -176,7 +176,7 @@ int read_cg (int cg, struct cg **cgpp) { struct cg *diskcg = cg_locate (cg); - + if (swab_disk) { *cgpp = malloc (sblock->fs_cgsize); @@ -205,7 +205,7 @@ release_cg (struct cg *cgp) /* * Allocate a block in the file system. - * + * * The size of the requested block is given, which must be some * multiple of fs_fsize and <= fs_bsize. * A preference may be optionally specified. If a preference is given @@ -215,7 +215,7 @@ release_cg (struct cg *cgp) * 3) allocate a block in the same cylinder group. * 4) quadradically rehash into other cylinder groups, until an * available block is located. - * If no block preference is given the following heirarchy is used + * If no block preference is given the following hierarchy is used * to allocate a block: * 1) allocate a block in the cylinder group that contains the * inode for the file. @@ -224,7 +224,7 @@ release_cg (struct cg *cgp) */ error_t ffs_alloc(register struct node *np, - daddr_t lbn, + daddr_t lbn, daddr_t bpref, int size, daddr_t *bnp, @@ -233,7 +233,7 @@ ffs_alloc(register struct node *np, register struct fs *fs; daddr_t bno; int cg; - + *bnp = 0; fs = sblock; #ifdef DIAGNOSTIC @@ -247,7 +247,7 @@ ffs_alloc(register struct node *np, spin_lock (&alloclock); if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) goto nospace; - if (cred && !diskfs_isuid (0, cred) + if (cred && !idvec_contains (cred->user->uids, 0) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; #ifdef QUOTA @@ -297,7 +297,7 @@ error_t ffs_realloccg(register struct node *np, daddr_t lbprev, volatile daddr_t bpref, - int osize, + int osize, int nsize, daddr_t *pbn, struct protid *cred) @@ -306,7 +306,7 @@ ffs_realloccg(register struct node *np, int cg, error; volatile int request; daddr_t bprev, bno; - + *pbn = 0; fs = sblock; #ifdef DIAGNOSTIC @@ -322,8 +322,9 @@ ffs_realloccg(register struct node *np, #endif /* DIAGNOSTIC */ spin_lock (&alloclock); - - if (!diskfs_isuid (0, cred) && freespace(fs, fs->fs_minfree) <= 0) + + if (!idvec_contains (cred->user->uids, 0) + && freespace(fs, fs->fs_minfree) <= 0) goto nospace; error = diskfs_catch_exception (); if (error) @@ -377,8 +378,8 @@ ffs_realloccg(register struct node *np, switch ((int)fs->fs_optim) { case FS_OPTSPACE: /* - * Allocate an exact sized fragment. Although this makes - * best use of space, we will waste time relocating it if + * Allocate an exact sized fragment. Although this makes + * best use of space, we will waste time relocating it if * the file continues to grow. If the fragmentation is * less than half of the minimum free reserve, we choose * to begin optimizing for time. @@ -418,7 +419,7 @@ ffs_realloccg(register struct node *np, bno = (daddr_t)ffs_hashalloc(np, cg, (long)bpref, request, (u_long (*)())ffs_alloccg); if (bno > 0) { -#if 0 /* Not necessary in GNU Hurd ufs */ +#if 0 /* Not necessary in GNU Hurd ufs */ bp->b_blkno = fsbtodb(fs, bno); (void) vnode_pager_uncache(ITOV(ip)); #endif @@ -471,7 +472,7 @@ nospace: * logical blocks to be made contiguous is given. The allocator attempts * to find a range of sequential blocks starting as close as possible to * an fs_rotdelay offset from the end of the allocation for the logical - * block immediately preceeding the current range. If successful, the + * block immediately preceding the current range. If successful, the * physical block numbers in the buffer pointers and in the inode are * changed to reflect the new allocation. If unsuccessful, the allocation * is left unchanged. The success in doing the reallocation is returned. @@ -584,7 +585,7 @@ ffs_reallocblks(ap) * Next we must write out the modified inode and indirect blocks. * For strict correctness, the writes should be synchronous since * the old block values may have been written to disk. In practise - * they are almost never written, but if we are concerned about + * they are almost never written, but if we are concerned about * strict correctness, the `doasyncfree' flag should be set to zero. * * The test on `doasyncfree' should be changed to test a flag @@ -630,20 +631,20 @@ fail: /* * Allocate an inode in the file system. - * + * * If allocating a directory, use ffs_dirpref to select the inode. * If allocating in a directory, the following hierarchy is followed: * 1) allocate the preferred inode. * 2) allocate an inode in the same cylinder group. * 3) quadradically rehash into other cylinder groups, until an * available inode is located. - * If no inode preference is given the following heirarchy is used + * If no inode preference is given the following hierarchy is used * to allocate an inode: * 1) allocate an inode in cylinder group 0. * 2) quadradically rehash into other cylinder groups, until an * available inode is located. */ -/* This is now the diskfs_alloc_node callback from the diskfs library +/* This is now the diskfs_alloc_node callback from the diskfs library (described in <hurd/diskfs.h>). It used to be ffs_valloc in BSD. */ error_t diskfs_alloc_node (struct node *dir, @@ -655,7 +656,7 @@ diskfs_alloc_node (struct node *dir, ino_t ino, ipref; int cg, error; int sex; - + fs = sblock; @@ -682,9 +683,9 @@ diskfs_alloc_node (struct node *dir, goto noinodes; error = diskfs_cached_lookup (ino, &np); assert ("duplicate allocation" && !np->dn_stat.st_mode); - assert (!np->istranslated); + assert (! (np->dn_stat.st_mode & S_IPTRANS)); if (np->dn_stat.st_blocks) { - printf("free inode %d had %d blocks\n", + printf("free inode %Ld had %Ld blocks\n", ino, np->dn_stat.st_blocks); np->dn_stat.st_blocks = 0; np->dn_set_ctime = 1; @@ -699,7 +700,7 @@ diskfs_alloc_node (struct node *dir, nextgennumber = sex; np->dn_stat.st_gen = nextgennumber; spin_unlock (&gennumberlock); - + *npp = np; alloc_sync (np); return (0); @@ -738,7 +739,7 @@ ffs_dirpref(register struct fs *fs) * Select the desired position for the next block in a file. The file is * logically divided into sections. The first section is composed of the * direct blocks. Each additional section contains fs_maxbpg blocks. - * + * * If no blocks have been allocated in the first section, the policy is to * request a block in the same cylinder group as the inode that describes * the file. If no blocks have been allocated in any other section, the @@ -752,7 +753,7 @@ ffs_dirpref(register struct fs *fs) * indirect block, the information on the previous allocation is unavailable; * here a best guess is made based upon the logical block number being * allocated. - * + * * If a section is already partially allocated, the policy is to * contiguously allocate fs_maxcontig blocks. The end of one of these * contiguous blocks and the beginning of the next is physically separated @@ -785,10 +786,10 @@ ffs_blkpref(struct node *np, */ if (indx == 0 || bap[indx - 1] == 0) startcg = - (ino_to_cg(fs, np->dn->number) + (ino_to_cg(fs, np->dn->number) + lbn / fs->fs_maxbpg); else - startcg = dtog(fs, + startcg = dtog(fs, read_disk_entry (bap[indx - 1])) + 1; startcg %= fs->fs_ncg; avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; @@ -891,14 +892,14 @@ ffs_hashalloc(struct node *np, /* * Determine whether a fragment can be extended. * - * Check to see if the necessary fragments are available, and + * Check to see if the necessary fragments are available, and * if they are, allocate them. */ static daddr_t ffs_fragextend(struct node *np, int cg, long bprev, - int osize, + int osize, int nsize) { register struct fs *fs; @@ -1015,7 +1016,7 @@ ffs_alloccg(struct node *np, bno = ffs_alloccgblk(fs, cgp, bpref); /* bdwrite(bp); */ if (releasecg) - release_cg (cgp); + release_cg (cgp); return (bno); } /* @@ -1029,7 +1030,7 @@ ffs_alloccg(struct node *np, break; if (allocsiz == fs->fs_frag) { /* - * no fragments were available, so a block will be + * no fragments were available, so a block will be * allocated, and hacked up */ if (cgp->cg_cs.cs_nbfree == 0) { @@ -1048,7 +1049,7 @@ ffs_alloccg(struct node *np, csum[cg].cs_nffree += i; fs->fs_fmod = 1; cgp->cg_frsum[i]++; - + if (releasecg) release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); @@ -1126,7 +1127,7 @@ ffs_alloccgblk(register struct fs *fs, /* * Block layout information is not available. * Leaving bpref unchanged means we take the - * next available free block following the one + * next available free block following the one * we just allocated. Hopefully this will at * least hit a track cache on drives of unknown * geometry (e.g. SCSI). @@ -1134,7 +1135,7 @@ ffs_alloccgblk(register struct fs *fs, goto norot; } /* - * check the summary information to see if a block is + * check the summary information to see if a block is * available in the requested cylinder starting at the * requested rotational position and proceeding around. */ @@ -1284,7 +1285,7 @@ fail: brelse(bp); return (0); } -#endif +#endif /* * Determine whether an inode can be allocated. @@ -1376,7 +1377,7 @@ gotit: * Free a block or fragment. * * The specified block or fragment is placed back in the - * free map. If a fragment is deallocated, a possible + * free map. If a fragment is deallocated, a possible * block reassembly is checked. */ void @@ -1394,7 +1395,7 @@ ffs_blkfree(register struct node *np, assert ((u_int)size <= fs->fs_bsize && !fragoff (fs, size)); cg = dtog(fs, bno); if ((u_int)bno >= fs->fs_size) { - printf("bad block %ld, ino %d\n", bno, np->dn->number); + printf("bad block %ld, ino %Ld\n", bno, np->dn->number); /* ffs_fserr(fs, ip->i_uid, "bad block"); */ return; } @@ -1408,7 +1409,7 @@ ffs_blkfree(register struct node *np, cgp = (struct cg *)bp->b_data; #else releasecg = read_cg (cg, &cgp); -#endif +#endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ if (releasecg) @@ -1483,7 +1484,7 @@ ffs_blkfree(register struct node *np, * * The specified inode is placed back in the free map. */ -/* Implement diskfs call back diskfs_free_node (described in +/* Implement diskfs call back diskfs_free_node (described in <hurd/diskfs.h>. This was called ffs_vfree in BSD. */ void diskfs_free_node (struct node *np, mode_t mode) @@ -1507,17 +1508,17 @@ diskfs_free_node (struct node *np, mode_t mode) cgp = (struct cg *)bp->b_data; #else releasecg = read_cg (cg, &cgp); -#endif +#endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ if (releasecg) - release_cg (cgp); + release_cg (cgp); return; } cgp->cg_time = diskfs_mtime->seconds; ino %= fs->fs_ipg; if (isclr(cg_inosused(cgp), ino)) { -/* printf("dev = 0x%x, ino = %d, fs = %s\n", +/* printf("dev = 0x%x, ino = %Ld, fs = %s\n", pip->i_dev, ino, fs->fs_fsmnt); */ assert (diskfs_readonly); } @@ -1686,7 +1687,7 @@ ffs_clusteracct(struct fs *fs, #if 0 /* * Fserr prints the name of a file system with an error diagnostic. - * + * * The form of the error message is: * fs: error message */ diff --git a/ufs/consts.c b/ufs/consts.c index 6698c5f4..69221233 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -1,5 +1,5 @@ /* Various constants wanted by the diskfs library - Copyright (C) 1994, 1995 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 @@ -16,8 +16,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" +#include "dir.h" +#include <version.h> int diskfs_link_max = LINK_MAX; +int diskfs_name_max = MAXNAMLEN; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; int diskfs_shortcut_chrdev = 1; @@ -25,7 +28,6 @@ int diskfs_shortcut_blkdev = 1; int diskfs_shortcut_fifo = 1; int diskfs_shortcut_ifsock = 1; char *diskfs_server_name = "ufs"; -int diskfs_major_version = 0; -int diskfs_minor_version = 0; -int diskfs_edit_version = 0; +char *diskfs_server_version = HURD_VERSION; +char *diskfs_extra_version = "GNU Hurd"; int diskfs_synchronous = 0; diff --git a/ufs/devio.c b/ufs/devio.c deleted file mode 100644 index 2e5cc332..00000000 --- a/ufs/devio.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Device input and output - Copyright (C) 1992, 1993, 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 "ufs.h" -#include <device/device.h> -#include <device/device_request.h> - -/* Write disk block ADDR with DATA of LEN bytes, waiting for completion. */ -error_t -dev_write_sync (daddr_t addr, - vm_address_t data, - long len) -{ - int foo; - assert (!diskfs_readonly); - if (device_write (ufs_device, 0, addr, (io_buf_ptr_t) data, len, &foo) - || foo != len) - return EIO; - return 0; -} - -/* Write diskblock ADDR with DATA of LEN bytes; don't bother waiting - for completion. */ -error_t -dev_write (daddr_t addr, - vm_address_t data, - long len) -{ - assert (!diskfs_readonly); - if (device_write_request (ufs_device, MACH_PORT_NULL, 0, addr, - (io_buf_ptr_t) data, len)) - return EIO; - return 0; -} - -static int deverr; - -/* Read disk block ADDR; put the address of the data in DATA; read LEN - bytes. Always *DATA should be a full page no matter what. */ -error_t -dev_read_sync (daddr_t addr, - vm_address_t *data, - long len) -{ - int foo; - deverr = device_read (ufs_device, 0, addr, len, (io_buf_ptr_t *)data, - (u_int *)&foo); - if (deverr || foo != len) - return EIO; - return 0; -} - @@ -1,5 +1,7 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996 Free Software Foundation + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2007 + 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 @@ -64,8 +66,8 @@ struct dirstat /* Index of this directory block. */ int idx; - - /* For stat COMPRESS, this is the address (inside mapbuf) + + /* For stat COMPRESS, this is the address (inside mapbuf) of the first direct in the directory block to be compressed. */ /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ struct directory_entry *entry; @@ -79,24 +81,24 @@ struct dirstat size_t nbytes; }; -size_t diskfs_dirstat_size = sizeof (struct dirstat); +const size_t diskfs_dirstat_size = sizeof (struct dirstat); /* Initialize DS such that diskfs_drop_dirstat will ignore it. */ -void +void diskfs_null_dirstat (struct dirstat *ds) { ds->type = LOOKUP; } -static error_t -dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, struct dirstat *ds, - ino_t *inum); +static error_t +dirscanblock (vm_address_t blockoff, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, + struct dirstat *ds, ino_t *inum); /* Implement the diskfs_lookup from the diskfs library. See <hurd/diskfs.h> for the interface specification. */ error_t -diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, +diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; @@ -111,8 +113,9 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, vm_address_t buf = 0; vm_size_t buflen = 0; int blockaddr; - int idx; - + int idx, lastidx; + int looped; + if ((type == REMOVE) || (type == RENAME)) assert (npp); @@ -121,12 +124,16 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, spec_dotdot = type & SPEC_DOTDOT; type &= ~SPEC_DOTDOT; - + namelen = strlen (name); if (namelen > MAXNAMLEN) - return ENAMETOOLONG; - + { + if (ds) + diskfs_null_dirstat (ds); + return ENAMETOOLONG; + } + try_again: if (ds) { @@ -136,7 +143,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } if (buf) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); buf = 0; } if (ds && (type == CREATE || type == RENAME)) @@ -144,6 +151,10 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp, prot); + + if (memobj == MACH_PORT_NULL) + return errno; + buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); @@ -152,26 +163,45 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, mach_port_deallocate (mach_task_self (), memobj); inum = 0; - - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; - - for (blockaddr = buf, idx = 0; - blockaddr - buf < dp->dn_stat.st_size; - blockaddr += DIRBLKSIZ, idx++) + + diskfs_set_node_atime (dp); + + /* Start the lookup at DP->dn->dir_idx. */ + idx = dp->dn->dir_idx; + if (idx * DIRBLKSIZ > dp->dn_stat.st_size) + idx = 0; /* just in case */ + blockaddr = buf + idx * DIRBLKSIZ; + looped = (idx == 0); + lastidx = idx; + if (lastidx == 0) + lastidx = dp->dn_stat.st_size / DIRBLKSIZ; + + while (!looped || idx < lastidx) { err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum); if (!err) - break; + { + dp->dn->dir_idx = idx; + break; + } if (err != ENOENT) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); return err; } + + blockaddr += DIRBLKSIZ; + idx++; + if (blockaddr - buf >= dp->dn_stat.st_size && !looped) + { + /* We've gotten to the end; start back at the beginning */ + looped = 1; + blockaddr = buf; + idx = 0; + } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -195,7 +225,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, goto out; } } - + /* We are looking up .. */ /* Check to see if this is the root of the filesystem. */ else if (dp->dn->number == 2) @@ -203,7 +233,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, err = EAGAIN; goto out; } - + /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) @@ -237,11 +267,11 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, retry_dotdot = inum; goto try_again; } - + /* Here below are the spec dotdot cases. */ else if (type == RENAME || type == REMOVE) np = ifind (inum); - + else if (type == LOOKUP) { diskfs_nput (dp); @@ -252,13 +282,13 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, else assert (0); } - + if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; ds->stat = EXTEND; - ds->idx = idx; + ds->idx = dp->dn_stat.st_size / DIRBLKSIZ; } /* Return to the user; if we can't, release the reference @@ -269,7 +299,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, || !ds || ds->type == LOOKUP) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); if (ds) ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ } @@ -278,7 +308,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, ds->mapbuf = buf; ds->mapextent = buflen; } - + if (np) { assert (npp); @@ -312,8 +342,8 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, diskfs_lookup. If found, set *INUM to the inode number, else return ENOENT. */ static error_t -dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, +dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, struct dirstat *ds, ino_t *inum) { int nfree = 0; @@ -325,7 +355,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, int looking = 0; int countcopies = 0; int consider_compress = 0; - + if (ds && (ds->stat == LOOKING || ds->stat == COMPRESS)) { @@ -339,30 +369,30 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, prevoff = currentoff, currentoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *)currentoff; - + if (!entry->d_reclen || read_disk_entry (entry->d_reclen) % 4 || DIRECT_NAMLEN (entry) > MAXNAMLEN - || (currentoff + read_disk_entry (entry->d_reclen) + || (currentoff + read_disk_entry (entry->d_reclen) > blockaddr + DIRBLKSIZ) || entry->d_name[DIRECT_NAMLEN (entry)] || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", + fprintf (stderr, "Bad directory entry: inode: %Ld offset: %zd\n", dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } - + if (looking || countcopies) { int thisfree; - + /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) thisfree = read_disk_entry (entry->d_reclen); else - thisfree = (read_disk_entry (entry->d_reclen) + thisfree = (read_disk_entry (entry->d_reclen) - DIRSIZ (DIRECT_NAMLEN (entry))); /* If this isn't at the front of the block, then it will @@ -370,9 +400,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, number of bytes there too. */ if (countcopies && currentoff != blockaddr) nbytes += DIRSIZ (DIRECT_NAMLEN (entry)); - + if (ds->stat == COMPRESS && nbytes > ds->nbytes) - /* The previously found compress is better than + /* The previously found compress is better than this one, so don't bother counting any more. */ countcopies = 0; @@ -389,9 +419,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, nfree += thisfree; if (nfree >= needed) consider_compress = 1; - } + } } - + if (entry->d_ino) nentries++; @@ -402,7 +432,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, break; } - if (consider_compress + if (consider_compress && (ds->type == LOOKING || (ds->type == COMPRESS && ds->nbytes > nbytes))) { @@ -412,7 +442,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->idx = idx; ds->nbytes = nbytes; } - + if (currentoff >= blockaddr + DIRBLKSIZ) { int i; @@ -422,9 +452,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, down how many entries there were. */ if (!dp->dn->dirents) { - dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) - * sizeof (int)); - for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) + * sizeof (int)); + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; } /* Make sure the count is correct if there is one now. */ @@ -434,7 +464,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, return ENOENT; } - + /* We have found the required name. */ if (ds && type == CREATE) @@ -460,7 +490,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, the preceding lookup call, and only if that call returned ENOENT. */ error_t diskfs_direnter_hard(struct node *dp, - char *name, + const char *name, struct node *np, struct dirstat *ds, struct protid *cred) @@ -470,21 +500,21 @@ diskfs_direnter_hard(struct node *dp, int needed = DIRSIZ (namelen); int oldneeded; vm_address_t fromoff, tooff; - int totfreed; + int totfreed; error_t err; - off_t oldsize; + size_t oldsize = 0; assert (ds->type == CREATE); - + dp->dn_set_mtime = 1; switch (ds->stat) { case TAKE: /* We are supposed to consume this slot. */ - assert (ds->entry->d_ino == 0 + assert (ds->entry->d_ino == 0 && read_disk_entry (ds->entry->d_reclen) >= needed); - + write_disk_entry (ds->entry->d_ino, np->dn->number); DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) @@ -492,27 +522,27 @@ diskfs_direnter_hard(struct node *dp, bcopy (name, ds->entry->d_name, namelen + 1); break; - + case SHRINK: /* We are supposed to take the extra space at the end of this slot. */ oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (read_disk_entry (ds->entry->d_reclen) - oldneeded >= needed); - + new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); write_disk_entry (new->d_ino, np->dn->number); - write_disk_entry (new->d_reclen, + write_disk_entry (new->d_reclen, read_disk_entry (ds->entry->d_reclen) - oldneeded); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); - + write_disk_entry (ds->entry->d_reclen, oldneeded); - + break; - + case COMPRESS: /* We are supposed to move all the entries to the front of the block, giving each the minimum @@ -540,7 +570,7 @@ diskfs_direnter_hard(struct node *dp, totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; assert (totfreed >= needed); - + new = (struct directory_entry *) tooff; write_disk_entry (new->d_ino, np->dn->number); write_disk_entry (new->d_reclen, totfreed); @@ -553,14 +583,20 @@ diskfs_direnter_hard(struct node *dp, case EXTEND: /* Extend the file. */ assert (needed <= DIRBLKSIZ); - + oldsize = dp->dn_stat.st_size; + if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size + DIRBLKSIZ) + { + /* We can't possibly map the whole directory in. */ + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + return EOVERFLOW; + } while (oldsize + DIRBLKSIZ > dp->allocsize) { err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); if (err) { - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); return err; } } @@ -577,42 +613,49 @@ diskfs_direnter_hard(struct node *dp, new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; - + default: assert (0); } dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + if (ds->stat != EXTEND) { - /* If we are keeping count of this block, then keep the count up + /* If we are keeping count of this block, then keep the count up to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]++; } else { + int i; /* It's cheap, so start a count here even if we aren't counting anything at all. */ if (dp->dn->dirents) { - dp->dn->dirents = realloc (dp->dn->dirents, - (ds->idx + 1) * sizeof (int)); + dp->dn->dirents = realloc (dp->dn->dirents, + (dp->dn_stat.st_size / DIRBLKSIZ + * sizeof (int))); + for (i = oldsize / DIRBLKSIZ; + i < dp->dn_stat.st_size / DIRBLKSIZ; + i++) + dp->dn->dirents[i] = -1; + dp->dn->dirents[ds->idx] = 1; } else { - int i; - dp->dn->dirents = malloc ((ds->idx + 1) * sizeof (int)); - for (i = 0; i < ds->idx; i++) + dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ + * sizeof (int)); + for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; dp->dn->dirents[ds->idx] = 1; } } - + diskfs_file_update (dp, 1); return 0; @@ -621,7 +664,7 @@ diskfs_direnter_hard(struct node *dp, /* Following a lookup call for REMOVE, this removes the link from the directory. DP is the directory being changed and DS is the cached information returned from lookup. This call is only valid if the - directory has been locked continously since the call to lookup, and + directory has been locked continuously since the call to lookup, and only if that call succeeded. */ error_t diskfs_dirremove_hard(struct node *dp, @@ -629,7 +672,7 @@ diskfs_dirremove_hard(struct node *dp, { assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; if (ds->preventry == 0) @@ -638,48 +681,48 @@ diskfs_dirremove_hard(struct node *dp, { assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry == read_disk_entry (ds->preventry->d_reclen)); - write_disk_entry (ds->preventry->d_reclen, + write_disk_entry (ds->preventry->d_reclen, (read_disk_entry (ds->preventry->d_reclen) + read_disk_entry (ds->entry->d_reclen))); } dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); /* If we are keeping count of this block, then keep the count up to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]--; - + diskfs_file_update (dp, 1); return 0; } - + /* Following a lookup call for RENAME, this changes the inode number - on a directory entry. DP is the directory being changed; NP is - the new node being linked in; DP is the cached information returned + on a directory entry. DP is the directory being changed; NP is + the new node being linked in; DP is the cached information returned by lookup. This call is only valid if the directory has been locked continuously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirrewrite_hard(struct node *dp, +diskfs_dirrewrite_hard(struct node *dp, struct node *np, struct dirstat *ds) { assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; write_disk_entry (ds->entry->d_ino, np->dn->number); if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + diskfs_file_update (dp, 1); return 0; @@ -692,23 +735,26 @@ diskfs_dirempty(struct node *dp, struct protid *cred) { struct directory_entry *entry; - int curoff; - vm_address_t buf; + vm_address_t buf, curoff; memory_object_t memobj; error_t err; memobj = diskfs_get_filemap (dp, VM_PROT_READ); + + if (memobj == MACH_PORT_NULL) + /* XXX should reflect error properly */ + return 0; + buf = 0; - + err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0); mach_port_deallocate (mach_task_self (), memobj); assert (!err); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); - for (curoff = buf; + for (curoff = buf; curoff < buf + dp->dn_stat.st_size; curoff += read_disk_entry (entry->d_reclen)) { @@ -720,19 +766,17 @@ diskfs_dirempty(struct node *dp, || (entry->d_name[1] != '.' && entry->d_name[1] != '\0'))) { - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + munmap ((caddr_t) buf, dp->dn_stat.st_size); + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); return 0; } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + munmap ((caddr_t) buf, dp->dn_stat.st_size); return 1; } @@ -743,7 +787,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) if (ds->type != LOOKUP) { assert (ds->mapbuf); - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); ds->type = LOOKUP; } return 0; @@ -756,7 +800,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) static error_t count_dirents (struct node *dp, int nb, char *buf) { - int amt; + size_t amt; char *offinblk; struct directory_entry *entry; int count = 0; @@ -764,12 +808,12 @@ count_dirents (struct node *dp, int nb, char *buf) assert (dp->dn->dirents); assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size); - + err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt); if (err) return err; assert (amt == DIRBLKSIZ); - + for (offinblk = buf; offinblk < buf + DIRBLKSIZ; offinblk += read_disk_entry (entry->d_reclen)) @@ -778,7 +822,7 @@ count_dirents (struct node *dp, int nb, char *buf) if (entry->d_ino) count++; } - + assert (dp->dn->dirents[nb] == -1 || dp->dn->dirents[nb] == count); dp->dn->dirents[nb] = count; return 0; @@ -787,11 +831,11 @@ count_dirents (struct node *dp, int nb, char *buf) /* Implement the disikfs_get_directs callback as described in <hurd/diskfs.h>. */ error_t -diskfs_get_directs (struct node *dp, - int entry, +diskfs_get_directs (struct node *dp, + int entry, int nentries, char **data, - u_int *datacnt, + size_t *datacnt, vm_size_t bufsiz, int *amt) { @@ -806,9 +850,9 @@ diskfs_get_directs (struct node *dp, char *datap; struct directory_entry *entryp; int allocsize; - int checklen; + size_t checklen; struct dirent *userp; - + nblks = dp->dn_stat.st_size/DIRBLKSIZ; if (!dp->dn->dirents) @@ -818,15 +862,6 @@ diskfs_get_directs (struct node *dp, dp->dn->dirents[i] = -1; } - /* Allocate enough space to hold the maximum we might return */ - if (!bufsiz || bufsiz > dp->dn_stat.st_size) - allocsize = round_page (dp->dn_stat.st_size); - else - allocsize = round_page (bufsiz); - - if (allocsize > *datacnt) - vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); - /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run off the end, ENTRY is too big. */ @@ -847,17 +882,29 @@ diskfs_get_directs (struct node *dp, break; curentry += dp->dn->dirents[blkno]; - + bufvalid = 0; } - + if (blkno == nblks) { + /* We reached the end of the directory without seeing ENTRY. + This is treated as an EOF condition, meaning we return + success with empty results. */ *datacnt = 0; *amt = 0; return 0; } + /* Allocate enough space to hold the maximum we might return */ + if (!bufsiz || bufsiz > dp->dn_stat.st_size) + allocsize = round_page (dp->dn_stat.st_size); + else + allocsize = round_page (bufsiz); + + if (allocsize > *datacnt) + *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + /* Set bufp appropriately */ bufp = buf; if (curentry != entry) @@ -873,15 +920,15 @@ diskfs_get_directs (struct node *dp, assert (checklen == DIRBLKSIZ); bufvalid = 1; } - for (i = 0, bufp = buf; - i < entry - curentry && bufp - buf < DIRBLKSIZ; + for (i = 0, bufp = buf; + i < entry - curentry && bufp - buf < DIRBLKSIZ; (bufp - += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), + += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); - } + } i = 0; datap = *data; @@ -893,7 +940,7 @@ diskfs_get_directs (struct node *dp, { if (!bufvalid) { - err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &checklen); if (err) return err; @@ -924,17 +971,16 @@ diskfs_get_directs (struct node *dp, bufvalid = 0; } } - + /* We've copied all we can. If we allocated our own array but didn't fill all of it, then free whatever memory we didn't use. */ if (allocsize > *datacnt) { if (round_page (datap - *data) < allocsize) - vm_deallocate (mach_task_self (), - (vm_address_t) (*data + round_page (datap - *data)), - allocsize - round_page (datap - *data)); + munmap (*data + round_page (datap - *data), + allocsize - round_page (datap - *data)); } - + /* Set variables for return */ *datacnt = datap - *data; *amt = i; @@ -70,6 +70,7 @@ * dp->d_ino set to 0. */ #define DIRBLKSIZ DEV_BSIZE +#undef MAXNAMLEN #define MAXNAMLEN 255 /* Don't call this struct DIRECT because the library defines that @@ -90,13 +91,13 @@ struct directory_entry { /* Return the namlen from a struct direct, paying attention to whether this filesystem supports the type extension */ #if (BYTE_ORDER == LITTLE_ENDIAN) -#define DIRECT_NAMLEN(dp) (direct_symlink_extension || swab_disk \ - ? (dp)->d_namlen \ - : (dp)->d_type) +#define DIRECT_NAMLEN(dp) (*(direct_symlink_extension || swab_disk \ + ? &(dp)->d_namlen \ + : &(dp)->d_type)) #else -#define DIRECT_NAMLEN(dp) (!direct_symlink_extension && swab_disk \ - ? (dp)->d_type \ - : (dp)->d_namlen) +#define DIRECT_NAMLEN(dp) (*(!direct_symlink_extension && swab_disk \ + ? &(dp)->d_type \ + : &(dp)->d_namlen)) #endif /* diff --git a/ufs/hyper.c b/ufs/hyper.c index e4f58249..ece327a2 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 95, 96, 97, 98, 1999 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,12 +19,13 @@ #include <string.h> #include <stdio.h> #include <error.h> +#include <hurd/store.h> static int ufs_clean; /* fs clean before we started writing? */ static int oldformat; -vm_address_t zeroblock; +void *zeroblock; struct fs *sblock; struct csum *csum; @@ -33,7 +34,7 @@ void swab_sblock (struct fs *sblock) { int i, j; - + sblock->fs_sblkno = swab_long (sblock->fs_sblkno); sblock->fs_cblkno = swab_long (sblock->fs_cblkno); sblock->fs_iblkno = swab_long (sblock->fs_iblkno); @@ -107,24 +108,24 @@ swab_sblock (struct fs *sblock) else for (i = 0; i < sblock->fs_cpc; i++) for (j = 0; j < sblock->fs_nrpos; j++) - fs_postbl(sblock, j)[i] + fs_postbl(sblock, j)[i] = swab_short (fs_postbl (sblock, j)[i]); /* The rot table is all chars */ } - + void swab_csums (struct csum *csum) { int i; - + for (i = 0; i < sblock->fs_ncg; i++) { csum[i].cs_ndir = swab_long (csum[i].cs_ndir); csum[i].cs_nbfree = swab_long (csum[i].cs_nbfree); csum[i].cs_nifree = swab_long (csum[i].cs_nifree); csum[i].cs_nffree = swab_long (csum[i].cs_nffree); - } + } } void @@ -137,7 +138,7 @@ get_hypermetadata (void) /* Free previous values. */ if (zeroblock) - vm_deallocate (mach_task_self (), zeroblock, sblock->fs_bsize); + munmap ((caddr_t) zeroblock, sblock->fs_bsize); if (csum) free (csum); @@ -190,13 +191,13 @@ get_hypermetadata (void) { error (0, 0, "%s: warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck", - diskfs_device_arg); + diskfs_disk_name); if (! diskfs_readonly) { diskfs_readonly = 1; error (0, 0, "%s: MOUNTED READ-ONLY; MUST USE `fsysopts --writable'", - diskfs_device_arg); + diskfs_disk_name); } } @@ -247,18 +248,16 @@ get_hypermetadata (void) if (swab_disk) swab_csums (csum); - if ((diskfs_device_size << diskfs_log2_device_block_size) - < sblock->fs_size * sblock->fs_fsize) + if (store->size < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size (%ld) less than necessary " + "Disk size (%Ld) less than necessary " "(superblock says we need %ld)\n", - diskfs_device_size << diskfs_log2_device_block_size, - sblock->fs_size * sblock->fs_fsize); + store->size, sblock->fs_size * sblock->fs_fsize); exit (1); } - vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); + zeroblock = mmap (0, sblock->fs_bsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); /* If the filesystem has new features in it, don't pay attention to the user's request not to use them. */ @@ -276,11 +275,9 @@ get_hypermetadata (void) taken from ordinary data blocks and might not be an even number of pages; in that case writing it through the pager would nuke whatever pages came after it on the disk and were backed by file pagers. */ -void +error_t diskfs_set_hypermetadata (int wait, int clean) { - vm_address_t buf; - vm_size_t bufsize; error_t err; spin_lock (&alloclock); @@ -289,21 +286,41 @@ diskfs_set_hypermetadata (int wait, int clean) { /* Copy into a page-aligned buffer to avoid bugs in kernel device code. */ - - bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - - err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), - &buf, bufsize); - if (!err) + void *buf = 0; + size_t read = 0; + size_t bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); + + err = store_read (store, + fsbtodb (sblock, sblock->fs_csaddr) + << log2_dev_blocks_per_dev_bsize, + bufsize, &buf, &read); + if (err) + return err; + else if (read != bufsize) + err = EIO; + else { - bcopy (csum, (void *) buf, sblock->fs_cssize); + size_t wrote; + bcopy (csum, buf, sblock->fs_cssize); if (swab_disk) swab_csums ((struct csum *)buf); - diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), - buf, bufsize); - csum_dirty = 0; - vm_deallocate (mach_task_self (), buf, bufsize); + err = store_write (store, + fsbtodb (sblock, sblock->fs_csaddr) + << log2_dev_blocks_per_dev_bsize, + buf, bufsize, &wrote); + if (!err && wrote != bufsize) + err = EIO; } + + munmap (buf, read); + + if (err) + { + spin_unlock (&alloclock); + return err; + } + + csum_dirty = 0; } if (clean && ufs_clean && !sblock->fs_clean) @@ -326,6 +343,7 @@ diskfs_set_hypermetadata (int wait, int clean) copy_sblock (); sync_disk (wait); + return 0; } /* Copy the sblock into the disk */ @@ -376,10 +394,9 @@ copy_sblock () void diskfs_readonly_changed (int readonly) { - vm_protect (mach_task_self (), - (vm_address_t)disk_image, - diskfs_device_size << diskfs_log2_device_block_size, - 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); + (*(readonly ? store_set_flags : store_clear_flags)) (store, STORE_READONLY); + + mprotect (disk_image, store->size, PROT_READ | (readonly ? 0 : PROT_WRITE)); if (readonly) { diff --git a/ufs/inode.c b/ufs/inode.c index 640e6b6f..77a45edb 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,7 @@ /* Inode management routines - Copyright (C) 1994, 1995, 1996 Free Software Foundation + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2007 + 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,6 +22,8 @@ #include <unistd.h> #include <stdio.h> #include <netinet/in.h> +#include <fcntl.h> +#include <hurd/store.h> #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -42,10 +46,10 @@ inode_init () nodehash[n] = 0; } -/* Fetch inode INUM, set *NPP to the node structure; +/* Fetch inode INUM, set *NPP to the node structure; gain one user reference and lock the node. */ -error_t -diskfs_cached_lookup (int inum, struct node **npp) +error_t +diskfs_cached_lookup (ino_t inum, struct node **npp) { struct disknode *dn; struct node *np; @@ -68,6 +72,7 @@ diskfs_cached_lookup (int inum, struct node **npp) dn->number = inum; dn->dirents = 0; + dn->dir_idx = 0; rwlock_init (&dn->allocptrlock); dn->dirty = 0; @@ -85,7 +90,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np); - + if (!diskfs_check_readonly () && !np->dn_stat.st_gen) { spin_lock (&gennumberlock); @@ -95,7 +100,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&gennumberlock); np->dn_set_ctime = 1; } - + if (err) return err; else @@ -111,13 +116,13 @@ struct node * ifind (ino_t inum) { struct node *np; - + spin_lock (&diskfs_node_refcnt_lock); for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) { if (np->dn->number != inum) continue; - + assert (np->references); spin_unlock (&diskfs_node_refcnt_lock); return np; @@ -127,7 +132,7 @@ ifind (ino_t inum) /* The last reference to a node has gone away; drop it from the hash table and clean all state in the dn structure. */ -void +void diskfs_node_norefs (struct node *np) { *np->dn->hprevp = np->dn->hnext; @@ -155,7 +160,7 @@ diskfs_lost_hardrefs (struct node *np) #ifdef notanymore struct port_info *pi; struct pager *p; - + /* Check and see if there is a pager which has only one reference (ours). If so, then drop that reference, breaking the cycle. The complexity in this routine @@ -167,17 +172,17 @@ diskfs_lost_hardrefs (struct node *np) pi = (struct port_info *) np->dn->fileinfo->p; if (pi->refcnt == 1) { - + /* The only way to get a new reference to the pager in this state is to call diskfs_get_filemap; this can't happen as long as we hold NP locked. So we can safely unlock _libports_portrefcntlock for the following call. */ spin_unlock (&_libports_portrefcntlock); - + /* Right now the node is locked with no hard refs; - this is an anomolous situation. Before messing with - the reference count on the file pager, we have to + this is an anomalous situation. Before messing with + the reference count on the file pager, we have to give ourselves a reference back so that we are really allowed to hold the lock. Then we can do the unreference. */ @@ -209,53 +214,41 @@ diskfs_new_hardrefs (struct node *np) static error_t read_disknode (struct node *np) { - static int fsid, fsidset; struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - + err = diskfs_catch_exception (); if (err) return err; - np->istranslated = !! di->di_trans; - - if (!fsidset) - { - fsid = getpid (); - fsidset = 1; - } - st->st_fstype = FSTYPE_UFS; - st->st_fsid = fsid; + st->st_fsid = getpid (); /* This call is very cheap. */ st->st_ino = np->dn->number; st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); - st->st_mode = (read_disk_entry (di->di_model) - | (read_disk_entry (di->di_modeh) << 16)); + st->st_mode = (((read_disk_entry (di->di_model) + | (read_disk_entry (di->di_modeh) << 16)) + & ~S_ITRANS) + | (di->di_trans ? S_IPTRANS : 0)); st->st_nlink = read_disk_entry (di->di_nlink); st->st_size = read_disk_entry (di->di_size); -#ifdef notyet - st->st_atimespec = di->di_atime; - st->st_mtimespec = di->di_mtime; - st->st_ctimespec = di->di_ctime; -#else - st->st_atime = read_disk_entry (di->di_atime.tv_sec); - st->st_atime_usec = read_disk_entry (di->di_atime.tv_nsec) / 1000; - st->st_mtime = read_disk_entry (di->di_mtime.tv_sec); - st->st_mtime_usec = read_disk_entry (di->di_mtime.tv_nsec) / 1000; - st->st_ctime = read_disk_entry (di->di_ctime.tv_sec); - st->st_ctime_usec = read_disk_entry (di->di_ctime.tv_nsec) / 1000; -#endif + st->st_atim.tv_sec = read_disk_entry (di->di_atime.tv_sec); + st->st_atim.tv_nsec = read_disk_entry (di->di_atime.tv_nsec); + st->st_mtim.tv_sec = read_disk_entry (di->di_mtime.tv_sec); + st->st_mtim.tv_nsec = read_disk_entry (di->di_mtime.tv_nsec); + st->st_ctim.tv_sec = read_disk_entry (di->di_ctime.tv_sec); + st->st_ctim.tv_nsec = read_disk_entry (di->di_ctime.tv_nsec); st->st_blksize = sblock->fs_bsize; st->st_blocks = read_disk_entry (di->di_blocks); st->st_flags = read_disk_entry (di->di_flags); - + if (sblock->fs_inodefmt < FS_44INODEFMT) { st->st_uid = read_disk_entry (di->di_ouid); st->st_gid = read_disk_entry (di->di_ogid); - st->st_author = 0; + st->st_author = st->st_uid; + np->author_tracks_uid = 1; } else { @@ -270,8 +263,8 @@ read_disknode (struct node *np) if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) st->st_rdev = 0; - if (S_ISLNK (st->st_mode) - && direct_symlink_extension + if (S_ISLNK (st->st_mode) + && direct_symlink_extension && st->st_size < sblock->fs_maxsymlinklen) np->allocsize = 0; else @@ -297,14 +290,25 @@ error_t diskfs_node_reload (struct node *node) return 0; } +/* Return 0 if NP's author can be changed to AUTHOR; otherwise return an + error code. */ +error_t +diskfs_validate_author_change (struct node *np, uid_t author) +{ + if (compat_mode == COMPAT_GNU) + return 0; + else + /* For non-hurd filesystems, the author & owner are the same. */ + return (author == np->dn_stat.st_uid) ? 0 : EINVAL; +} + static void write_node (struct node *np) { struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - - assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); + if (np->dn_stat_dirty) { assert (!diskfs_readonly); @@ -312,9 +316,9 @@ write_node (struct node *np) err = diskfs_catch_exception (); if (err) return; - + write_disk_entry (di->di_gen, st->st_gen); - + if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) write_disk_entry (di->di_rdev, st->st_rdev); @@ -323,12 +327,13 @@ write_node (struct node *np) if (compat_mode == COMPAT_GNU) { - write_disk_entry (di->di_model, st->st_mode & 0xffff); - write_disk_entry (di->di_modeh, (st->st_mode >> 16) & 0xffff); + mode_t mode = st->st_mode & ~S_ITRANS; + write_disk_entry (di->di_model, mode & 0xffff); + write_disk_entry (di->di_modeh, (mode >> 16) & 0xffff); } - else + else { - write_disk_entry (di->di_model, st->st_mode & 0xffff); + write_disk_entry (di->di_model, st->st_mode & 0xffff & ~S_ITRANS); di->di_modeh = 0; } @@ -337,7 +342,7 @@ write_node (struct node *np) write_disk_entry (di->di_uid, st->st_uid); write_disk_entry (di->di_gid, st->st_gid); } - + if (sblock->fs_inodefmt < FS_44INODEFMT) { write_disk_entry (di->di_ouid, st->st_uid & 0xffff); @@ -348,49 +353,43 @@ write_node (struct node *np) write_disk_entry (di->di_nlink, st->st_nlink); write_disk_entry (di->di_size, st->st_size); -#ifdef notyet - di->di_atime = st->st_atimespec; - di->di_mtime = st->st_mtimespec; - di->di_ctime = st->st_ctimespec; -#else - write_disk_entry (di->di_atime.tv_sec, st->st_atime); - write_disk_entry (di->di_atime.tv_nsec, st->st_atime_usec * 1000); - write_disk_entry (di->di_mtime.tv_sec, st->st_mtime); - write_disk_entry (di->di_mtime.tv_nsec, st->st_mtime_usec * 1000); - write_disk_entry (di->di_ctime.tv_sec, st->st_ctime); - write_disk_entry (di->di_ctime.tv_nsec, st->st_ctime_usec * 1000); -#endif + write_disk_entry (di->di_atime.tv_sec, st->st_atim.tv_sec); + write_disk_entry (di->di_atime.tv_nsec, st->st_atim.tv_nsec); + write_disk_entry (di->di_mtime.tv_sec, st->st_mtim.tv_sec); + write_disk_entry (di->di_mtime.tv_nsec, st->st_mtim.tv_nsec); + write_disk_entry (di->di_ctime.tv_sec, st->st_ctim.tv_sec); + write_disk_entry (di->di_ctime.tv_nsec, st->st_ctim.tv_nsec); write_disk_entry (di->di_blocks, st->st_blocks); write_disk_entry (di->di_flags, st->st_flags); - + diskfs_end_catch_exception (); np->dn_stat_dirty = 0; record_poke (di, sizeof (struct dinode)); } -} +} /* See if we should create a symlink by writing it directly into the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ static error_t -create_symlink_hook (struct node *np, char *target) +create_symlink_hook (struct node *np, const char *target) { int len = strlen (target); error_t err; struct dinode *di; - + if (!direct_symlink_extension) return EINVAL; - + assert (compat_mode != COMPAT_BSD42); if (len >= sblock->fs_maxsymlinklen) return EINVAL; - + err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); bcopy (target, di->di_shortlink, len); np->dn_stat.st_size = len; @@ -401,29 +400,28 @@ create_symlink_hook (struct node *np, char *target) diskfs_end_catch_exception (); return 0; } -error_t (*diskfs_create_symlink_hook)(struct node *, char *) +error_t (*diskfs_create_symlink_hook)(struct node *, const char *) = create_symlink_hook; /* Check if this symlink is stored directly in the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ -static error_t +static error_t read_symlink_hook (struct node *np, char *buf) { error_t err; - - if (!direct_symlink_extension + + if (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen) return EINVAL; err = diskfs_catch_exception (); if (err) return err; - + bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - if (! diskfs_check_readonly ()) - np->dn_set_atime = 1; + diskfs_set_node_atime (np); diskfs_end_catch_exception (); return 0; @@ -439,7 +437,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) struct item *i; error_t err; int n; - + /* Acquire a reference on all the nodes in the hash table and enter them into a list on the stack. */ spin_lock (&diskfs_node_refcnt_lock); @@ -479,10 +477,10 @@ write_all_disknodes () write_node (np); return 0; } - + diskfs_node_iterate (helper); } - + void diskfs_write_disknode (struct node *np, int wait) { @@ -497,23 +495,27 @@ error_t diskfs_set_statfs (struct statfs *st) { st->f_type = FSTYPE_UFS; - st->f_bsize = sblock->fs_bsize; - st->f_blocks = sblock->fs_dsize * sblock->fs_frag; + st->f_bsize = sblock->fs_fsize; + st->f_blocks = sblock->fs_dsize; st->f_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag + sblock->fs_cstotal.cs_nffree); st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) - (sblock->fs_dsize - st->f_bfree)); + if (st->f_bfree < ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100))) + st->f_bavail = 0; st->f_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ st->f_ffree = sblock->fs_cstotal.cs_nifree; st->f_fsid = getpid (); st->f_namelen = 0; + st->f_favail = st->f_ffree; + st->f_frsize = sblock->fs_fsize; return 0; } /* Implement the diskfs_set_translator callback from the diskfs library; see <hurd/diskfs.h> for the interface description. */ error_t -diskfs_set_translator (struct node *np, char *name, u_int namelen, +diskfs_set_translator (struct node *np, const char *name, u_int namelen, struct protid *cred) { daddr_t blkno; @@ -530,10 +532,10 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); blkno = read_disk_entry (di->di_trans); - + if (namelen && !blkno) { /* Allocate block for translator */ @@ -554,10 +556,10 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, di->di_trans = 0; record_poke (di, sizeof (struct dinode)); np->dn_stat.st_blocks -= btodb (sblock->fs_bsize); - np->istranslated = 0; + np->dn_stat.st_mode &= ~S_IPTRANS; np->dn_set_ctime = 1; } - + if (namelen) { bcopy (&namelen, buf, sizeof (u_int)); @@ -566,10 +568,10 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, bcopy (buf, disk_image + fsaddr (sblock, blkno), sblock->fs_bsize); sync_disk_blocks (blkno, sblock->fs_bsize, 1); - np->istranslated = 1; + np->dn_stat.st_mode |= S_IPTRANS; np->dn_set_ctime = 1; } - + diskfs_end_catch_exception (); return err; } @@ -582,7 +584,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) error_t err; daddr_t blkno; u_int datalen; - void *transloc; + const void *transloc; err = diskfs_catch_exception (); if (err) @@ -591,10 +593,17 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) blkno = read_disk_entry ((dino (np->dn->number))->di_trans); assert (blkno); transloc = disk_image + fsaddr (sblock, blkno); - + datalen = *(u_int *)transloc; - *namep = malloc (datalen); - bcopy (transloc + sizeof (u_int), *namep, datalen); + if (datalen > sblock->fs_bsize - sizeof (u_int)) + err = EFTYPE; + else + { + *namep = malloc (datalen); + if (*namep == NULL) + err = ENOMEM; + memcpy (*namep, transloc + sizeof (u_int), datalen); + } diskfs_end_catch_exception (); @@ -619,108 +628,76 @@ diskfs_shutdown_soft_ports () offset into inode block holding inode (4 bytes) */ error_t diskfs_S_file_get_storage_info (struct protid *cred, - int *class, - off_t **addresses, - u_int *naddresses, - size_t *block_size, - char *storage_name, - mach_port_t *storage_port, - mach_msg_type_name_t *storage_port_type, - char **storage_data, - u_int *storage_data_len, - int *flags) + mach_port_t **ports, + mach_msg_type_name_t *ports_type, + mach_msg_type_number_t *num_ports, + int **ints, mach_msg_type_number_t *num_ints, + off_t **offsets, + mach_msg_type_number_t *num_offsets, + char **data, mach_msg_type_number_t *data_len) { error_t err; struct node *np; - int i; - struct dinode *di; - void *cp; - + struct store *file_store; + struct store_run runs[NDADDR]; + size_t num_runs = 0; + + if (! cred) + return EOPNOTSUPP; + np = cred->po->np; mutex_lock (&np->lock); - + /* See if this file fits in the direct block pointers. If not, punt for now. (Reading indir blocks is a pain, and I'm postponing pain.) XXX */ - if (np->allocsize > NDADDR * sblock->fs_bsize) { mutex_unlock (&np->lock); return EINVAL; } - - if (*naddresses < NDADDR * 2) - vm_allocate (mach_task_self (), (vm_address_t *) addresses, - sizeof (int) * NDADDR * 2, 1); - else - bzero (addresses, *naddresses * 2 * sizeof (int)); - *naddresses = NDADDR * 2; - - if (*storage_data_len < 4 * sizeof (int)) - vm_allocate (mach_task_self (), (vm_address_t *) storage_data, - sizeof (int) * 4, 1); - *storage_data_len = 4 * sizeof (int); - di = dino (np->dn->number); - err = diskfs_catch_exception (); - if (err) - { - mutex_unlock (&np->lock); - return err; - } - - /* Copy the block pointers */ + if (! err) + if (!direct_symlink_extension + || np->dn_stat.st_size >= sblock->fs_maxsymlinklen + || !S_ISLNK (np->dn_stat.st_mode)) + /* Copy the block pointers */ + { + int i; + struct store_run *run = runs; + struct dinode *di = dino (np->dn->number); + + for (i = 0; i < NDADDR; i++) + { + store_offset_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); + store_offset_t length = + (((i + 1) * sblock->fs_bsize > np->allocsize) + ? np->allocsize - i * sblock->fs_bsize + : sblock->fs_bsize); + start <<= log2_dev_blocks_per_dev_bsize; + length <<= log2_dev_blocks_per_dev_bsize; + if (num_runs == 0 || run->start + run->length != start) + *run++ = (struct store_run){ start, length }; + else + run->length += length; + } + } + diskfs_end_catch_exception (); - if (!direct_symlink_extension - || np->dn_stat.st_size >= sblock->fs_maxsymlinklen - || !S_ISLNK (np->dn_stat.st_mode)) + mutex_unlock (&np->lock); + + if (! err) + err = store_clone (store, &file_store); + if (! err) { - for (i = 0; i < NDADDR; i++) - { - (*addresses)[2 * i] = fsbtodb (sblock, - read_disk_entry (di->di_db[i])); - if ((i + 1) * sblock->fs_bsize > np->allocsize) - (*addresses)[2 * i + 1] = np->allocsize - i * sblock->fs_bsize; - else - (*addresses)[2 * i + 1] = sblock->fs_bsize; - } + err = store_remap (file_store, runs, num_runs, &file_store); + if (! err) + err = store_return (file_store, ports, num_ports, ints, num_ints, + offsets, num_offsets, data, data_len); + store_free (file_store); } + *ports_type = MACH_MSG_TYPE_COPY_SEND; - /* Fill in the aux data */ - cp = *storage_data; - - *(int *)cp = htonl (np->dn->number); - cp += sizeof (int); - - *(int *)cp = htonl (di->di_trans); - cp += sizeof (int); - - *(int *)cp = htonl (fsbtodb (sblock, ino_to_fsba (sblock, np->dn->number))); - cp += sizeof (int); - - *(int *)cp = htonl (ino_to_fsbo (sblock, np->dn->number) - * sizeof (struct dinode)); - - - diskfs_end_catch_exception (); - - *class = STORAGE_DEVICE; - *flags = 0; - *block_size = DEV_BSIZE; - - if (diskfs_device_name) - strcpy (storage_name, diskfs_device_name); - - if (diskfs_isuid (0, cred)) - *storage_port = diskfs_device; - else - *storage_port = MACH_PORT_NULL; - *storage_port_type = MACH_MSG_TYPE_COPY_SEND; - - mutex_unlock (&np->lock); - - return 0; + return err; } - - @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994,95,96,97,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 @@ -26,9 +26,19 @@ #include <stdlib.h> #include <string.h> #include <argz.h> +#include <argp.h> +#include <hurd/store.h> struct node *diskfs_root_node; +struct store *store = 0; +struct store_parsed *store_parsed = 0; + +char *diskfs_disk_name = 0; + +/* Number of device blocks per DEV_BSIZE block. */ +unsigned log2_dev_blocks_per_dev_bsize = 0; + /* Set diskfs_root_node to the root inode. */ static void warp_root (void) @@ -66,7 +76,7 @@ options[] = {0} }; -/* Parse a command line option. */ +/* Parse a ufs-specific command line option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { @@ -101,6 +111,7 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case ARGP_KEY_INIT: + state->child_inputs[0] = state->input; state->hook = (void *)compat_mode; break; case ARGP_KEY_SUCCESS: compat_mode = (enum compat_mode)state->hook; break; @@ -112,37 +123,34 @@ parse_opt (int key, char *arg, struct argp_state *state) } /* Add our startup arguments to the standard diskfs set. */ -static const struct argp *startup_parents[] = { &diskfs_std_device_startup_argp, 0}; -static struct argp startup_argp = {options, parse_opt, 0, 0, startup_parents}; +static const struct argp_child startup_children[] = + {{&diskfs_store_startup_argp}, {0}}; +static struct argp startup_argp = {options, parse_opt, 0, 0, startup_children}; /* Similarly at runtime. */ -static const struct argp *runtime_parents[] = {&diskfs_std_runtime_argp, 0}; -static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_parents}; +static const struct argp_child runtime_children[] = + {{&diskfs_std_runtime_argp}, {0}}; +static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_children}; struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; /* Override the standard diskfs routine so we can add our own output. */ error_t -diskfs_get_options (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, size_t *argz_len) { error_t err; - *argz = 0; - *argz_len = 0; - /* Get the standard things. */ err = diskfs_append_std_options (argz, argz_len); if (!err && compat_mode != COMPAT_GNU) - { - err = - argz_add (argz, argz_len, - ((compat_mode == COMPAT_BSD42) - ? "--compat=4.2" - : "--compat=4.4")); - if (err) - free (argz); /* Deallocate what diskfs returned. */ - } + err = argz_add (argz, argz_len, + ((compat_mode == COMPAT_BSD42) + ? "--compat=4.2" + : "--compat=4.4")); + + if (! err) + err = store_parsed_append_args (store_parsed, argz, argz_len); return err; } @@ -150,55 +158,28 @@ diskfs_get_options (char **argz, unsigned *argz_len) int main (int argc, char **argv) { - error_t err; - off_t disk_size; mach_port_t bootstrap; - argp_parse (&startup_argp, argc, argv, 0, 0, 0); - - /* This must come after the args have been parsed, as this is where the - host priv ports are set for booting. */ - diskfs_console_stdio (); + /* Initialize the diskfs library, parse arguments, and open the store. + This starts the first diskfs thread for us. */ + store = diskfs_init_main (&startup_argp, argc, argv, + &store_parsed, &bootstrap); - if (diskfs_boot_flags) - { - /* We are the bootstrap filesystem. */ - bootstrap = MACH_PORT_NULL; - diskfs_use_mach_device = 1; - compat_mode = COMPAT_GNU; - } - 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"); + if (store->block_size > DEV_BSIZE) + error (4, 0, "%s: Bad device block size %zd (should be <= %d)", + diskfs_disk_name, store->block_size, DEV_BSIZE); + if (store->size < SBSIZE + SBOFF) + error (5, 0, "%s: Disk too small (%Ld bytes)", diskfs_disk_name, + store->size); - err = diskfs_device_open (); - if (err) - error (3, err, "%s", diskfs_device_arg); - - if (diskfs_device_block_size != DEV_BSIZE) - error (4, err, "%s: Bad device record size %d (should be %d)", - diskfs_device_arg, diskfs_device_block_size, DEV_BSIZE); - if (diskfs_log2_device_block_size == 0) - error (4, err, "%s: Device block size (%d) not a power of 2", - diskfs_device_arg, diskfs_device_block_size); - - disk_size = diskfs_device_size << diskfs_log2_device_block_size; - assert (disk_size >= SBSIZE + SBOFF); + log2_dev_blocks_per_dev_bsize = 0; + while ((1 << log2_dev_blocks_per_dev_bsize) < DEV_BSIZE) + log2_dev_blocks_per_dev_bsize++; + log2_dev_blocks_per_dev_bsize -= store->log2_block_size; /* Map the entire disk. */ create_disk_pager (); - /* Start the first request thread, to handle RPCs and page requests. */ - diskfs_spawn_first_thread (); - get_hypermetadata (); inode_init (); @@ -211,6 +192,8 @@ main (int argc, char **argv) outside world. */ diskfs_startup_diskfs (bootstrap, 0); + /* SET HOST NAME */ + /* And this thread is done with its work. */ cthread_exit (0); @@ -221,7 +204,7 @@ error_t diskfs_reload_global_state () { flush_pokes (); - pager_flush (disk_pager, 1); + pager_flush (diskfs_disk_pager, 1); get_hypermetadata (); return 0; } diff --git a/ufs/mapbuf.c b/ufs/mapbuf.c deleted file mode 100644 index edf432a5..00000000 --- a/ufs/mapbuf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Cache mappings of the disk - Copyright (C) 1994 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - 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 "ufs.h" - -struct mapbuf *mblist; -spin_lock_t mblistlock = SPIN_LOCK_INITIALIZER; - -struct mapbuf * -map_region (vm_offset_t diskloc, vm_size_t length) -{ - struct mapbuf *mb; - - /* Check to see if we are already mapping this region */ - spin_lock (&mblistlock); - for (mb = mblist; mb; mb = mb->next) - { - diff --git a/ufs/pager.c b/ufs/pager.c index bea290ab..3038932d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 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 @@ -19,6 +19,7 @@ #include <strings.h> #include <stdio.h> #include <unistd.h> +#include <hurd/store.h> spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; @@ -32,6 +33,9 @@ spin_lock_t unlocked_pagein_lock = SPIN_LOCK_INITIALIZER; struct port_bucket *pager_bucket; +/* Mapped image of the disk. */ +void *disk_image; + /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has @@ -117,7 +121,14 @@ find_address (struct user_pager_info *upi, { if (*nplock) rwlock_reader_unlock (*nplock); - return EIO; + if (isread) + return EIO; + else + { + *addr = 0; + *disksize = 0; + return 0; + } } if (offset + __vm_page_size > np->allocsize) @@ -161,7 +172,11 @@ pager_read_page (struct user_pager_info *pager, if (addr) { - err = diskfs_device_read_sync (addr, (void *)buf, disksize); + size_t read = 0; + err = store_read (store, addr << log2_dev_blocks_per_dev_bsize, + disksize, (void **)buf, &read); + if (read != disksize) + err = EIO; if (!err && disksize != __vm_page_size) bzero ((void *)(*buf + disksize), __vm_page_size - disksize); *writelock = 0; @@ -172,7 +187,8 @@ pager_read_page (struct user_pager_info *pager, printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page); fflush (stdout); #endif - vm_allocate (mach_task_self (), buf, __vm_page_size, 1); + *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); *writelock = 1; } @@ -199,15 +215,15 @@ pager_write_page (struct user_pager_info *pager, return err; if (addr) - err = diskfs_device_write_sync (addr, buf, disksize); - else { - printf ("Attempt to write unallocated disk\n."); - printf ("Object %p\tOffset %#x\n", pager, page); - fflush (stdout); - err = 0; /* unallocated disk; - error would be pointless */ + size_t wrote; + err = store_write (store, addr << log2_dev_blocks_per_dev_bsize, + (void *)buf, disksize, &wrote); + if (wrote != disksize) + err = EIO; } + else + err = 0; if (nplock) rwlock_reader_unlock (nplock); @@ -286,6 +302,8 @@ pager_unlock_page (struct user_pager_info *pager, /* Check to see if this block is allocated. */ if (indirs[0].bno == 0) { + size_t wrote; + if (indirs[0].offset == -1) { err = ffs_alloc (np, lblkno (sblock, address), @@ -294,9 +312,17 @@ pager_unlock_page (struct user_pager_info *pager, sblock->fs_bsize, &bno, 0); if (err) goto out; + assert (lblkno (sblock, address) < NDADDR); - diskfs_device_write_sync (fsbtodb (sblock, bno), - zeroblock, sblock->fs_bsize); + err = store_write (store, + fsbtodb (sblock, bno) + << log2_dev_blocks_per_dev_bsize, + zeroblock, sblock->fs_bsize, &wrote); + if (!err && wrote != sblock->fs_bsize) + err = EIO; + if (err) + goto out; + indirs[0].bno = bno; write_disk_entry (di->di_db[lblkno (sblock, address)], bno); record_poke (di, sizeof (struct dinode)); @@ -378,8 +404,14 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; - diskfs_device_write_sync (fsbtodb (sblock, bno), - zeroblock, sblock->fs_bsize); + err = store_write (store, + fsbtodb (sblock, bno) + << log2_dev_blocks_per_dev_bsize, + zeroblock, sblock->fs_bsize, &wrote); + if (!err && wrote != sblock->fs_bsize) + err = EIO; + if (err) + goto out; indirs[0].bno = bno; write_disk_entry (siblock[indirs[0].offset], bno); @@ -405,7 +437,7 @@ pager_report_extent (struct user_pager_info *pager, *offset = 0; if (pager->type == DISK) - *size = diskfs_device_size << diskfs_log2_device_block_size; + *size = store->size; else *size = pager->np->allocsize; @@ -436,15 +468,6 @@ pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) -static void -thread_function (any_t foo __attribute__ ((unused))) -{ - for (;;) - ports_manage_port_operations_multithread (pager_bucket, pager_demuxer, - 1000 * 60 * 2, 0, - 1, MACH_PORT_NULL); -} - /* Create the DISK pager. */ void create_disk_pager (void) @@ -453,8 +476,10 @@ create_disk_pager (void) upi->type = DISK; upi->np = 0; - disk_pager_setup (upi, MAY_CACHE); - upi->p = disk_pager; + pager_bucket = ports_create_bucket (); + diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, store->size, + &disk_image); + upi->p = diskfs_disk_pager; } /* This syncs a single file (NP) to disk. Wait for all I/O to complete @@ -546,6 +571,13 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + if (upi->p == 0) + { + diskfs_nrele_light (np); + free (upi); + spin_unlock (&node2pagelock); + return MACH_PORT_NULL; + } np->dn->fileinfo = upi; right = pager_get_port (np->dn->fileinfo->p); ports_port_deref (np->dn->fileinfo->p); @@ -743,7 +775,7 @@ diskfs_shutdown_pager () { struct pager *p = arg; /* Don't ever shut down the disk pager. */ - if (p != disk_pager) + if (p != diskfs_disk_pager) pager_shutdown (p); return 0; } @@ -762,7 +794,7 @@ diskfs_sync_everything (int wait) { struct pager *p = arg; /* Make sure the disk pager is done last. */ - if (p != disk_pager) + if (p != diskfs_disk_pager) pager_sync (p, wait); return 0; } diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c index d09942e8..267aa106 100644 --- a/ufs/pokeloc.c +++ b/ufs/pokeloc.c @@ -75,7 +75,7 @@ sync_disk (int wait) spin_lock (&pokelistlock); for (pl = pokelist; pl; pl = tmp) { - pager_sync_some (disk_pager, pl->offset, pl->length, wait); + pager_sync_some (diskfs_disk_pager, pl->offset, pl->length, wait); tmp = pl->next; free (pl); } diff --git a/ufs/sizes.c b/ufs/sizes.c index a0b090d3..58cbfc98 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999 Free Software Foundation This file is part of the GNU Hurd. @@ -82,8 +82,7 @@ diskfs_truncate (struct node *np, np->allocsize = length; /* temporary */ bsize = blksize (sblock, np, lblkno (sblock, length)); np->allocsize = savesize; - diskfs_node_rdwr (np, (void *) zeroblock, length, - bsize - offset, 1, 0, 0); + diskfs_node_rdwr (np, zeroblock, length, bsize - offset, 1, 0, 0); diskfs_file_update (np, 1); } @@ -105,10 +104,14 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); - poke_pages (obj, round_page (length), round_page (np->allocsize)); - mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (upi->p, round_page (length), - np->allocsize - length, 1); + if (obj != MACH_PORT_NULL) + { + /* XXX should cope with errors from diskfs_get_filemap */ + poke_pages (obj, round_page (length), round_page (np->allocsize)); + mach_port_deallocate (mach_task_self (), obj); + pager_flush_some (upi->p, round_page (length), + np->allocsize - length, 1); + } ports_port_deref (upi->p); } @@ -321,7 +324,7 @@ indir_release (struct node *np, daddr_t bno, int level) the block from the kernel's memory, making sure we do it synchronously--and BEFORE we attach it to the free list with ffs_blkfree. */ - pager_flush_some (disk_pager, fsaddr (sblock, bno), sblock->fs_bsize, 1); + pager_flush_some (diskfs_disk_pager, fsaddr (sblock, bno), sblock->fs_bsize, 1); /* We should also take this block off the inode's list of dirty indirect blocks if it's there. */ @@ -389,7 +392,8 @@ block_extended (struct node *np, don't get paged in from disk. */ if (round_page (old_size) < round_page (new_size)) offer_data (np, lbn * sblock->fs_bsize + round_page (old_size), - round_page (new_size) - round_page (old_size), zeroblock); + round_page (new_size) - round_page (old_size), + (vm_address_t)zeroblock); if (old_pbn != new_pbn) { @@ -400,6 +404,11 @@ block_extended (struct node *np, /* Map in this part of the file */ mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + + /* XXX Should cope with errors from diskfs_get_filemap and back + out the operation here. */ + assert (mapobj); + err = vm_map (mach_task_self (), &mapaddr, round_page (old_size), 0, 1, mapobj, lbn * sblock->fs_bsize, 0, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); @@ -430,7 +439,7 @@ block_extended (struct node *np, /* Undo mapping */ mach_port_deallocate (mach_task_self (), mapobj); - vm_deallocate (mach_task_self (), mapaddr, round_page (old_size)); + munmap ((caddr_t) mapaddr, round_page (old_size)); /* Now it's OK to free the old block */ ffs_blkfree (np, old_pbn, old_size); @@ -477,6 +486,9 @@ diskfs_grow (struct node *np, /* This reference will ensure that NP->dn->fileinfo stays allocated. */ pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + if (pagerpt == MACH_PORT_NULL) + return errno; + /* The new last block of the file. */ lbn = lblkno (sblock, end - 1); @@ -553,7 +565,8 @@ diskfs_grow (struct node *np, goto out; - offer_data (np, lbn * sblock->fs_bsize, size, zeroblock); + offer_data (np, lbn * sblock->fs_bsize, size, + (vm_address_t)zeroblock); write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; @@ -647,7 +660,8 @@ diskfs_grow (struct node *np, sblock->fs_bsize, &bno, 0); if (err) goto out; - offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, zeroblock); + offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, + (vm_address_t)zeroblock); indirs[0].bno = bno; write_disk_entry (siblock[indirs[0].offset], bno); record_poke (siblock, sblock->fs_bsize); @@ -697,7 +711,7 @@ poke_pages (memory_object_t obj, { for (poke = addr; poke < addr + len; poke += vm_page_size) *(volatile int *)poke = *(volatile int *)poke; - vm_deallocate (mach_task_self (), addr, len); + munmap ((caddr_t) addr, len); } start += len; } @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 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,15 +17,24 @@ #include <mach.h> #include <hurd.h> +#include <sys/mman.h> #include <hurd/ports.h> #include <hurd/pager.h> #include <hurd/fshelp.h> #include <hurd/iohelp.h> #include <hurd/diskfs.h> +#include <sys/mman.h> #include <assert.h> +#include <features.h> #include "fs.h" #include "dinode.h" +#ifdef UFS_DEFINE_EI +#define UFS_EI +#else +#define UFS_EI __extern_inline +#endif + /* Define this if memory objects should not be cached by the kernel. Normally, don't define it, but defining it causes a much greater rate of paging requests, which may be helpful in catching bugs. */ @@ -36,6 +45,8 @@ struct disknode { ino_t number; + int dir_idx; + /* For a directory, this array holds the number of directory entries in each DIRBLKSIZE piece of the directory. */ int *dirents; @@ -79,14 +90,22 @@ struct user_pager_info } type; struct pager *p; vm_prot_t max_prot; - + vm_offset_t allow_unlocked_pagein; vm_size_t unlocked_pagein_length; }; #include <hurd/diskfs-pager.h> -extern vm_address_t zeroblock; +/* The physical media. */ +extern struct store *store; +/* What the user specified. */ +extern struct store_parsed *store_parsed; + +/* Mapped image of the disk. */ +extern void *disk_image; + +extern void *zeroblock; extern struct fs *sblock; extern struct csum *csum; @@ -120,6 +139,8 @@ int direct_symlink_extension; /* If this is set, then the disk is byteswapped from native order. */ int swab_disk; +/* Number of device blocks per DEV_BSIZE block. */ +unsigned log2_dev_blocks_per_dev_bsize; /* Handy macros */ #define DEV_BSIZE 512 @@ -136,8 +157,18 @@ int swab_disk; /* Functions for looking inside disk_image */ +extern struct dinode * dino (ino_t inum); +extern daddr_t * indir_block (daddr_t bno); +extern struct cg * cg_locate (int ncg); +extern void sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait); +extern void sync_dinode (int inum, int wait); +extern short swab_short (short arg); +extern long swab_long (long arg); +extern long long swab_long_long (long long arg); + +#if defined(__USE_EXTERN_INLINES) || defined(UFS_DEFINE_EI) /* Convert an inode number to the dinode on disk. */ -extern inline struct dinode * +UFS_EI struct dinode * dino (ino_t inum) { return (struct dinode *) @@ -147,28 +178,28 @@ dino (ino_t inum) } /* Convert a indirect block number to a daddr_t table. */ -extern inline daddr_t * +UFS_EI daddr_t * indir_block (daddr_t bno) { return (daddr_t *) (disk_image + fsaddr (sblock, bno)); } /* Convert a cg number to the cylinder group. */ -extern inline struct cg * +UFS_EI struct cg * cg_locate (int ncg) { return (struct cg *) (disk_image + fsaddr (sblock, cgtod (sblock, ncg))); } /* Sync part of the disk */ -extern inline void +UFS_EI void sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait) { - pager_sync_some (disk_pager, fsaddr (sblock, blkno), nbytes, wait); + pager_sync_some (diskfs_disk_pager, fsaddr (sblock, blkno), nbytes, wait); } /* Sync an disk inode */ -extern inline void +UFS_EI void sync_dinode (int inum, int wait) { sync_disk_blocks (ino_to_fsba (sblock, inum), sblock->fs_fsize, wait); @@ -176,26 +207,27 @@ sync_dinode (int inum, int wait) /* Functions for byte swapping */ -extern inline short +UFS_EI short swab_short (short arg) { return (((arg & 0xff) << 8) | ((arg & 0xff00) >> 8)); } -extern inline long +UFS_EI long swab_long (long arg) { return (((long) swab_short (arg & 0xffff) << 16) | swab_short ((arg & 0xffff0000) >> 16)); } -extern inline long long +UFS_EI long long swab_long_long (long long arg) { return (((long long) swab_long (arg & 0xffffffff) << 32) - | swab_long ((arg & 0xffffffff00000000lL) >> 32)); + | swab_long ((arg & 0xffffffff00000000LL) >> 32)); } +#endif /* Use extern inlines. */ /* Return ENTRY, after byteswapping it if necessary */ #define read_disk_entry(entry) \ @@ -211,7 +243,7 @@ swab_long_long (long long arg) abort (); \ ret; \ }) - + /* Execute A = B, but byteswap it along the way if necessary */ #define write_disk_entry(a,b) \ ({ \ diff --git a/ufs/xinl.c b/ufs/xinl.c new file mode 100644 index 00000000..7994a1f7 --- /dev/null +++ b/ufs/xinl.c @@ -0,0 +1,2 @@ +#define UFS_DEFINE_EI +#include "ufs.h" |