@@ -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
432471int 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+
481525int mca_io_ompio_file_get_position (ompi_file_t * fd ,
482526 OMPI_MPI_OFFSET_TYPE * offset )
483527{
0 commit comments