@@ -2572,6 +2572,7 @@ struct cl_dio_aio {
struct cl_page_list cda_pages;
struct kiocb *cda_iocb;
ssize_t cda_bytes;
+ unsigned int cda_no_aio_complete:1;
};
/** @} cl_sync_io */
@@ -1669,6 +1669,13 @@ static void ll_heat_add(struct inode *inode, enum cl_io_type iot,
}
if (io->ci_aio) {
+ /*
+ * VFS will call aio_complete() if no -EIOCBQUEUED
+ * is returned for AIO, so we can not call aio_complete()
+ * in our end_io().
+ */
+ if (rc != -EIOCBQUEUED)
+ io->ci_aio->cda_no_aio_complete = 1;
/**
* Drop one extra reference so that end_io() could be
* called for this IO context, we could call it after
@@ -1087,7 +1087,7 @@ static void cl_aio_end(const struct lu_env *env, struct cl_sync_io *anchor)
cl_page_put(env, page);
}
- if (!is_sync_kiocb(aio->cda_iocb) &&
+ if (!is_sync_kiocb(aio->cda_iocb) && !aio->cda_no_aio_complete &&
aio->cda_iocb->ki_complete)
aio->cda_iocb->ki_complete(aio->cda_iocb,
ret ?: aio->cda_bytes, 0);
@@ -1108,6 +1108,7 @@ struct cl_dio_aio *cl_aio_alloc(struct kiocb *iocb)
cl_aio_end);
cl_page_list_init(&aio->cda_pages);
aio->cda_iocb = iocb;
+ aio->cda_no_aio_complete = 0;
}
return aio;
}