]>
Commit | Line | Data |
---|---|---|
b224ea98 | 1 | |
30a4f2a8 | 2 | /* |
18b23dc1 | 3 | * $Id: disk.cc,v 1.103 1998/02/09 21:17:25 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; | |
af95908a | 181 | debug(50, 3) ("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 | } |
0a0bf5db | 212 | #if USE_ASYNC_IO |
95d15928 | 213 | aioClose(fd); |
0a0bf5db | 214 | #else |
95d15928 | 215 | close(fd); |
0a0bf5db | 216 | #endif |
6cf028ab | 217 | debug(6, 5) ("file_close: FD %d\n", fd); |
218 | fd_close(fd); | |
090089c4 | 219 | } |
220 | ||
090089c4 | 221 | |
222 | /* write handler */ | |
582b6456 | 223 | static void |
79d39a72 | 224 | diskHandleWrite(int fd, void *notused) |
090089c4 | 225 | { |
4a86108c | 226 | int len = 0; |
0a0bf5db | 227 | disk_ctrl_t *ctrlp; |
228 | dwrite_q *q = NULL; | |
229 | dwrite_q *wq = NULL; | |
76f87348 | 230 | fde *F = &fd_table[fd]; |
231 | struct _fde_disk *fdd = &F->disk; | |
de866d20 | 232 | if (!fdd->write_q) |
582b6456 | 233 | return; |
0a0bf5db | 234 | /* We need to combine subsequent write requests after the first */ |
d377699f | 235 | /* But only if we don't need to seek() in betwen them, ugh! */ |
de866d20 | 236 | if (fdd->write_q->next != NULL && fdd->write_q->next->next != NULL) { |
237 | len = 0; | |
238 | for (q = fdd->write_q->next; q != NULL; q = q->next) | |
d377699f | 239 | len += q->len - q->buf_offset; |
0a0bf5db | 240 | wq = xcalloc(1, sizeof(dwrite_q)); |
241 | wq->buf = xmalloc(len); | |
242 | wq->len = 0; | |
d377699f | 243 | wq->buf_offset = 0; |
0a0bf5db | 244 | wq->next = NULL; |
ed7f0b6a | 245 | wq->free_func = xfree; |
0a0bf5db | 246 | do { |
de866d20 | 247 | q = fdd->write_q->next; |
d377699f | 248 | len = q->len - q->buf_offset; |
249 | xmemcpy(wq->buf + wq->len, q->buf + q->buf_offset, len); | |
0a0bf5db | 250 | wq->len += len; |
de866d20 | 251 | fdd->write_q->next = q->next; |
ed7f0b6a | 252 | if (q->free_func) |
253 | (q->free_func) (q->buf); | |
0a0bf5db | 254 | safe_free(q); |
de866d20 | 255 | } while (fdd->write_q->next != NULL); |
256 | fdd->write_q_tail = wq; | |
257 | fdd->write_q->next = wq; | |
0a0bf5db | 258 | } |
259 | ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
260 | ctrlp->fd = fd; | |
8350fe9b | 261 | assert(fdd->write_q != NULL); |
d377699f | 262 | assert(fdd->write_q->len > fdd->write_q->buf_offset); |
0a0bf5db | 263 | #if USE_ASYNC_IO |
264 | aioWrite(fd, | |
d377699f | 265 | fdd->write_q->buf + fdd->write_q->buf_offset, |
266 | fdd->write_q->len - fdd->write_q->buf_offset, | |
0a0bf5db | 267 | diskHandleWriteComplete, |
cd1fb0eb | 268 | ctrlp); |
0a0bf5db | 269 | #else |
270 | len = write(fd, | |
d377699f | 271 | fdd->write_q->buf + fdd->write_q->buf_offset, |
272 | fdd->write_q->len - fdd->write_q->buf_offset); | |
582b6456 | 273 | diskHandleWriteComplete(ctrlp, len, errno); |
0a0bf5db | 274 | #endif |
275 | } | |
276 | ||
de866d20 | 277 | static void |
b69f7771 | 278 | diskHandleWriteComplete(void *data, int len, int errcode) |
0a0bf5db | 279 | { |
280 | disk_ctrl_t *ctrlp = data; | |
0a0bf5db | 281 | int fd = ctrlp->fd; |
76f87348 | 282 | fde *F = &fd_table[fd]; |
283 | struct _fde_disk *fdd = &F->disk; | |
de866d20 | 284 | dwrite_q *q = fdd->write_q; |
285 | int status = DISK_OK; | |
0a0bf5db | 286 | errno = errcode; |
6cf028ab | 287 | |
0a0bf5db | 288 | safe_free(data); |
de866d20 | 289 | if (q == NULL) /* Someone aborted then write completed */ |
290 | return; | |
6cf028ab | 291 | |
0e473d70 | 292 | if (len == -2 && errcode == -2) { /* Write cancelled - cleanup */ |
6cf028ab | 293 | do { |
294 | fdd->write_q = q->next; | |
ed7f0b6a | 295 | if (q->free_func) |
296 | (q->free_func) (q->buf); | |
6cf028ab | 297 | safe_free(q); |
298 | } while ((q = fdd->write_q)); | |
299 | return; | |
300 | } | |
6cf028ab | 301 | fd_bytes(fd, len, FD_WRITE); |
0a0bf5db | 302 | if (len < 0) { |
b224ea98 | 303 | if (!ignoreErrno(errno)) { |
de866d20 | 304 | status = errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR; |
a3d5953d | 305 | debug(50, 1) ("diskHandleWrite: FD %d: disk write error: %s\n", |
0c77d853 | 306 | fd, xstrerror()); |
6cf028ab | 307 | if (fdd->wrt_handle == NULL || status != DISK_NO_SPACE_LEFT) { |
de866d20 | 308 | /* FLUSH PENDING BUFFERS */ |
309 | do { | |
310 | fdd->write_q = q->next; | |
ed7f0b6a | 311 | if (q->free_func) |
312 | (q->free_func) (q->buf); | |
de866d20 | 313 | safe_free(q); |
314 | } while ((q = fdd->write_q)); | |
090089c4 | 315 | } |
0c77d853 | 316 | } |
de866d20 | 317 | len = 0; |
0a0bf5db | 318 | } |
8350fe9b | 319 | if (q != NULL) { |
320 | /* q might become NULL from write failure above */ | |
d377699f | 321 | q->buf_offset += len; |
6cf028ab | 322 | if (q->buf_offset > q->len) |
323 | debug(50, 1) ("diskHandleWriteComplete: q->buf_offset > q->len (%p,%d, %d, %d FD %d)\n", | |
324 | q, q->buf_offset, q->len, len, fd); | |
d377699f | 325 | assert(q->buf_offset <= q->len); |
326 | if (q->buf_offset == q->len) { | |
56878878 | 327 | /* complete write */ |
328 | fdd->write_q = q->next; | |
ed7f0b6a | 329 | if (q->free_func) |
330 | (q->free_func) (q->buf); | |
56878878 | 331 | safe_free(q); |
332 | } | |
090089c4 | 333 | } |
de866d20 | 334 | if (fdd->write_q == NULL) { |
335 | /* no more data */ | |
336 | fdd->write_q_tail = NULL; | |
79a15e0a | 337 | EBIT_CLR(F->flags, FD_WRITE_DAEMON); |
de866d20 | 338 | } else { |
0a0bf5db | 339 | /* another block is queued */ |
de866d20 | 340 | commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); |
79a15e0a | 341 | EBIT_SET(F->flags, FD_WRITE_DAEMON); |
4a86108c | 342 | } |
de866d20 | 343 | if (fdd->wrt_handle) |
d89d1fb6 | 344 | fdd->wrt_handle(fd, status, len, fdd->wrt_handle_data); |
79a15e0a | 345 | if (EBIT_TEST(F->flags, FD_CLOSE_REQUEST)) |
b59c7120 | 346 | file_close(fd); |
090089c4 | 347 | } |
348 | ||
349 | ||
090089c4 | 350 | /* write block to a file */ |
351 | /* write back queue. Only one writer at a time. */ | |
352 | /* call a handle when writing is complete. */ | |
e3ef2b09 | 353 | void |
3ebcfaa1 | 354 | file_write(int fd, |
d377699f | 355 | off_t file_offset, |
5830cdb3 | 356 | void *ptr_to_buf, |
684c2720 | 357 | int len, |
d89d1fb6 | 358 | DWCB handle, |
684c2720 | 359 | void *handle_data, |
9e4ad609 | 360 | FREE * free_func) |
090089c4 | 361 | { |
c6ac7aae | 362 | dwrite_q *wq = NULL; |
48cc3fcf | 363 | fde *F = &fd_table[fd]; |
364 | assert(fd >= 0); | |
365 | assert(F->open); | |
090089c4 | 366 | /* if we got here. Caller is eligible to write. */ |
30a4f2a8 | 367 | wq = xcalloc(1, sizeof(dwrite_q)); |
d377699f | 368 | wq->file_offset = file_offset; |
090089c4 | 369 | wq->buf = ptr_to_buf; |
090089c4 | 370 | wq->len = len; |
d377699f | 371 | wq->buf_offset = 0; |
090089c4 | 372 | wq->next = NULL; |
ed7f0b6a | 373 | wq->free_func = free_func; |
76f87348 | 374 | F->disk.wrt_handle = handle; |
375 | F->disk.wrt_handle_data = handle_data; | |
090089c4 | 376 | /* add to queue */ |
48cc3fcf | 377 | if (F->disk.write_q == NULL) { |
090089c4 | 378 | /* empty queue */ |
76f87348 | 379 | F->disk.write_q = F->disk.write_q_tail = wq; |
090089c4 | 380 | } else { |
76f87348 | 381 | F->disk.write_q_tail->next = wq; |
382 | F->disk.write_q_tail = wq; | |
090089c4 | 383 | } |
79a15e0a | 384 | if (!EBIT_TEST(F->flags, FD_WRITE_DAEMON)) { |
0a0bf5db | 385 | #if USE_ASYNC_IO |
95d15928 | 386 | diskHandleWrite(fd, NULL); |
0a0bf5db | 387 | #else |
95d15928 | 388 | commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); |
0a0bf5db | 389 | #endif |
79a15e0a | 390 | EBIT_SET(F->flags, FD_WRITE_DAEMON); |
429fdbec | 391 | } |
090089c4 | 392 | } |
393 | ||
394 | ||
395 | ||
396 | /* Read from FD */ | |
582b6456 | 397 | static void |
398 | diskHandleRead(int fd, void *data) | |
090089c4 | 399 | { |
582b6456 | 400 | dread_ctrl *ctrl_dat = data; |
606bd3b5 | 401 | #if !USE_ASYNC_IO |
edd2eb63 | 402 | fde *F = &fd_table[fd]; |
090089c4 | 403 | int len; |
606bd3b5 | 404 | #endif |
405 | disk_ctrl_t *ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
0a0bf5db | 406 | ctrlp->fd = fd; |
cd1fb0eb | 407 | ctrlp->data = ctrl_dat; |
0a0bf5db | 408 | #if USE_ASYNC_IO |
409 | aioRead(fd, | |
711982d8 | 410 | ctrl_dat->buf, |
411 | ctrl_dat->req_len, | |
0a0bf5db | 412 | diskHandleReadComplete, |
cd1fb0eb | 413 | ctrlp); |
0a0bf5db | 414 | #else |
711982d8 | 415 | if (F->disk.offset != ctrl_dat->offset) { |
f2b30883 | 416 | debug(6, 3) ("diskHandleRead: FD %d seeking to offset %d\n", |
343c257b | 417 | fd, (int) ctrl_dat->offset); |
711982d8 | 418 | lseek(fd, ctrl_dat->offset, SEEK_SET); /* XXX ignore return? */ |
556c33d5 | 419 | F->disk.offset = ctrl_dat->offset; |
711982d8 | 420 | } |
421 | len = read(fd, ctrl_dat->buf, ctrl_dat->req_len); | |
422 | F->disk.offset += len; | |
582b6456 | 423 | diskHandleReadComplete(ctrlp, len, errno); |
090089c4 | 424 | #endif |
0a0bf5db | 425 | } |
426 | ||
de866d20 | 427 | static void |
4f92c80c | 428 | diskHandleReadComplete(void *data, int len, int errcode) |
0a0bf5db | 429 | { |
430 | disk_ctrl_t *ctrlp = data; | |
431 | dread_ctrl *ctrl_dat = ctrlp->data; | |
432 | int fd = ctrlp->fd; | |
901a2a3c | 433 | int rc = DISK_OK; |
0a0bf5db | 434 | errno = errcode; |
6cf028ab | 435 | |
0a0bf5db | 436 | xfree(data); |
6cf028ab | 437 | |
0e473d70 | 438 | if (len == -2 && errcode == -2) { /* Read cancelled - cleanup */ |
6cf028ab | 439 | cbdataUnlock(ctrl_dat->client_data); |
440 | safe_free(ctrl_dat); | |
441 | return; | |
442 | } | |
4f92c80c | 443 | fd_bytes(fd, len, FD_READ); |
0a0bf5db | 444 | if (len < 0) { |
b224ea98 | 445 | if (ignoreErrno(errno)) { |
901a2a3c | 446 | commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0); |
de866d20 | 447 | return; |
0a0bf5db | 448 | } |
901a2a3c | 449 | debug(50, 1) ("diskHandleRead: FD %d: %s\n", fd, xstrerror()); |
450 | len = 0; | |
451 | rc = DISK_ERROR; | |
090089c4 | 452 | } else if (len == 0) { |
901a2a3c | 453 | rc = DISK_EOF; |
090089c4 | 454 | } |
901a2a3c | 455 | if (cbdataValid(ctrl_dat->client_data)) |
5d86029a | 456 | ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data); |
901a2a3c | 457 | cbdataUnlock(ctrl_dat->client_data); |
6a54c60e | 458 | safe_free(ctrl_dat); |
090089c4 | 459 | } |
460 | ||
461 | ||
462 | /* start read operation */ | |
463 | /* buffer must be allocated from the caller. | |
464 | * It must have at least req_len space in there. | |
465 | * call handler when a reading is complete. */ | |
b8d8561b | 466 | int |
d377699f | 467 | file_read(int fd, char *buf, int req_len, off_t offset, DRCB * handler, void *client_data) |
090089c4 | 468 | { |
469 | dread_ctrl *ctrl_dat; | |
711982d8 | 470 | assert(fd >= 0); |
30a4f2a8 | 471 | ctrl_dat = xcalloc(1, sizeof(dread_ctrl)); |
090089c4 | 472 | ctrl_dat->fd = fd; |
473 | ctrl_dat->offset = offset; | |
474 | ctrl_dat->req_len = req_len; | |
475 | ctrl_dat->buf = buf; | |
090089c4 | 476 | ctrl_dat->end_of_file = 0; |
477 | ctrl_dat->handler = handler; | |
478 | ctrl_dat->client_data = client_data; | |
901a2a3c | 479 | cbdataLock(client_data); |
0a0bf5db | 480 | #if USE_ASYNC_IO |
481 | diskHandleRead(fd, ctrl_dat); | |
482 | #else | |
b177367b | 483 | commSetSelect(fd, |
234967c9 | 484 | COMM_SELECT_READ, |
cd1fb0eb | 485 | diskHandleRead, |
486 | ctrl_dat, | |
b177367b | 487 | 0); |
0a0bf5db | 488 | #endif |
090089c4 | 489 | return DISK_OK; |
490 | } | |
491 | ||
b8d8561b | 492 | int |
493 | diskWriteIsComplete(int fd) | |
b59c7120 | 494 | { |
95d15928 | 495 | return fd_table[fd].disk.write_q ? 0 : 1; |
0a21bd84 | 496 | } |