diff options
author | Roland McGrath <roland@gnu.org> | 1999-11-21 04:27:23 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1999-11-21 04:27:23 +0000 |
commit | d4139b9468005e145ba4c9fffa90b212de05e7d5 (patch) | |
tree | 0b2f89e42395f814345f1de6dff41945e21a01ad /storeio | |
parent | 1a69c12f73b7df071d87ed26a4e89c26cb7b05eb (diff) |
1999-11-20 Roland McGrath <roland@baalperazim.frob.com>
* dev.c (dev_read, dev_write): In DEV->inhibit_cache case,
handle zero (i.e. unknown) block_size by treating it as 1.
Use shift and bitwise-and rather than multiply and modulus
for block size arithmetic, since it's a known power of two.
Diffstat (limited to 'storeio')
-rw-r--r-- | storeio/dev.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/storeio/dev.c b/storeio/dev.c index cf557f46..0a713253 100644 --- a/storeio/dev.c +++ b/storeio/dev.c @@ -348,12 +348,17 @@ dev_write (struct dev *dev, off_t offs, void *buf, size_t len, struct store *store = dev->store; - if (offs % store->block_size != 0 || len % store->block_size != 0) + if (store->block_size == 0) + /* We don't know the block size, so let the device enforce it. */ + return store_write (dev->store, offs, buf, len, amount); + + if ((offs & (store->block_size - 1)) != 0 + || (len & (store->block_size - 1)) != 0) /* Not whole blocks. No can do. */ - return EINVAL; + return EINVAL; /* EIO? */ /* Do a direct write to the store. */ - return store_write (dev->store, offs * store->block_size, + return store_write (dev->store, offs << store->log2_block_size, buf, len, amount); } @@ -425,18 +430,25 @@ 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. */ + Note that in this case we handle non-power-of-two block sizes. + We could, that is, but libstore won't have it (see libstore/make.c). + If the device does not report a block size, we let any attempt + through on the assumption the device will enforce its own limits. */ struct store *store = dev->store; - if (offs % store->block_size != 0 - || whole_amount % store->block_size != 0) + if (store->block_size == 0) + /* We don't know the block size, so let the device enforce it. */ + return store_read (dev->store, offs, whole_amount, buf, len); + + if ((offs & (store->block_size - 1)) != 0 + || (whole_amount & (store->block_size - 1)) != 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); + return store_read (dev->store, offs << store->log2_block_size, + whole_amount, buf, len); } err = dev_rw (dev, offs, whole_amount, len, buf_read, raw_read); |