summaryrefslogtreecommitdiff
path: root/storage/xtradb/os
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2014-04-16 12:13:43 +0300
committerJan Lindström <jplindst@mariadb.org>2014-04-16 12:13:43 +0300
commit150e88e8c9b85e3e6ce500a91fd215d231e99881 (patch)
treee029a8c9beae4cf67edc5239694c68f8b4de28c0 /storage/xtradb/os
parent983366e0eef50b95329bcba154ee4fb38b85df3c (diff)
parent142c20eda9d287f7f898dd8d89821f0e809dafc6 (diff)
downloadmariadb-git-150e88e8c9b85e3e6ce500a91fd215d231e99881.tar.gz
Merge from lp:maria/5.5 to maria-5.5.37 release revision 4154.
Diffstat (limited to 'storage/xtradb/os')
-rw-r--r--storage/xtradb/os/os0file.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index a5d7c69624a..c2c04f8c7a5 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -2494,12 +2494,13 @@ os_file_pread(
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
- /* Handle signal interruptions correctly */
+ /* Handle partial reads and signal interruptions correctly */
for (n_bytes = 0; n_bytes < (ssize_t) n; ) {
- n_read = pread(file, buf, (ssize_t)n, offs);
+ n_read = pread(file, buf, (ssize_t)n - n_bytes, offs);
if (n_read > 0) {
n_bytes += n_read;
offs += n_read;
+ buf = (char *)buf + n_read;
} else if (n_read == -1 && errno == EINTR) {
continue;
} else {
@@ -2622,12 +2623,13 @@ os_file_pwrite(
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
- /* Handle signal interruptions correctly */
+ /* Handle partial writes and signal interruptions correctly */
for (ret = 0; ret < (ssize_t) n; ) {
- n_written = pwrite(file, buf, (ssize_t)n, offs);
- if (n_written > 0) {
+ n_written = pwrite(file, buf, (ssize_t)n - ret, offs);
+ if (n_written >= 0) {
ret += n_written;
offs += n_written;
+ buf = (char *)buf + n_written;
} else if (n_written == -1 && errno == EINTR) {
continue;
} else {
@@ -4813,6 +4815,7 @@ os_aio_linux_handle(
segment = os_aio_get_array_and_local_segment(&array, global_seg);
n = array->n_slots / array->n_segments;
+ wait_for_event:
/* Loop until we have found a completed request. */
for (;;) {
ibool any_reserved = FALSE;
@@ -4882,6 +4885,43 @@ found:
ut_error;
}
#endif /* UNIV_DO_FLUSH */
+ } else if ((slot->ret == 0) && (slot->n_bytes > 0)
+ && (slot->n_bytes < (long) slot->len)) {
+ /* Partial read or write scenario */
+ int submit_ret;
+ struct iocb* iocb;
+ slot->buf = (byte*)slot->buf + slot->n_bytes;
+ slot->offset = slot->offset + slot->n_bytes;
+ slot->len = slot->len - slot->n_bytes;
+ /* Resetting the bytes read/written */
+ slot->n_bytes = 0;
+ slot->io_already_done = FALSE;
+ iocb = &(slot->control);
+
+ if (slot->type == OS_FILE_READ) {
+ io_prep_pread(&slot->control, slot->file, slot->buf,
+ slot->len, (off_t) slot->offset);
+ } else {
+ ut_a(slot->type == OS_FILE_WRITE);
+ io_prep_pwrite(&slot->control, slot->file, slot->buf,
+ slot->len, (off_t) slot->offset);
+ }
+ /* Resubmit an I/O request */
+ submit_ret = io_submit(array->aio_ctx[segment], 1, &iocb);
+ if (submit_ret < 0 ) {
+ /* Aborting in case of submit failure */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ "InnoDB: Error: Native Linux AIO interface. "
+ "io_submit() call failed when resubmitting a "
+ "partial I/O request on the file %s.",
+ slot->name);
+ ut_error;
+ } else {
+ ret = FALSE;
+ os_mutex_exit(array->mutex);
+ goto wait_for_event;
+ }
} else {
errno = -slot->ret;