summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2001-12-30 00:59:12 +0000
committerRoland McGrath <roland@gnu.org>2001-12-30 00:59:12 +0000
commita6c81e7db4148a965d7dc2d166d8c6e69d65a8c7 (patch)
treec4cca121a60ccc1728c91097ce2950fa278ac88c
parentce9f2b8cc21d00b4b1604a07a653ea7bec1f67b2 (diff)
2001-12-29 Roland McGrath <roland@frob.com>
* nbd.c (NBD_IO_MAX): New macro. (nbd_write): Write in chunks no larger than NBD_IO_MAX. (nbd_read): Cap AMOUNT to NBD_IO_MAX.
-rw-r--r--libstore/nbd.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/libstore/nbd.c b/libstore/nbd.c
index c3a3ef66..9130db43 100644
--- a/libstore/nbd.c
+++ b/libstore/nbd.c
@@ -43,6 +43,8 @@
#define NBD_REQUEST_MAGIC (htonl (0x25609513))
#define NBD_REPLY_MAGIC (htonl (0x67446698))
+#define NBD_IO_MAX 10240
+
struct nbd_startup
{
char magic[16]; /* NBD_INIT_MAGIC */
@@ -120,29 +122,45 @@ nbd_write (struct store *store,
{
magic: NBD_REQUEST_MAGIC,
type: htonl (1), /* WRITE */
- from: htonll (addr << store->log2_block_size),
- len: htonl (len)
};
error_t err;
mach_msg_type_number_t cc;
- err = io_write (store->port, (char *) &req, sizeof req, -1, &cc);
- if (err)
- return err;
- if (cc != sizeof req)
- return EIO;
-
+ addr <<= store->log2_block_size;
*amount = 0;
+
do
{
- err = io_write (store->port, (char *) buf, len - *amount, -1, &cc);
+ size_t chunk = len < NBD_IO_MAX ? len : NBD_IO_MAX, nwrote;
+ req.from = htonll (addr);
+ req.len = htonl (chunk);
+
+ err = io_write (store->port, (char *) &req, sizeof req, -1, &cc);
+ if (err)
+ return err;
+ if (cc != sizeof req)
+ return EIO;
+
+ nwrote = 0;
+ do
+ {
+ err = io_write (store->port, (char *) buf, chunk - nwrote, -1, &cc);
+ if (err)
+ return err;
+ buf += cc;
+ nwrote += cc;
+ } while (nwrote < chunk);
+
+ err = read_reply (store, req.handle);
if (err)
return err;
- buf += cc;
- *amount += cc;
- } while (*amount < len);
- return read_reply (store, req.handle);
+ addr += chunk;
+ *amount += chunk;
+ len -= chunk;
+ } while (len > 0);
+
+ return 0;
}
static error_t
@@ -154,12 +172,18 @@ nbd_read (struct store *store,
{
magic: NBD_REQUEST_MAGIC,
type: htonl (0), /* READ */
- from: htonll (addr << store->log2_block_size),
- len: htonl (amount),
};
error_t err;
mach_msg_type_number_t cc;
+ if (amount > NBD_IO_MAX)
+ amount = NBD_IO_MAX;
+
+ addr <<= store->log2_block_size;
+
+ req.from = htonll (addr);
+ req.len = htonl (amount);
+
err = io_write (store->port, (char *) &req, sizeof req, -1, &cc);
if (err)
return err;
@@ -168,7 +192,7 @@ nbd_read (struct store *store,
err = read_reply (store, req.handle);
if (err == 0)
- err = io_read (store->port, (char **) buf, len, (off_t) -1, amount);
+ err = io_read (store->port, (char **) buf, &cc, (off_t) -1, amount);
return err;
}