]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
a0855499f4083fcb3864244c4b288e7afa73dd59
2 * Copyright (C) 1996-2016 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 */
12 #include "DiskIO/IORequestor.h"
13 #include "DiskIO/ReadRequest.h"
14 #include "DiskIO/WriteRequest.h"
15 #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) {
146 debugs(79, DBG_CRITICAL
, MYNAME
<< xstrerr(errflag
));
147 debugs(79, DBG_IMPORTANT
, "\t" << path_
);
150 ++store_open_disk_fd
;
151 commSetCloseOnExec(fd
);
152 fd_open(fd
, FD_FILE
, path_
);
155 IORequestor::Pointer t
= ioRequestor
;
157 t
->ioCompletedNotification();
159 debugs(79, 3, "DiskThreadsDiskFile::openDone: exiting");
162 void DiskThreadsDiskFile::doClose()
165 ++statCounter
.syscalls
.disk
.closes
;
176 --store_open_disk_fd
;
182 DiskThreadsDiskFile::close()
184 debugs(79, 3, "DiskThreadsDiskFile::close: " << this << " closing for " << ioRequestor
.getRaw());
186 if (!ioInProgress()) {
188 assert (ioRequestor
!= NULL
);
189 ioRequestor
->closeCompleted();
192 debugs(79, DBG_CRITICAL
, HERE
<< "DiskThreadsDiskFile::close: " <<
193 "did NOT close because ioInProgress() is true. now what?");
198 DiskThreadsDiskFile::canRead() const
200 debugs(79, 3, "DiskThreadsDiskFile::canRead: fd is " << fd
);
205 DiskThreadsDiskFile::write(WriteRequest
* writeRequest
)
207 debugs(79, 3, "DiskThreadsDiskFile::write: FD " << fd
);
208 ++statCounter
.syscalls
.disk
.writes
;
212 aioWrite(fd
, writeRequest
->offset
, (char *)writeRequest
->buf
, writeRequest
->len
, WriteDone
, new IoResult
<WriteRequest
>(this, writeRequest
),
213 writeRequest
->free_func
);
216 file_write(fd
, writeRequest
->offset
, (char *)writeRequest
->buf
, writeRequest
->len
, WriteDone
, new IoResult
<WriteRequest
>(this, writeRequest
),
217 writeRequest
->free_func
);
222 DiskThreadsDiskFile::canWrite() const
228 DiskThreadsDiskFile::ioInProgress() const
230 return inProgressIOs
> 0;
233 /* === STATIC =========================================================== */
237 DiskThreadsDiskFile::ReadDone(int fd
, void *my_data
, const char *buf
, int len
, int errflag
)
240 DiskThreadsDiskFile::ReadDone(int fd
, const char *buf
, int len
, int errflag
, void *my_data
)
243 IoResult
<ReadRequest
> * result
= static_cast<IoResult
<ReadRequest
> *>(my_data
);
245 result
->file
->readDone(fd
, buf
, len
, errflag
, result
->request
);
250 DiskThreadsDiskFile::readDone(int rvfd
, const char *buf
, int len
, int errflag
, RefCount
<ReadRequest
> request
)
252 debugs(79, 3, "DiskThreadsDiskFile::readDone: FD " << rvfd
);
258 debugs(79, 3, "DiskThreadsDiskFile::readDone: got failure (" << errflag
<< ")");
261 rlen
= (ssize_t
) len
;
265 /* translate errflag from errno to Squid disk error */
269 errflag
= DISK_ERROR
;
275 if (errflag
== DISK_EOF
)
276 errflag
= DISK_OK
; /* EOF is signalled by len == 0, not errors... */
282 ioRequestor
->readCompleted(buf
, rlen
, errflag
, request
);
286 DiskThreadsDiskFile::
288 WriteDone(int fd
, void *my_data
, const char *buf
, int len
, int errflag
)
290 WriteDone(int fd
, int errflag
, size_t len
, void *my_data
)
293 IoResult
<WriteRequest
> * result
= static_cast<IoResult
<WriteRequest
> *>(my_data
);
295 result
->file
->writeDone(fd
, errflag
, len
, result
->request
);
300 DiskThreadsDiskFile::writeDone(int rvfd
, int errflag
, size_t len
, RefCount
<WriteRequest
> request
)
303 static int loop_detect
= 0;
306 /* Translate from errno to Squid disk error */
309 errflag
= errflag
== ENOSPC
? DISK_NO_SPACE_LEFT
: DISK_ERROR
;
315 debugs(79, 3, "DiskThreadsDiskFile::writeDone: FD " << fd
<< ", len " << len
<< ", err=" << errflag
);
318 assert(loop_detect
< 10);
322 ioRequestor
->writeCompleted(errflag
, len
, request
);
327 /** \cond AUTODOCS_IGNORE */
329 cbdata_type IoResult
<RT
>::CBDATA_IoResult
= CBDATA_UNKNOWN
;