]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 79 Disk IO Routines */
13 #include "DiskIO/IORequestor.h"
14 #include "DiskIO/ReadRequest.h"
15 #include "DiskIO/WriteRequest.h"
16 #include "DiskThreadsDiskFile.h"
20 #include "StatCounters.h"
25 /* === PUBLIC =========================================================== */
27 CBDATA_CLASS_INIT(DiskThreadsDiskFile
);
29 DiskThreadsDiskFile::DiskThreadsDiskFile(char const *aPath
, DiskThreadsIOStrategy
*anIO
):fd(-1), errorOccured (false), IO(anIO
),
33 debugs(79, 3, "UFSFile::UFSFile: " << aPath
);
34 path_
= xstrdup(aPath
);
37 DiskThreadsDiskFile::~DiskThreadsDiskFile()
44 DiskThreadsDiskFile::open(int flags
, mode_t mode
, RefCount
<IORequestor
> callback
)
46 ++statCounter
.syscalls
.disk
.opens
;
49 fd
= file_open(path_
, flags
);
52 debugs(79, 3, "DiskThreadsDiskFile::open: got failure (" << errno
<< ")");
60 ioRequestor
= callback
;
66 aioOpen(path_
, flags
, mode
, DiskThreadsDiskFile::OpenDone
, this);
70 openDone(fd
, NULL
, fd
, 0);
76 DiskThreadsDiskFile::read(ReadRequest
* request
)
78 debugs(79, 3, "DiskThreadsDiskFile::read: " << this << ", size " << request
->len
);
80 assert (ioRequestor
.getRaw());
81 ++statCounter
.syscalls
.disk
.reads
;
85 aioRead(fd
, request
->offset
, request
->len
, ReadDone
, new IoResult
<ReadRequest
>(this, request
));
88 file_read(fd
, request
->buf
, request
->len
, request
->offset
, ReadDone
, new IoResult
<ReadRequest
>(this, request
));
93 DiskThreadsDiskFile::create(int flags
, mode_t mode
, RefCount
<IORequestor
> callback
)
95 ++statCounter
.syscalls
.disk
.opens
;
98 int fd
= file_open(path_
, flags
);
101 debugs(79, 3, "DiskThreadsDiskFile::create: got failure (" << errno
<< ")");
109 ioRequestor
= callback
;
115 aioOpen(path_
, flags
, mode
, DiskThreadsDiskFile::OpenDone
, this);
119 openDone (fd
, NULL
, fd
, 0);
125 DiskThreadsDiskFile::error() const
131 DiskThreadsDiskFile::OpenDone(int fd
, void *cbdata
, const char *buf
, int aio_return
, int aio_errno
)
133 DiskThreadsDiskFile
*myFile
= static_cast<DiskThreadsDiskFile
*>(cbdata
);
134 myFile
->openDone (fd
, buf
, aio_return
, aio_errno
);
138 DiskThreadsDiskFile::openDone(int, const char *, int anFD
, int errflag
)
140 debugs(79, 3, "DiskThreadsDiskFile::openDone: FD " << anFD
<< ", errflag " << errflag
);
145 if (errflag
|| fd
< 0) {
147 debugs(79, DBG_CRITICAL
, "DiskThreadsDiskFile::openDone: " << xstrerror());
148 debugs(79, DBG_IMPORTANT
, "\t" << path_
);
151 ++store_open_disk_fd
;
152 commSetCloseOnExec(fd
);
153 fd_open(fd
, FD_FILE
, path_
);
156 IORequestor::Pointer t
= ioRequestor
;
158 t
->ioCompletedNotification();
160 debugs(79, 3, "DiskThreadsDiskFile::openDone: exiting");
163 void DiskThreadsDiskFile::doClose()
166 ++statCounter
.syscalls
.disk
.closes
;
177 --store_open_disk_fd
;
183 DiskThreadsDiskFile::close()
185 debugs(79, 3, "DiskThreadsDiskFile::close: " << this << " closing for " << ioRequestor
.getRaw());
187 if (!ioInProgress()) {
189 assert (ioRequestor
!= NULL
);
190 ioRequestor
->closeCompleted();
193 debugs(79, DBG_CRITICAL
, HERE
<< "DiskThreadsDiskFile::close: " <<
194 "did NOT close because ioInProgress() is true. now what?");
199 DiskThreadsDiskFile::canRead() const
201 debugs(79, 3, "DiskThreadsDiskFile::canRead: fd is " << fd
);
206 DiskThreadsDiskFile::write(WriteRequest
* writeRequest
)
208 debugs(79, 3, "DiskThreadsDiskFile::write: FD " << fd
);
209 ++statCounter
.syscalls
.disk
.writes
;
213 aioWrite(fd
, writeRequest
->offset
, (char *)writeRequest
->buf
, writeRequest
->len
, WriteDone
, new IoResult
<WriteRequest
>(this, writeRequest
),
214 writeRequest
->free_func
);
217 file_write(fd
, writeRequest
->offset
, (char *)writeRequest
->buf
, writeRequest
->len
, WriteDone
, new IoResult
<WriteRequest
>(this, writeRequest
),
218 writeRequest
->free_func
);
223 DiskThreadsDiskFile::canWrite() const
229 DiskThreadsDiskFile::ioInProgress() const
231 return inProgressIOs
> 0;
234 /* === STATIC =========================================================== */
238 DiskThreadsDiskFile::ReadDone(int fd
, void *my_data
, const char *buf
, int len
, int errflag
)
241 DiskThreadsDiskFile::ReadDone(int fd
, const char *buf
, int len
, int errflag
, void *my_data
)
244 IoResult
<ReadRequest
> * result
= static_cast<IoResult
<ReadRequest
> *>(my_data
);
246 result
->file
->readDone(fd
, buf
, len
, errflag
, result
->request
);
251 DiskThreadsDiskFile::readDone(int rvfd
, const char *buf
, int len
, int errflag
, RefCount
<ReadRequest
> request
)
253 debugs(79, 3, "DiskThreadsDiskFile::readDone: FD " << rvfd
);
259 debugs(79, 3, "DiskThreadsDiskFile::readDone: got failure (" << errflag
<< ")");
262 rlen
= (ssize_t
) len
;
266 /* translate errflag from errno to Squid disk error */
270 errflag
= DISK_ERROR
;
276 if (errflag
== DISK_EOF
)
277 errflag
= DISK_OK
; /* EOF is signalled by len == 0, not errors... */
283 ioRequestor
->readCompleted(buf
, rlen
, errflag
, request
);
287 DiskThreadsDiskFile::
289 WriteDone(int fd
, void *my_data
, const char *buf
, int len
, int errflag
)
291 WriteDone(int fd
, int errflag
, size_t len
, void *my_data
)
294 IoResult
<WriteRequest
> * result
= static_cast<IoResult
<WriteRequest
> *>(my_data
);
296 result
->file
->writeDone(fd
, errflag
, len
, result
->request
);
301 DiskThreadsDiskFile::writeDone(int rvfd
, int errflag
, size_t len
, RefCount
<WriteRequest
> request
)
304 static int loop_detect
= 0;
307 /* Translate from errno to Squid disk error */
310 errflag
= errflag
== ENOSPC
? DISK_NO_SPACE_LEFT
: DISK_ERROR
;
316 debugs(79, 3, "DiskThreadsDiskFile::writeDone: FD " << fd
<< ", len " << len
<< ", err=" << errflag
);
319 assert(loop_detect
< 10);
323 ioRequestor
->writeCompleted(errflag
, len
, request
);
328 /** \cond AUTODOCS_IGNORE */
330 cbdata_type IoResult
<RT
>::CBDATA_IoResult
= CBDATA_UNKNOWN
;