Commit f92388fa authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-27900 fixes

* prevent infinite recursion in beyond-EOF reads (when pread returns 0)
* reduce code duplication

followup for d7817382 and f4fb6cb3
parent e9e6db93
...@@ -161,8 +161,7 @@ class aio_uring final : public tpool::aio ...@@ -161,8 +161,7 @@ class aio_uring final : public tpool::aio
} }
io_uring_cqe_seen(&aio->uring_, cqe); io_uring_cqe_seen(&aio->uring_, cqe);
if (iocb->m_ret_len != iocb->m_len && !iocb->m_err) finish_synchronous(iocb);
finish_synchronous(iocb);
// If we need to resubmit the IO operation, but the ring is full, // If we need to resubmit the IO operation, but the ring is full,
// we will follow the same path as for any other error codes. // we will follow the same path as for any other error codes.
......
...@@ -128,8 +128,7 @@ class aio_linux final : public aio ...@@ -128,8 +128,7 @@ class aio_linux final : public aio
{ {
iocb->m_ret_len= event.res; iocb->m_ret_len= event.res;
iocb->m_err= 0; iocb->m_err= 0;
if (iocb->m_ret_len != iocb->m_len) finish_synchronous(iocb);
finish_synchronous(iocb);
} }
iocb->m_internal_task.m_func= iocb->m_callback; iocb->m_internal_task.m_func= iocb->m_callback;
iocb->m_internal_task.m_arg= iocb; iocb->m_internal_task.m_arg= iocb;
......
...@@ -173,7 +173,17 @@ class aio ...@@ -173,7 +173,17 @@ class aio
protected: protected:
static void synchronous(aiocb *cb); static void synchronous(aiocb *cb);
/** finish a partial read/write callback synchronously */ /** finish a partial read/write callback synchronously */
static void finish_synchronous(aiocb *cb); static inline void finish_synchronous(aiocb *cb)
{
if (!cb->m_err && cb->m_ret_len != cb->m_len)
{
/* partial read/write */
cb->m_buffer= (char *) cb->m_buffer + cb->m_ret_len;
cb->m_len-= (unsigned int) cb->m_ret_len;
cb->m_offset+= cb->m_ret_len;
synchronous(cb);
}
}
}; };
class timer class timer
......
...@@ -85,24 +85,11 @@ void aio::synchronous(aiocb *cb) ...@@ -85,24 +85,11 @@ void aio::synchronous(aiocb *cb)
#endif #endif
cb->m_ret_len = ret_len; cb->m_ret_len = ret_len;
cb->m_err = err; cb->m_err = err;
if (!err && cb->m_ret_len != cb->m_len) if (ret_len)
finish_synchronous(cb); finish_synchronous(cb);
} }
/**
A partial read/write has occured, continue synchronously.
*/
void aio::finish_synchronous(aiocb *cb)
{
assert(cb->m_ret_len != (unsigned int) cb->m_len && !cb->m_err);
/* partial read/write */
cb->m_buffer= (char *) cb->m_buffer + cb->m_ret_len;
cb->m_len-= (unsigned int) cb->m_ret_len;
cb->m_offset+= cb->m_ret_len;
synchronous(cb);
}
/** /**
Implementation of generic threadpool. Implementation of generic threadpool.
This threadpool consists of the following components This threadpool consists of the following components
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment