1
1

Merge pull request #6905 from edgargabriel/pr/file-seek-end-fix-v4.0.x

io_ompio_file_open: fix offset calculation with SEEK_END
Этот коммит содержится в:
Howard Pritchard 2019-08-23 13:11:33 -06:00 коммит произвёл GitHub
родитель 390e0bc5b2 d72d39bfee
Коммит e4adbeefe7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23

Просмотреть файл

@ -385,6 +385,45 @@ int mca_io_ompio_file_sync (ompi_file_t *fh)
return ret;
}
static void mca_io_ompio_file_get_eof_offset (ompio_file_t *fh,
OMPI_MPI_OFFSET_TYPE in_offset,
OMPI_MPI_OFFSET_TYPE *out_offset)
{
/* a file_seek with SEEK_END might require an actual offset that is
not lined up with the end of the file, depending on the file view.
This routine determines the closest (smaller or equal) offset to
the provided in_offset value, avoiding gaps in the file view and avoiding to
break up an etype.
*/
OMPI_MPI_OFFSET_TYPE offset=0, prev_offset=0, start_offset=0;
size_t k=0, blocklen=0;
size_t index_in_file_view=0;
in_offset -= fh->f_disp;
if ( fh->f_view_size > 0 ) {
/* starting offset of the current copy of the filew view */
start_offset = in_offset / fh->f_view_extent;
index_in_file_view = 0;
/* determine block id that the offset is located in and
the starting offset of that block */
while ( offset <= in_offset && index_in_file_view < fh->f_iov_count) {
prev_offset = offset;
offset = start_offset + (OMPI_MPI_OFFSET_TYPE)(intptr_t) fh->f_decoded_iov[index_in_file_view++].iov_base;
}
offset = prev_offset;
blocklen = fh->f_decoded_iov[index_in_file_view-1].iov_len;
while ( offset <= in_offset && k <= blocklen ) {
prev_offset = offset;
offset += fh->f_etype_size;
k += fh->f_etype_size;
}
*out_offset = prev_offset;
}
return;
}
int mca_io_ompio_file_seek (ompi_file_t *fh,
OMPI_MPI_OFFSET_TYPE off,
@ -392,7 +431,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
{
int ret = OMPI_SUCCESS;
mca_common_ompio_data_t *data;
OMPI_MPI_OFFSET_TYPE offset, temp_offset;
OMPI_MPI_OFFSET_TYPE offset, temp_offset, temp_offset2;
data = (mca_common_ompio_data_t *) fh->f_io_selected_data;
@ -409,7 +448,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
case MPI_SEEK_CUR:
ret = mca_common_ompio_file_get_position (&data->ompio_fh,
&temp_offset);
offset += temp_offset;
offset += temp_offset * data->ompio_fh.f_etype_size;
if (offset < 0) {
OPAL_THREAD_UNLOCK(&fh->f_lock);
return OMPI_ERROR;
@ -417,7 +456,9 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
break;
case MPI_SEEK_END:
ret = data->ompio_fh.f_fs->fs_file_get_size (&data->ompio_fh,
&temp_offset);
&temp_offset2);
mca_io_ompio_file_get_eof_offset (&data->ompio_fh,
temp_offset2, &temp_offset);
offset += temp_offset;
if (offset < 0 || OMPI_SUCCESS != ret) {
OPAL_THREAD_UNLOCK(&fh->f_lock);
@ -436,6 +477,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
return ret;
}
int mca_io_ompio_file_get_position (ompi_file_t *fd,
OMPI_MPI_OFFSET_TYPE *offset)
{