diff options
author | Jan Lindström <jplindst@mariadb.org> | 2014-04-16 12:13:43 +0300 |
---|---|---|
committer | Jan Lindström <jplindst@mariadb.org> | 2014-04-16 12:13:43 +0300 |
commit | 150e88e8c9b85e3e6ce500a91fd215d231e99881 (patch) | |
tree | e029a8c9beae4cf67edc5239694c68f8b4de28c0 /storage/xtradb/os | |
parent | 983366e0eef50b95329bcba154ee4fb38b85df3c (diff) | |
parent | 142c20eda9d287f7f898dd8d89821f0e809dafc6 (diff) | |
download | mariadb-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.c | 50 |
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; |