#include <sys/ioctl.h>
#include <linux/fs.h>
#include <errno.h>
-#include <linux/kdev_t.h>
-#include <asm/unistd.h>
+#include <unistd.h>
#include <libaio.h>
#include "checkers.h"
ct->ptr = (unsigned char *) (((unsigned long)ct->buf + pgsize - 1) &
(~(pgsize - 1)));
- /* Sucessfully initialized, return the context. */
+ /* Successfully initialized, return the context. */
c->context = (void *) ct;
return 0;
if (ct->reset_flags) {
if ((flags = fcntl(c->fd, F_GETFL)) >= 0) {
+ int ret __attribute__ ((unused));
+
flags &= ~O_DIRECT;
/* No point in checking for errors */
- fcntl(c->fd, F_SETFL, flags);
+ ret = fcntl(c->fd, F_SETFL, flags);
}
}
free(ct);
}
+void libcheck_repair (struct checker * c)
+{
+ return;
+}
+
static int
-check_state(int fd, struct directio_context *ct, int sync)
+check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
{
struct timespec timeout = { .tv_nsec = 5 };
struct io_event event;
if (fstat(fd, &sb) == 0) {
LOG(4, "called for %x", (unsigned) sb.st_rdev);
}
- if (sync) {
+ if (sync > 0) {
LOG(4, "called in synchronous mode");
- timeout.tv_sec = ASYNC_TIMEOUT_SEC;
+ timeout.tv_sec = timeout_secs;
timeout.tv_nsec = 0;
}
if (r < 0 ) {
LOG(3, "async io getevents returned %li (errno=%s)", r,
strerror(errno));
+ ct->running = 0;
rc = PATH_UNCHECKED;
} else if (r < 1L) {
- if (ct->running > ASYNC_TIMEOUT_SEC || sync) {
+ if (ct->running > timeout_secs || sync) {
+ struct iocb *ios[1] = { &ct->io };
+
LOG(3, "abort check on timeout");
+ r = io_cancel(ct->ioctx, ios[0], &event);
+ /*
+ * Only reset ct->running if we really
+ * could abort the pending I/O
+ */
+ if (r)
+ LOG(3, "io_cancel error %i", errno);
+ else
+ ct->running = 0;
rc = PATH_DOWN;
} else {
LOG(3, "async io pending");
if (!ct)
return PATH_UNCHECKED;
- ret = check_state(c->fd, ct, c->sync);
+ ret = check_state(c->fd, ct, c->sync, c->timeout);
switch (ret)
{