@@ -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
389428int 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+
439481int mca_io_ompio_file_get_position (ompi_file_t * fd ,
440482 OMPI_MPI_OFFSET_TYPE * offset )
441483{
0 commit comments