Skip to content

Commit 76cdb13

Browse files
authored
Merge pull request #6955 from edgargabriel/pr/file_seek_end_fix-v3.1
v3.1.x: io_ompio_file_open: fix offset calculation with SEEK_END
2 parents 4bf6ccf + a766849 commit 76cdb13

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)