Skip to content

v3.1.x: io_ompio_file_open: fix offset calculation with SEEK_END #6955

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 4, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions ompi/mca/io/ompio/io_ompio_file_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,53 @@ int mca_io_ompio_file_sync (ompi_file_t *fh)
return ret;
}

static void mca_io_ompio_file_get_eof_offset (mca_io_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,
int whence)
{
int ret = OMPI_SUCCESS;
mca_io_ompio_data_t *data;
OMPI_MPI_OFFSET_TYPE offset, temp_offset;
OMPI_MPI_OFFSET_TYPE offset, temp_offset, temp_offset2;

data = (mca_io_ompio_data_t *) fh->f_io_selected_data;

Expand All @@ -414,16 +453,20 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
}
break;
case MPI_SEEK_CUR:
offset += data->ompio_fh.f_position_in_file_view;
offset += data->ompio_fh.f_disp;
ret = mca_common_ompio_file_get_position (&data->ompio_fh,
&temp_offset);
offset += temp_offset * data->ompio_fh.f_etype_size;

if (offset < 0) {
OPAL_THREAD_UNLOCK(&fh->f_mutex);
return OMPI_ERROR;
}
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_mutex);
Expand All @@ -442,6 +485,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)
{
Expand Down