Skip to content

Commit a766849

Browse files
committed
io_ompio_file_open: fix offset calculation with SEEK_END
and SEEK_CUR. fixes an issue reported by Wei-keng Liao Fixes Issue open-mpi#6858 Note, that some manual adjustements were required compared to the commit on master due to structural differences in ompio between master and 3.x branches. (cherry picked from commit 34b06dc) Signed-off-by: Edgar Gabriel <[email protected]>
1 parent 4bf6ccf commit a766849

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
@@ -392,14 +392,53 @@ int mca_io_ompio_file_sync (ompi_file_t *fh)
392392
return ret;
393393
}
394394

395+
static void mca_io_ompio_file_get_eof_offset (mca_io_ompio_file_t *fh,
396+
OMPI_MPI_OFFSET_TYPE in_offset,
397+
OMPI_MPI_OFFSET_TYPE *out_offset)
398+
{
399+
/* a file_seek with SEEK_END might require an actual offset that is
400+
not lined up with the end of the file, depending on the file view.
401+
This routine determines the closest (smaller or equal) offset to
402+
the provided in_offset value, avoiding gaps in the file view and avoiding to
403+
break up an etype.
404+
*/
405+
OMPI_MPI_OFFSET_TYPE offset=0, prev_offset=0, start_offset=0;
406+
size_t k=0, blocklen=0;
407+
size_t index_in_file_view=0;
408+
409+
in_offset -= fh->f_disp;
410+
if ( fh->f_view_size > 0 ) {
411+
/* starting offset of the current copy of the filew view */
412+
start_offset = in_offset / fh->f_view_extent;
413+
414+
index_in_file_view = 0;
415+
/* determine block id that the offset is located in and
416+
the starting offset of that block */
417+
while ( offset <= in_offset && index_in_file_view < fh->f_iov_count) {
418+
prev_offset = offset;
419+
offset = start_offset + (OMPI_MPI_OFFSET_TYPE)(intptr_t) fh->f_decoded_iov[index_in_file_view++].iov_base;
420+
}
421+
422+
offset = prev_offset;
423+
blocklen = fh->f_decoded_iov[index_in_file_view-1].iov_len;
424+
while ( offset <= in_offset && k <= blocklen ) {
425+
prev_offset = offset;
426+
offset += fh->f_etype_size;
427+
k += fh->f_etype_size;
428+
}
429+
430+
*out_offset = prev_offset;
431+
}
432+
return;
433+
}
395434

396435
int mca_io_ompio_file_seek (ompi_file_t *fh,
397436
OMPI_MPI_OFFSET_TYPE off,
398437
int whence)
399438
{
400439
int ret = OMPI_SUCCESS;
401440
mca_io_ompio_data_t *data;
402-
OMPI_MPI_OFFSET_TYPE offset, temp_offset;
441+
OMPI_MPI_OFFSET_TYPE offset, temp_offset, temp_offset2;
403442

404443
data = (mca_io_ompio_data_t *) fh->f_io_selected_data;
405444

@@ -414,16 +453,20 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
414453
}
415454
break;
416455
case MPI_SEEK_CUR:
417-
offset += data->ompio_fh.f_position_in_file_view;
418-
offset += data->ompio_fh.f_disp;
456+
ret = mca_common_ompio_file_get_position (&data->ompio_fh,
457+
&temp_offset);
458+
offset += temp_offset * data->ompio_fh.f_etype_size;
459+
419460
if (offset < 0) {
420461
OPAL_THREAD_UNLOCK(&fh->f_mutex);
421462
return OMPI_ERROR;
422463
}
423464
break;
424465
case MPI_SEEK_END:
425466
ret = data->ompio_fh.f_fs->fs_file_get_size (&data->ompio_fh,
426-
&temp_offset);
467+
&temp_offset2);
468+
mca_io_ompio_file_get_eof_offset (&data->ompio_fh,
469+
temp_offset2, &temp_offset);
427470
offset += temp_offset;
428471
if (offset < 0 || OMPI_SUCCESS != ret) {
429472
OPAL_THREAD_UNLOCK(&fh->f_mutex);
@@ -442,6 +485,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
442485
return ret;
443486
}
444487

488+
445489
int mca_io_ompio_file_get_position (ompi_file_t *fd,
446490
OMPI_MPI_OFFSET_TYPE *offset)
447491
{

0 commit comments

Comments
 (0)