43 |
#define NBD_REQUEST_MAGIC (htonl (0x25609513)) |
#define NBD_REQUEST_MAGIC (htonl (0x25609513)) |
44 |
#define NBD_REPLY_MAGIC (htonl (0x67446698)) |
#define NBD_REPLY_MAGIC (htonl (0x67446698)) |
45 |
|
|
46 |
|
#define NBD_IO_MAX 10240 |
47 |
|
|
48 |
struct nbd_startup |
struct nbd_startup |
49 |
{ |
{ |
50 |
char magic[16]; /* NBD_INIT_MAGIC */ |
char magic[16]; /* NBD_INIT_MAGIC */ |
122 |
{ |
{ |
123 |
magic: NBD_REQUEST_MAGIC, |
magic: NBD_REQUEST_MAGIC, |
124 |
type: htonl (1), /* WRITE */ |
type: htonl (1), /* WRITE */ |
|
from: htonll (addr << store->log2_block_size), |
|
|
len: htonl (len) |
|
125 |
}; |
}; |
126 |
error_t err; |
error_t err; |
127 |
mach_msg_type_number_t cc; |
mach_msg_type_number_t cc; |
128 |
|
|
129 |
err = io_write (store->port, (char *) &req, sizeof req, -1, &cc); |
addr <<= store->log2_block_size; |
|
if (err) |
|
|
return err; |
|
|
if (cc != sizeof req) |
|
|
return EIO; |
|
|
|
|
130 |
*amount = 0; |
*amount = 0; |
131 |
|
|
132 |
do |
do |
133 |
{ |
{ |
134 |
err = io_write (store->port, (char *) buf, len - *amount, -1, &cc); |
size_t chunk = len < NBD_IO_MAX ? len : NBD_IO_MAX, nwrote; |
135 |
|
req.from = htonll (addr); |
136 |
|
req.len = htonl (chunk); |
137 |
|
|
138 |
|
err = io_write (store->port, (char *) &req, sizeof req, -1, &cc); |
139 |
if (err) |
if (err) |
140 |
return err; |
return err; |
141 |
buf += cc; |
if (cc != sizeof req) |
142 |
*amount += cc; |
return EIO; |
|
} while (*amount < len); |
|
143 |
|
|
144 |
return read_reply (store, req.handle); |
nwrote = 0; |
145 |
|
do |
146 |
|
{ |
147 |
|
err = io_write (store->port, (char *) buf, chunk - nwrote, -1, &cc); |
148 |
|
if (err) |
149 |
|
return err; |
150 |
|
buf += cc; |
151 |
|
nwrote += cc; |
152 |
|
} while (nwrote < chunk); |
153 |
|
|
154 |
|
err = read_reply (store, req.handle); |
155 |
|
if (err) |
156 |
|
return err; |
157 |
|
|
158 |
|
addr += chunk; |
159 |
|
*amount += chunk; |
160 |
|
len -= chunk; |
161 |
|
} while (len > 0); |
162 |
|
|
163 |
|
return 0; |
164 |
} |
} |
165 |
|
|
166 |
static error_t |
static error_t |
172 |
{ |
{ |
173 |
magic: NBD_REQUEST_MAGIC, |
magic: NBD_REQUEST_MAGIC, |
174 |
type: htonl (0), /* READ */ |
type: htonl (0), /* READ */ |
|
from: htonll (addr << store->log2_block_size), |
|
|
len: htonl (amount), |
|
175 |
}; |
}; |
176 |
error_t err; |
error_t err; |
177 |
mach_msg_type_number_t cc; |
mach_msg_type_number_t cc; |
178 |
|
|
179 |
|
if (amount > NBD_IO_MAX) |
180 |
|
amount = NBD_IO_MAX; |
181 |
|
|
182 |
|
addr <<= store->log2_block_size; |
183 |
|
|
184 |
|
req.from = htonll (addr); |
185 |
|
req.len = htonl (amount); |
186 |
|
|
187 |
err = io_write (store->port, (char *) &req, sizeof req, -1, &cc); |
err = io_write (store->port, (char *) &req, sizeof req, -1, &cc); |
188 |
if (err) |
if (err) |
189 |
return err; |
return err; |
192 |
|
|
193 |
err = read_reply (store, req.handle); |
err = read_reply (store, req.handle); |
194 |
if (err == 0) |
if (err == 0) |
195 |
err = io_read (store->port, (char **) buf, len, (off_t) -1, amount); |
err = io_read (store->port, (char **) buf, &cc, (off_t) -1, amount); |
196 |
return err; |
return err; |
197 |
} |
} |
198 |
|
|