Skip to content

Commit 34b06dc

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 #6858 Signed-off-by: Edgar Gabriel <[email protected]>
1 parent 385da4e commit 34b06dc

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

ompi/mca/io/ompio/io_ompio_file_open.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,53 @@ int mca_io_ompio_file_sync (ompi_file_t *fh)
385385
return ret;
386386
}
387387

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

389428
int mca_io_ompio_file_seek (ompi_file_t *fh,
390429
OMPI_MPI_OFFSET_TYPE off,
391430
int whence)
392431
{
393432
int ret = OMPI_SUCCESS;
394433
mca_common_ompio_data_t *data;
395-
OMPI_MPI_OFFSET_TYPE offset, temp_offset;
434+
OMPI_MPI_OFFSET_TYPE offset, temp_offset, temp_offset2;
396435

397436
data = (mca_common_ompio_data_t *) fh->f_io_selected_data;
398437

@@ -409,15 +448,17 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
409448
case MPI_SEEK_CUR:
410449
ret = mca_common_ompio_file_get_position (&data->ompio_fh,
411450
&temp_offset);
412-
offset += temp_offset;
451+
offset += temp_offset * data->ompio_fh.f_etype_size;
413452
if (offset < 0) {
414453
OPAL_THREAD_UNLOCK(&fh->f_lock);
415454
return OMPI_ERROR;
416455
}
417456
break;
418457
case MPI_SEEK_END:
419458
ret = data->ompio_fh.f_fs->fs_file_get_size (&data->ompio_fh,
420-
&temp_offset);
459+
&temp_offset2);
460+
mca_io_ompio_file_get_eof_offset (&data->ompio_fh,
461+
temp_offset2, &temp_offset);
421462
offset += temp_offset;
422463
if (offset < 0 || OMPI_SUCCESS != ret) {
423464
OPAL_THREAD_UNLOCK(&fh->f_lock);
@@ -436,6 +477,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
436477
return ret;
437478
}
438479

480+
439481
int mca_io_ompio_file_get_position (ompi_file_t *fd,
440482
OMPI_MPI_OFFSET_TYPE *offset)
441483
{

0 commit comments

Comments
 (0)