@@ -392,14 +392,53 @@ int mca_io_ompio_file_sync (ompi_file_t *fh)
392
392
return ret ;
393
393
}
394
394
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
+ }
395
434
396
435
int mca_io_ompio_file_seek (ompi_file_t * fh ,
397
436
OMPI_MPI_OFFSET_TYPE off ,
398
437
int whence )
399
438
{
400
439
int ret = OMPI_SUCCESS ;
401
440
mca_io_ompio_data_t * data ;
402
- OMPI_MPI_OFFSET_TYPE offset , temp_offset ;
441
+ OMPI_MPI_OFFSET_TYPE offset , temp_offset , temp_offset2 ;
403
442
404
443
data = (mca_io_ompio_data_t * ) fh -> f_io_selected_data ;
405
444
@@ -414,16 +453,20 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
414
453
}
415
454
break ;
416
455
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
+
419
460
if (offset < 0 ) {
420
461
OPAL_THREAD_UNLOCK (& fh -> f_mutex );
421
462
return OMPI_ERROR ;
422
463
}
423
464
break ;
424
465
case MPI_SEEK_END :
425
466
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 );
427
470
offset += temp_offset ;
428
471
if (offset < 0 || OMPI_SUCCESS != ret ) {
429
472
OPAL_THREAD_UNLOCK (& fh -> f_mutex );
@@ -442,6 +485,7 @@ int mca_io_ompio_file_seek (ompi_file_t *fh,
442
485
return ret ;
443
486
}
444
487
488
+
445
489
int mca_io_ompio_file_get_position (ompi_file_t * fd ,
446
490
OMPI_MPI_OFFSET_TYPE * offset )
447
491
{
0 commit comments