diff options
author | Roland McGrath <roland@gnu.org> | 1999-01-27 20:46:47 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1999-01-27 20:46:47 +0000 |
commit | 8e8f1f026b493aeea075d4f1cbc05bbf0dd6cec6 (patch) | |
tree | fe387c55550994e63545bb880b143bc6e2f4661d /storeio/dev.c | |
parent | 917384c096a24625c84ab8901901a45e2f2f055f (diff) |
1999-01-27 Roland McGrath <roland@baalperazim.frob.com>
* storeio.c (options): New option -c/--no-cache.
(inhibit_cache): New variable.
(parse_opt): Make -c set it.
(trivfs_append_args): Report --no-cache if set.
(check_open_hook): Pass inhibit_cache flag to dev_open.
* dev.h (struct dev): New member `inhibit_cache'.
(dev_open): Update decl.
* dev.c (dev_open): Take new arg inhibit_cache, store in new dev.
If set, don't initialize buf_offs, io_lock, pager, pager_lock.
(dev_read, dev_write): If DEV->inhibit_cache is set, allow only
whole-block i/o: EINVAL for non-whole-block attempts.
* pager.c (dev_get_memory_object): If DEV->inhibit_cache is set, don't
make our own pager; if store_map returns EOPNOTSUPP, so do we.
Diffstat (limited to 'storeio/dev.c')
-rw-r--r-- | storeio/dev.c | 68 |
1 files changed, 56 insertions, 12 deletions
diff --git a/storeio/dev.c b/storeio/dev.c index 2f81f32a..30828556 100644 --- a/storeio/dev.c +++ b/storeio/dev.c @@ -1,6 +1,6 @@ /* store `device' I/O - Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -138,7 +138,8 @@ dev_buf_rw (struct dev *dev, size_t buf_offs, size_t *io_offs, size_t *len, desired block size, and must be a multiple of the device block size. If an error occurs, the error code is returned, otherwise 0. */ error_t -dev_open (struct store_parsed *name, int flags, struct dev **dev) +dev_open (struct store_parsed *name, int flags, int inhibit_cache, + struct dev **dev) { error_t err; struct dev *new = malloc (sizeof (struct dev)); @@ -161,12 +162,16 @@ dev_open (struct store_parsed *name, int flags, struct dev **dev) return ENOMEM; } - new->buf_offs = -1; - rwlock_init (&new->io_lock); + new->inhibit_cache = inhibit_cache; new->owner = 0; - new->block_mask = (1 << new->store->log2_block_size) - 1; - new->pager = 0; - mutex_init (&new->pager_lock); + if (!inhibit_cache) + { + new->buf_offs = -1; + rwlock_init (&new->io_lock); + new->block_mask = (1 << new->store->log2_block_size) - 1; + new->pager = 0; + mutex_init (&new->pager_lock); + } *dev = new; return 0; @@ -176,13 +181,16 @@ dev_open (struct store_parsed *name, int flags, struct dev **dev) void dev_close (struct dev *dev) { - if (dev->pager != NULL) - pager_shutdown (dev->pager); + if (!dev->inhibit_cache) + { + if (dev->pager != NULL) + pager_shutdown (dev->pager); - dev_buf_discard (dev); + dev_buf_discard (dev); - vm_deallocate (mach_task_self (), - (vm_address_t)dev->buf, dev->store->block_size); + vm_deallocate (mach_task_self (), + (vm_address_t)dev->buf, dev->store->block_size); + } store_free (dev->store); @@ -196,6 +204,9 @@ dev_sync(struct dev *dev, int wait) { error_t err; + if (dev->inhibit_cache) + return 0; + /* Sync any paged backing store. */ if (dev->pager != NULL) pager_sync (dev->pager, wait); @@ -330,6 +341,22 @@ dev_write (struct dev *dev, off_t offs, void *buf, size_t len, buf + io_offs, len, amount); } + if (dev->inhibit_cache) + { + /* Under --no-cache, we permit only whole-block writes. + Note that in this case we handle non-power-of-two block sizes. */ + + struct store *store = dev->store; + + if (offs % store->block_size != 0 || len % store->block_size != 0) + /* Not whole blocks. No can do. */ + return EINVAL; + + /* Do a direct write to the store. */ + return store_write (dev->store, offs * store->block_size, + buf, len, amount); + } + return dev_rw (dev, offs, len, amount, buf_write, raw_write); } @@ -397,6 +424,23 @@ dev_read (struct dev *dev, off_t offs, size_t whole_amount, } } + if (dev->inhibit_cache) + { + /* Under --no-cache, we permit only whole-block reads. + Note that in this case we handle non-power-of-two block sizes. */ + + struct store *store = dev->store; + + if (offs % store->block_size != 0 + || whole_amount % store->block_size != 0) + /* Not whole blocks. No can do. */ + return EINVAL; + + /* Do a direct read from the store. */ + return store_read (dev->store, offs * store->block_size, whole_amount, + buf, len); + } + err = dev_rw (dev, offs, whole_amount, len, buf_read, raw_read); if (err && allocated_buf) vm_deallocate (mach_task_self (), (vm_address_t)*buf, whole_amount); |