Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libmultipath: io_err_stat: don't free aio memory before completion #16

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions libmultipath/checkers/directio.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ get_events(struct aio_group *aio_grp, struct timespec *timeout)
for (i = 0; i < nr; i++) {
struct async_req *req = container_of(events[i].obj, struct async_req, io);

LOG(3, "io finished %lu/%lu", events[i].res,
LOG(4, "io finished %lu/%lu", events[i].res,
events[i].res2);

/* got an orphaned request */
Expand All @@ -283,7 +283,7 @@ get_events(struct aio_group *aio_grp, struct timespec *timeout)
} while (nr == 128); /* assume there are more events and try again */

if (nr < 0)
LOG(3, "async io getevents returned %i (errno=%s)",
LOG(4, "async io getevents returned %i (errno=%s)",
nr, strerror(errno));

return got_events;
Expand Down Expand Up @@ -315,7 +315,7 @@ check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
} else {
struct iocb *ios[1] = { &ct->req->io };

LOG(3, "starting new request");
LOG(4, "starting new request");
memset(&ct->req->io, 0, sizeof(struct iocb));
io_prep_pread(&ct->req->io, fd, ct->req->buf,
ct->req->blksize, 0);
Expand Down Expand Up @@ -360,7 +360,7 @@ check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
ct->running = 0;
rc = PATH_DOWN;
} else {
LOG(3, "async io pending");
LOG(4, "async io pending");
rc = PATH_PENDING;
}

Expand Down
26 changes: 16 additions & 10 deletions libmultipath/io_err_stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,14 @@ static int init_each_dio_ctx(struct dio_ctx *ct, int blksize,
return 0;
}

static void deinit_each_dio_ctx(struct dio_ctx *ct)
static int deinit_each_dio_ctx(struct dio_ctx *ct)
{
if (ct->buf)
free(ct->buf);
if (!ct->buf)
return 0;
if (ct->io_starttime.tv_sec != 0 || ct->io_starttime.tv_nsec != 0)
return 1;
free(ct->buf);
return 0;
}

static int setup_directio_ctx(struct io_err_stat_path *p)
Expand Down Expand Up @@ -164,6 +168,7 @@ static int setup_directio_ctx(struct io_err_stat_path *p)
static void free_io_err_stat_path(struct io_err_stat_path *p)
{
int i;
int inflight = 0;

if (!p)
return;
Expand All @@ -173,8 +178,13 @@ static void free_io_err_stat_path(struct io_err_stat_path *p)
cancel_inflight_io(p);

for (i = 0; i < CONCUR_NR_EVENT; i++)
deinit_each_dio_ctx(p->dio_ctx_array + i);
free(p->dio_ctx_array);
inflight += deinit_each_dio_ctx(p->dio_ctx_array + i);

if (!inflight)
free(p->dio_ctx_array);
else
io_err_stat_log(2, "%s: can't free aio space of %s, %d IOs in flight",
__func__, p->devname, inflight);

if (p->fd > 0)
close(p->fd);
Expand Down Expand Up @@ -503,7 +513,7 @@ static int try_to_cancel_timeout_io(struct dio_ctx *ct, struct timespec *t,
int rc = PATH_UNCHECKED;
int r;

if (ct->io_starttime.tv_sec == 0)
if (ct->io_starttime.tv_sec == 0 && ct->io_starttime.tv_nsec == 0)
return rc;
timespecsub(t, &ct->io_starttime, &difftime);
if (difftime.tv_sec > IOTIMEOUT_SEC) {
Expand All @@ -514,8 +524,6 @@ static int try_to_cancel_timeout_io(struct dio_ctx *ct, struct timespec *t,
if (r)
io_err_stat_log(5, "%s: io_cancel error %i",
dev, errno);
ct->io_starttime.tv_sec = 0;
ct->io_starttime.tv_nsec = 0;
rc = PATH_TIMEOUT;
} else {
rc = PATH_PENDING;
Expand Down Expand Up @@ -559,8 +567,6 @@ static void cancel_inflight_io(struct io_err_stat_path *pp)
if (r)
io_err_stat_log(5, "%s: io_cancel error %d, %i",
pp->devname, r, errno);
ct->io_starttime.tv_sec = 0;
ct->io_starttime.tv_nsec = 0;
}
}

Expand Down