]>
Commit | Line | Data |
---|---|---|
b224ea98 | 1 | |
30a4f2a8 | 2 | /* |
0e473d70 | 3 | * $Id: disk.cc,v 1.98 1998/02/02 21:16:21 wessels Exp $ |
30a4f2a8 | 4 | * |
5 | * DEBUG: section 6 Disk I/O Routines | |
6 | * AUTHOR: Harvest Derived | |
7 | * | |
42c04c16 | 8 | * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ |
30a4f2a8 | 9 | * -------------------------------------------------------- |
10 | * | |
11 | * Squid is the result of efforts by numerous individuals from the | |
12 | * Internet community. Development is led by Duane Wessels of the | |
13 | * National Laboratory for Applied Network Research and funded by | |
14 | * the National Science Foundation. | |
15 | * | |
16 | * This program is free software; you can redistribute it and/or modify | |
17 | * it under the terms of the GNU General Public License as published by | |
18 | * the Free Software Foundation; either version 2 of the License, or | |
19 | * (at your option) any later version. | |
20 | * | |
21 | * This program is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License | |
27 | * along with this program; if not, write to the Free Software | |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 | * | |
30 | */ | |
31 | ||
32 | /* | |
33 | * Copyright (c) 1994, 1995. All rights reserved. | |
34 | * | |
35 | * The Harvest software was developed by the Internet Research Task | |
36 | * Force Research Group on Resource Discovery (IRTF-RD): | |
37 | * | |
38 | * Mic Bowman of Transarc Corporation. | |
39 | * Peter Danzig of the University of Southern California. | |
40 | * Darren R. Hardy of the University of Colorado at Boulder. | |
41 | * Udi Manber of the University of Arizona. | |
42 | * Michael F. Schwartz of the University of Colorado at Boulder. | |
43 | * Duane Wessels of the University of Colorado at Boulder. | |
44 | * | |
45 | * This copyright notice applies to software in the Harvest | |
46 | * ``src/'' directory only. Users should consult the individual | |
47 | * copyright notices in the ``components/'' subdirectories for | |
48 | * copyright information about other software bundled with the | |
49 | * Harvest source code distribution. | |
50 | * | |
51 | * TERMS OF USE | |
52 | * | |
53 | * The Harvest software may be used and re-distributed without | |
54 | * charge, provided that the software origin and research team are | |
55 | * cited in any use of the system. Most commonly this is | |
56 | * accomplished by including a link to the Harvest Home Page | |
57 | * (http://harvest.cs.colorado.edu/) from the query page of any | |
58 | * Broker you deploy, as well as in the query result pages. These | |
59 | * links are generated automatically by the standard Broker | |
60 | * software distribution. | |
61 | * | |
62 | * The Harvest software is provided ``as is'', without express or | |
63 | * implied warranty, and with no support nor obligation to assist | |
64 | * in its use, correction, modification or enhancement. We assume | |
65 | * no liability with respect to the infringement of copyrights, | |
66 | * trade secrets, or any patents, and are not responsible for | |
67 | * consequential damages. Proper use of the Harvest software is | |
68 | * entirely the responsibility of the user. | |
69 | * | |
70 | * DERIVATIVE WORKS | |
71 | * | |
72 | * Users may make derivative works from the Harvest software, subject | |
73 | * to the following constraints: | |
74 | * | |
75 | * - You must include the above copyright notice and these | |
76 | * accompanying paragraphs in all forms of derivative works, | |
77 | * and any documentation and other materials related to such | |
78 | * distribution and use acknowledge that the software was | |
79 | * developed at the above institutions. | |
80 | * | |
81 | * - You must notify IRTF-RD regarding your distribution of | |
82 | * the derivative work. | |
83 | * | |
84 | * - You must clearly notify users that your are distributing | |
85 | * a modified version and not the original Harvest software. | |
86 | * | |
87 | * - Any derivative product is also subject to these copyright | |
88 | * and use restrictions. | |
89 | * | |
90 | * Note that the Harvest software is NOT in the public domain. We | |
91 | * retain copyright, as specified above. | |
92 | * | |
93 | * HISTORY OF FREE SOFTWARE STATUS | |
94 | * | |
95 | * Originally we required sites to license the software in cases | |
96 | * where they were going to build commercial products/services | |
97 | * around Harvest. In June 1995 we changed this policy. We now | |
98 | * allow people to use the core Harvest software (the code found in | |
99 | * the Harvest ``src/'' directory) for free. We made this change | |
100 | * in the interest of encouraging the widest possible deployment of | |
101 | * the technology. The Harvest software is really a reference | |
102 | * implementation of a set of protocols and formats, some of which | |
103 | * we intend to standardize. We encourage commercial | |
104 | * re-implementations of code complying to this set of standards. | |
105 | */ | |
ed43818f | 106 | |
44a47c6e | 107 | #include "squid.h" |
090089c4 | 108 | |
109 | #define DISK_LINE_LEN 1024 | |
090089c4 | 110 | |
0a0bf5db | 111 | typedef struct disk_ctrl_t { |
112 | int fd; | |
113 | void *data; | |
114 | } disk_ctrl_t; | |
115 | ||
116 | ||
117 | typedef struct open_ctrl_t { | |
f17936ab | 118 | FOCB *callback; |
0a0bf5db | 119 | void *callback_data; |
120 | char *path; | |
121 | } open_ctrl_t; | |
122 | ||
de866d20 | 123 | static AIOCB diskHandleWriteComplete; |
124 | static AIOCB diskHandleReadComplete; | |
95d15928 | 125 | static PF diskHandleRead; |
126 | static PF diskHandleWrite; | |
f5b8bbc4 | 127 | static void file_open_complete(void *, int, int); |
24382924 | 128 | |
090089c4 | 129 | /* initialize table */ |
b8d8561b | 130 | int |
0673c0ba | 131 | disk_init(void) |
090089c4 | 132 | { |
090089c4 | 133 | return 0; |
134 | } | |
135 | ||
136 | /* Open a disk file. Return a file descriptor */ | |
684c2720 | 137 | int |
6cf028ab | 138 | file_open(const char *path, int mode, FOCB * callback, void *callback_data, void *tag) |
090089c4 | 139 | { |
090089c4 | 140 | int fd; |
0a0bf5db | 141 | open_ctrl_t *ctrlp; |
142 | ||
143 | ctrlp = xmalloc(sizeof(open_ctrl_t)); | |
144 | ctrlp->path = xstrdup(path); | |
145 | ctrlp->callback = callback; | |
146 | ctrlp->callback_data = callback_data; | |
090089c4 | 147 | |
b59c7120 | 148 | if (mode & O_WRONLY) |
149 | mode |= O_APPEND; | |
4f92c80c | 150 | mode |= SQUID_NONBLOCK; |
b59c7120 | 151 | |
090089c4 | 152 | /* Open file */ |
0a0bf5db | 153 | #if USE_ASYNC_IO |
f17936ab | 154 | if (callback != NULL) { |
6cf028ab | 155 | aioOpen(path, mode, 0644, file_open_complete, ctrlp, tag); |
9e4ad609 | 156 | return DISK_OK; |
0a0bf5db | 157 | } |
f17936ab | 158 | #endif |
0a0bf5db | 159 | fd = open(path, mode, 0644); |
160 | file_open_complete(ctrlp, fd, errno); | |
161 | if (fd < 0) | |
162 | return DISK_ERROR; | |
163 | return fd; | |
0a0bf5db | 164 | } |
165 | ||
166 | ||
167 | static void | |
95d15928 | 168 | file_open_complete(void *data, int fd, int errcode) |
0a0bf5db | 169 | { |
170 | open_ctrl_t *ctrlp = (open_ctrl_t *) data; | |
6cf028ab | 171 | |
0e473d70 | 172 | if (fd == -2 && errcode == -2) { /* Cancelled - clean up */ |
6cf028ab | 173 | if (ctrlp->callback) |
174 | (ctrlp->callback) (ctrlp->callback_data, fd, errcode); | |
175 | xfree(ctrlp->path); | |
176 | xfree(ctrlp); | |
177 | return; | |
178 | } | |
0a0bf5db | 179 | if (fd < 0) { |
180 | errno = errcode; | |
a3d5953d | 181 | debug(50, 0) ("file_open: error opening file %s: %s\n", ctrlp->path, |
0a0bf5db | 182 | xstrerror()); |
183 | if (ctrlp->callback) | |
6cf028ab | 184 | (ctrlp->callback) (ctrlp->callback_data, DISK_ERROR, errcode); |
0a0bf5db | 185 | xfree(ctrlp->path); |
186 | xfree(ctrlp); | |
187 | return; | |
090089c4 | 188 | } |
365e5b34 | 189 | debug(6, 5) ("file_open: FD %d\n", fd); |
3ca60c86 | 190 | commSetCloseOnExec(fd); |
5c5783a2 | 191 | fd_open(fd, FD_FILE, ctrlp->path); |
0a0bf5db | 192 | if (ctrlp->callback) |
6cf028ab | 193 | (ctrlp->callback) (ctrlp->callback_data, fd, errcode); |
0a0bf5db | 194 | xfree(ctrlp->path); |
195 | xfree(ctrlp); | |
196 | } | |
197 | ||
090089c4 | 198 | /* close a disk file. */ |
95d15928 | 199 | void |
b8d8561b | 200 | file_close(int fd) |
090089c4 | 201 | { |
76f87348 | 202 | fde *F = &fd_table[fd]; |
0e473d70 | 203 | if (fd < 0) { |
6cf028ab | 204 | debug(6, 0) ("file_close: FD less than zero: %d\n", fd); |
205 | return; | |
206 | } | |
76f87348 | 207 | assert(F->open); |
79a15e0a | 208 | if (EBIT_TEST(F->flags, FD_WRITE_DAEMON)) { |
209 | EBIT_SET(F->flags, FD_CLOSE_REQUEST); | |
95d15928 | 210 | return; |
fb247d78 | 211 | } |
79a15e0a | 212 | if (EBIT_TEST(F->flags, FD_WRITE_PENDING)) { |
213 | EBIT_SET(F->flags, FD_CLOSE_REQUEST); | |
95d15928 | 214 | return; |
215 | } | |
0a0bf5db | 216 | #if USE_ASYNC_IO |
95d15928 | 217 | aioClose(fd); |
0a0bf5db | 218 | #else |
95d15928 | 219 | close(fd); |
0a0bf5db | 220 | #endif |
6cf028ab | 221 | debug(6, 5) ("file_close: FD %d\n", fd); |
222 | fd_close(fd); | |
090089c4 | 223 | } |
224 | ||
090089c4 | 225 | |
226 | /* write handler */ | |
582b6456 | 227 | static void |
79d39a72 | 228 | diskHandleWrite(int fd, void *notused) |
090089c4 | 229 | { |
4a86108c | 230 | int len = 0; |
0a0bf5db | 231 | disk_ctrl_t *ctrlp; |
232 | dwrite_q *q = NULL; | |
233 | dwrite_q *wq = NULL; | |
76f87348 | 234 | fde *F = &fd_table[fd]; |
235 | struct _fde_disk *fdd = &F->disk; | |
de866d20 | 236 | if (!fdd->write_q) |
582b6456 | 237 | return; |
0a0bf5db | 238 | /* We need to combine subsequent write requests after the first */ |
d377699f | 239 | /* But only if we don't need to seek() in betwen them, ugh! */ |
de866d20 | 240 | if (fdd->write_q->next != NULL && fdd->write_q->next->next != NULL) { |
241 | len = 0; | |
242 | for (q = fdd->write_q->next; q != NULL; q = q->next) | |
d377699f | 243 | len += q->len - q->buf_offset; |
0a0bf5db | 244 | wq = xcalloc(1, sizeof(dwrite_q)); |
245 | wq->buf = xmalloc(len); | |
246 | wq->len = 0; | |
d377699f | 247 | wq->buf_offset = 0; |
0a0bf5db | 248 | wq->next = NULL; |
249 | wq->free = xfree; | |
250 | do { | |
de866d20 | 251 | q = fdd->write_q->next; |
d377699f | 252 | len = q->len - q->buf_offset; |
253 | xmemcpy(wq->buf + wq->len, q->buf + q->buf_offset, len); | |
0a0bf5db | 254 | wq->len += len; |
de866d20 | 255 | fdd->write_q->next = q->next; |
0a0bf5db | 256 | if (q->free) |
257 | (q->free) (q->buf); | |
258 | safe_free(q); | |
de866d20 | 259 | } while (fdd->write_q->next != NULL); |
260 | fdd->write_q_tail = wq; | |
261 | fdd->write_q->next = wq; | |
0a0bf5db | 262 | } |
263 | ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
264 | ctrlp->fd = fd; | |
8350fe9b | 265 | assert(fdd->write_q != NULL); |
d377699f | 266 | assert(fdd->write_q->len > fdd->write_q->buf_offset); |
0a0bf5db | 267 | #if USE_ASYNC_IO |
268 | aioWrite(fd, | |
d377699f | 269 | fdd->write_q->buf + fdd->write_q->buf_offset, |
270 | fdd->write_q->len - fdd->write_q->buf_offset, | |
0a0bf5db | 271 | diskHandleWriteComplete, |
cd1fb0eb | 272 | ctrlp); |
0a0bf5db | 273 | #else |
274 | len = write(fd, | |
d377699f | 275 | fdd->write_q->buf + fdd->write_q->buf_offset, |
276 | fdd->write_q->len - fdd->write_q->buf_offset); | |
582b6456 | 277 | diskHandleWriteComplete(ctrlp, len, errno); |
0a0bf5db | 278 | #endif |
279 | } | |
280 | ||
de866d20 | 281 | static void |
b69f7771 | 282 | diskHandleWriteComplete(void *data, int len, int errcode) |
0a0bf5db | 283 | { |
284 | disk_ctrl_t *ctrlp = data; | |
0a0bf5db | 285 | int fd = ctrlp->fd; |
76f87348 | 286 | fde *F = &fd_table[fd]; |
287 | struct _fde_disk *fdd = &F->disk; | |
de866d20 | 288 | dwrite_q *q = fdd->write_q; |
289 | int status = DISK_OK; | |
0a0bf5db | 290 | errno = errcode; |
6cf028ab | 291 | |
0a0bf5db | 292 | safe_free(data); |
de866d20 | 293 | if (q == NULL) /* Someone aborted then write completed */ |
294 | return; | |
6cf028ab | 295 | |
0e473d70 | 296 | if (len == -2 && errcode == -2) { /* Write cancelled - cleanup */ |
6cf028ab | 297 | do { |
298 | fdd->write_q = q->next; | |
299 | if (q->free) | |
300 | (q->free) (q->buf); | |
301 | safe_free(q); | |
302 | } while ((q = fdd->write_q)); | |
303 | return; | |
304 | } | |
6cf028ab | 305 | fd_bytes(fd, len, FD_WRITE); |
0a0bf5db | 306 | if (len < 0) { |
b224ea98 | 307 | if (!ignoreErrno(errno)) { |
de866d20 | 308 | status = errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR; |
a3d5953d | 309 | debug(50, 1) ("diskHandleWrite: FD %d: disk write error: %s\n", |
0c77d853 | 310 | fd, xstrerror()); |
6cf028ab | 311 | if (fdd->wrt_handle == NULL || status != DISK_NO_SPACE_LEFT) { |
de866d20 | 312 | /* FLUSH PENDING BUFFERS */ |
313 | do { | |
314 | fdd->write_q = q->next; | |
315 | if (q->free) | |
316 | (q->free) (q->buf); | |
317 | safe_free(q); | |
318 | } while ((q = fdd->write_q)); | |
090089c4 | 319 | } |
0c77d853 | 320 | } |
de866d20 | 321 | len = 0; |
0a0bf5db | 322 | } |
8350fe9b | 323 | if (q != NULL) { |
324 | /* q might become NULL from write failure above */ | |
d377699f | 325 | q->buf_offset += len; |
6cf028ab | 326 | if (q->buf_offset > q->len) |
327 | debug(50, 1) ("diskHandleWriteComplete: q->buf_offset > q->len (%p,%d, %d, %d FD %d)\n", | |
328 | q, q->buf_offset, q->len, len, fd); | |
d377699f | 329 | assert(q->buf_offset <= q->len); |
330 | if (q->buf_offset == q->len) { | |
56878878 | 331 | /* complete write */ |
332 | fdd->write_q = q->next; | |
333 | if (q->free) | |
334 | (q->free) (q->buf); | |
335 | safe_free(q); | |
336 | } | |
090089c4 | 337 | } |
de866d20 | 338 | if (fdd->write_q == NULL) { |
339 | /* no more data */ | |
340 | fdd->write_q_tail = NULL; | |
79a15e0a | 341 | EBIT_CLR(F->flags, FD_WRITE_PENDING); |
342 | EBIT_CLR(F->flags, FD_WRITE_DAEMON); | |
de866d20 | 343 | } else { |
0a0bf5db | 344 | /* another block is queued */ |
de866d20 | 345 | commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); |
79a15e0a | 346 | EBIT_SET(F->flags, FD_WRITE_DAEMON); |
4a86108c | 347 | } |
de866d20 | 348 | if (fdd->wrt_handle) |
d89d1fb6 | 349 | fdd->wrt_handle(fd, status, len, fdd->wrt_handle_data); |
79a15e0a | 350 | if (EBIT_TEST(F->flags, FD_CLOSE_REQUEST)) |
b59c7120 | 351 | file_close(fd); |
090089c4 | 352 | } |
353 | ||
354 | ||
090089c4 | 355 | /* write block to a file */ |
356 | /* write back queue. Only one writer at a time. */ | |
357 | /* call a handle when writing is complete. */ | |
b8d8561b | 358 | int |
3ebcfaa1 | 359 | file_write(int fd, |
d377699f | 360 | off_t file_offset, |
684c2720 | 361 | char *ptr_to_buf, |
362 | int len, | |
d89d1fb6 | 363 | DWCB handle, |
684c2720 | 364 | void *handle_data, |
9e4ad609 | 365 | FREE * free_func) |
090089c4 | 366 | { |
c6ac7aae | 367 | dwrite_q *wq = NULL; |
48cc3fcf | 368 | fde *F = &fd_table[fd]; |
369 | assert(fd >= 0); | |
370 | assert(F->open); | |
090089c4 | 371 | /* if we got here. Caller is eligible to write. */ |
30a4f2a8 | 372 | wq = xcalloc(1, sizeof(dwrite_q)); |
d377699f | 373 | wq->file_offset = file_offset; |
090089c4 | 374 | wq->buf = ptr_to_buf; |
090089c4 | 375 | wq->len = len; |
d377699f | 376 | wq->buf_offset = 0; |
090089c4 | 377 | wq->next = NULL; |
86ee2017 | 378 | wq->free = free_func; |
76f87348 | 379 | F->disk.wrt_handle = handle; |
380 | F->disk.wrt_handle_data = handle_data; | |
090089c4 | 381 | /* add to queue */ |
79a15e0a | 382 | EBIT_SET(F->flags, FD_WRITE_PENDING); |
48cc3fcf | 383 | if (F->disk.write_q == NULL) { |
090089c4 | 384 | /* empty queue */ |
76f87348 | 385 | F->disk.write_q = F->disk.write_q_tail = wq; |
090089c4 | 386 | } else { |
76f87348 | 387 | F->disk.write_q_tail->next = wq; |
388 | F->disk.write_q_tail = wq; | |
090089c4 | 389 | } |
79a15e0a | 390 | if (!EBIT_TEST(F->flags, FD_WRITE_DAEMON)) { |
0a0bf5db | 391 | #if USE_ASYNC_IO |
95d15928 | 392 | diskHandleWrite(fd, NULL); |
0a0bf5db | 393 | #else |
95d15928 | 394 | commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); |
0a0bf5db | 395 | #endif |
79a15e0a | 396 | EBIT_SET(F->flags, FD_WRITE_DAEMON); |
429fdbec | 397 | } |
090089c4 | 398 | return DISK_OK; |
399 | } | |
400 | ||
401 | ||
402 | ||
403 | /* Read from FD */ | |
582b6456 | 404 | static void |
405 | diskHandleRead(int fd, void *data) | |
090089c4 | 406 | { |
582b6456 | 407 | dread_ctrl *ctrl_dat = data; |
606bd3b5 | 408 | #if !USE_ASYNC_IO |
edd2eb63 | 409 | fde *F = &fd_table[fd]; |
090089c4 | 410 | int len; |
606bd3b5 | 411 | #endif |
412 | disk_ctrl_t *ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
0a0bf5db | 413 | ctrlp->fd = fd; |
cd1fb0eb | 414 | ctrlp->data = ctrl_dat; |
0a0bf5db | 415 | #if USE_ASYNC_IO |
416 | aioRead(fd, | |
711982d8 | 417 | ctrl_dat->buf, |
418 | ctrl_dat->req_len, | |
0a0bf5db | 419 | diskHandleReadComplete, |
cd1fb0eb | 420 | ctrlp); |
0a0bf5db | 421 | #else |
711982d8 | 422 | if (F->disk.offset != ctrl_dat->offset) { |
f2b30883 | 423 | debug(6, 3) ("diskHandleRead: FD %d seeking to offset %d\n", |
343c257b | 424 | fd, (int) ctrl_dat->offset); |
711982d8 | 425 | lseek(fd, ctrl_dat->offset, SEEK_SET); /* XXX ignore return? */ |
556c33d5 | 426 | F->disk.offset = ctrl_dat->offset; |
711982d8 | 427 | } |
428 | len = read(fd, ctrl_dat->buf, ctrl_dat->req_len); | |
429 | F->disk.offset += len; | |
582b6456 | 430 | diskHandleReadComplete(ctrlp, len, errno); |
090089c4 | 431 | #endif |
0a0bf5db | 432 | } |
433 | ||
de866d20 | 434 | static void |
4f92c80c | 435 | diskHandleReadComplete(void *data, int len, int errcode) |
0a0bf5db | 436 | { |
437 | disk_ctrl_t *ctrlp = data; | |
438 | dread_ctrl *ctrl_dat = ctrlp->data; | |
439 | int fd = ctrlp->fd; | |
901a2a3c | 440 | int rc = DISK_OK; |
0a0bf5db | 441 | errno = errcode; |
6cf028ab | 442 | |
0a0bf5db | 443 | xfree(data); |
6cf028ab | 444 | |
0e473d70 | 445 | if (len == -2 && errcode == -2) { /* Read cancelled - cleanup */ |
6cf028ab | 446 | cbdataUnlock(ctrl_dat->client_data); |
447 | safe_free(ctrl_dat); | |
448 | return; | |
449 | } | |
4f92c80c | 450 | fd_bytes(fd, len, FD_READ); |
0a0bf5db | 451 | if (len < 0) { |
b224ea98 | 452 | if (ignoreErrno(errno)) { |
901a2a3c | 453 | commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0); |
de866d20 | 454 | return; |
0a0bf5db | 455 | } |
901a2a3c | 456 | debug(50, 1) ("diskHandleRead: FD %d: %s\n", fd, xstrerror()); |
457 | len = 0; | |
458 | rc = DISK_ERROR; | |
090089c4 | 459 | } else if (len == 0) { |
901a2a3c | 460 | rc = DISK_EOF; |
090089c4 | 461 | } |
901a2a3c | 462 | if (cbdataValid(ctrl_dat->client_data)) |
5d86029a | 463 | ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data); |
901a2a3c | 464 | cbdataUnlock(ctrl_dat->client_data); |
6a54c60e | 465 | safe_free(ctrl_dat); |
090089c4 | 466 | } |
467 | ||
468 | ||
469 | /* start read operation */ | |
470 | /* buffer must be allocated from the caller. | |
471 | * It must have at least req_len space in there. | |
472 | * call handler when a reading is complete. */ | |
b8d8561b | 473 | int |
d377699f | 474 | file_read(int fd, char *buf, int req_len, off_t offset, DRCB * handler, void *client_data) |
090089c4 | 475 | { |
476 | dread_ctrl *ctrl_dat; | |
711982d8 | 477 | assert(fd >= 0); |
30a4f2a8 | 478 | ctrl_dat = xcalloc(1, sizeof(dread_ctrl)); |
090089c4 | 479 | ctrl_dat->fd = fd; |
480 | ctrl_dat->offset = offset; | |
481 | ctrl_dat->req_len = req_len; | |
482 | ctrl_dat->buf = buf; | |
090089c4 | 483 | ctrl_dat->end_of_file = 0; |
484 | ctrl_dat->handler = handler; | |
485 | ctrl_dat->client_data = client_data; | |
901a2a3c | 486 | cbdataLock(client_data); |
0a0bf5db | 487 | #if USE_ASYNC_IO |
488 | diskHandleRead(fd, ctrl_dat); | |
489 | #else | |
b177367b | 490 | commSetSelect(fd, |
234967c9 | 491 | COMM_SELECT_READ, |
cd1fb0eb | 492 | diskHandleRead, |
493 | ctrl_dat, | |
b177367b | 494 | 0); |
0a0bf5db | 495 | #endif |
090089c4 | 496 | return DISK_OK; |
497 | } | |
498 | ||
b8d8561b | 499 | int |
500 | diskWriteIsComplete(int fd) | |
b59c7120 | 501 | { |
95d15928 | 502 | return fd_table[fd].disk.write_q ? 0 : 1; |
0a21bd84 | 503 | } |