Skip to content

Commit 87dfebb

Browse files
authored
Merge pull request #6956 from edgargabriel/pr/file_seek_end_fix-v3.0
v3.0.x: io_ompio_file_open: fix offset calculation with SEEK_END
2 parents b6e501b + 67b629b commit 87dfebb

File tree

1 file changed

+48
-4
lines changed

1 file changed

+48
-4
lines changed

ompi/mca/io/ompio/io_ompio_file_open.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,53 @@ int mca_io_ompio_file_sync (ompi_file_t *fh)
428428
return ret;
429429
}
430430

431+
static void mca_io_ompio_file_get_eof_offset (mca_io_ompio_file_t *fh,
432+
OMPI_MPI_OFFSET_TYPE in_offset,
433+
OMPI_MPI_OFFSET_TYPE *out_offset)
434+
{
435+
/* a file_seek with SEEK_END might require an actual offset that is
436+
not lined up with the end of the file, depending on the file view.
437+
This routine determines the closest (smaller or equal) offset to
438+
the provided in_offset value, avoiding gaps in the file view and avoiding to
439+
break up an etype.
440+
*/
441+
OMPI_MPI_OFFSET_TYPE offset=0, prev_offset=0, start_offset=0;
442+
size_t k=0, blocklen=0;
443+
size_t index_in_file_view=0;
444+
445+
in_offset -= fh->f_disp;
446+
if ( fh->f_view_size > 0 ) {
447+
/* starting offset of the current copy of the filew view */
448+
start_offset = in_offset / fh->f_view_extent;
449+
450+
index_in_file_view = 0;
451+
/* determine block id that the offset is located in and
452+
the starting offset of that block */
453+
while ( offset <= in_offset && index_in_file_view < fh->f_iov_count) {
454+
prev_offset = offset;
455+
offset = start_offset + (OMPI_MPI_OFFSET_TYPE)(intptr_t) fh->f_decoded_iov[index_in_file_view++].iov_base;
456+
}
457+
458+
offset = prev_offset;
459+
blocklen = fh->f_decoded_iov[index_in_file_view-1].iov_len;
460+
while ( offset <= in_offset && k <= blocklen ) {
461+
prev_offset = offset;
462+
offset += fh->f_etype_size;
463+
k += fh->f_etype_size;
464+
}
465+
466+
*out_offset = prev_offset;
467+
}
468+
return;
469+
}
431470

432471
int mca_io_ompio_file_seek (ompi_file_t *fh,
433472
OMPI_MPI_OFFSET_TYPE off,
434473
int whence)
435474
{
436475
int ret = OMPI_SUCCESS;
437476
mca_io_ompio_data_t *data;
438-
OMPI_MPI_OFFSET_TYPE offset, temp_offset;
477+
OMPI_MPI_OFFSET_TYPE offset, temp_offset, temp_offset2;
439478

440479
data = (mca_io_ompio_data_t *) fh->f_io_selected_data;
441480

@@ -450,16 +489,20 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
450489
}
451490
break;
452491
case MPI_SEEK_CUR:
453-
offset += data->ompio_fh.f_position_in_file_view;
454-
offset += data->ompio_fh.f_disp;
492+
ret = mca_common_ompio_file_get_position (&data->ompio_fh,
493+
&temp_offset);
494+
offset += temp_offset * data->ompio_fh.f_etype_size;
495+
455496
if (offset < 0) {
456497
OPAL_THREAD_UNLOCK(&fh->f_mutex);
457498
return OMPI_ERROR;
458499
}
459500
break;
460501
case MPI_SEEK_END:
461502
ret = data->ompio_fh.f_fs->fs_file_get_size (&data->ompio_fh,
462-
&temp_offset);
503+
&temp_offset2);
504+
mca_io_ompio_file_get_eof_offset (&data->ompio_fh,
505+
temp_offset2, &temp_offset);
463506
offset += temp_offset;
464507
if (offset < 0 || OMPI_SUCCESS != ret) {
465508
OPAL_THREAD_UNLOCK(&fh->f_mutex);
@@ -478,6 +521,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
478521
return ret;
479522
}
480523

524+
481525
int mca_io_ompio_file_get_position (ompi_file_t *fd,
482526
OMPI_MPI_OFFSET_TYPE *offset)
483527
{

0 commit comments

Comments
 (0)