-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/romio/adio/ad_nfs/ad_nfs_write.c
        -:    0:Graph:ad_nfs_write.gcno
        -:    0:Data:ad_nfs_write.gcda
        -:    0:Runs:224
        -:    0:Programs:67
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/* 
        -:    3: *
        -:    4: *   Copyright (C) 1997 University of Chicago. 
        -:    5: *   See COPYRIGHT notice in top-level directory.
        -:    6: */
        -:    7:
        -:    8:#include "ad_nfs.h"
        -:    9:#include "adio_extern.h"
        -:   10:
        -:   11:void ADIOI_NFS_WriteContig(ADIO_File fd, void *buf, int count, 
        -:   12:                     MPI_Datatype datatype, int file_ptr_type,
        -:   13:		     ADIO_Offset offset, ADIO_Status *status, int *error_code)
    #####:   14:{
    #####:   15:    int err=-1, datatype_size, len;
        -:   16:    static char myname[] = "ADIOI_NFS_WRITECONTIG";
        -:   17:
    #####:   18:    MPI_Type_size(datatype, &datatype_size);
    #####:   19:    len = datatype_size * count;
        -:   20:
    #####:   21:    if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
    #####:   22:	if (fd->fp_sys_posn != offset) {
        -:   23:#ifdef ADIOI_MPE_LOGGING
        -:   24:            MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:   25:#endif
    #####:   26:	    lseek(fd->fd_sys, offset, SEEK_SET);
        -:   27:#ifdef ADIOI_MPE_LOGGING
        -:   28:            MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:   29:#endif
        -:   30:        }
    #####:   31:	ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
        -:   32:#ifdef ADIOI_MPE_LOGGING
        -:   33:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
        -:   34:#endif
    #####:   35:	err = write(fd->fd_sys, buf, len);
        -:   36:#ifdef ADIOI_MPE_LOGGING
        -:   37:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
        -:   38:#endif
    #####:   39:	ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
    #####:   40:	fd->fp_sys_posn = offset + err;
        -:   41:	/* individual file pointer not updated */        
        -:   42:    }
        -:   43:    else { /* write from curr. location of ind. file pointer */
    #####:   44:	offset = fd->fp_ind;
    #####:   45:	if (fd->fp_sys_posn != fd->fp_ind) {
        -:   46:#ifdef ADIOI_MPE_LOGGING
        -:   47:            MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:   48:#endif
    #####:   49:	    lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
        -:   50:#ifdef ADIOI_MPE_LOGGING
        -:   51:            MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:   52:#endif
        -:   53:        }
    #####:   54:	ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
        -:   55:#ifdef ADIOI_MPE_LOGGING
        -:   56:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
        -:   57:#endif
    #####:   58:	err = write(fd->fd_sys, buf, len);
        -:   59:#ifdef ADIOI_MPE_LOGGING
        -:   60:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
        -:   61:#endif
    #####:   62:	ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
    #####:   63:	fd->fp_ind += err;
    #####:   64:	fd->fp_sys_posn = fd->fp_ind;
        -:   65:    }
        -:   66:
        -:   67:    /* --BEGIN ERROR HANDLING-- */
    #####:   68:    if (err == -1) {
    #####:   69:	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
        -:   70:					   myname, __LINE__, MPI_ERR_IO,
        -:   71:					   "**io",
        -:   72:					   "**io %s", strerror(errno));
    #####:   73:	return;
        -:   74:    }
        -:   75:    /* --END ERROR HANDLING-- */
        -:   76:
        -:   77:#ifdef HAVE_STATUS_SET_BYTES
    #####:   78:    MPIR_Status_set_bytes(status, datatype, err);
        -:   79:#endif
        -:   80:
    #####:   81:    *error_code = MPI_SUCCESS;
        -:   82:}
        -:   83:
        -:   84:
        -:   85:
        -:   86:
        -:   87:#ifdef ADIOI_MPE_LOGGING
        -:   88:#define ADIOI_BUFFERED_WRITE \
        -:   89:{ \
        -:   90:    if (req_off >= writebuf_off + writebuf_len) { \
        -:   91:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:   92:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:   93:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:   94:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
        -:   95:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:   96:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
        -:   97:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:   98:        if (err == -1) err_flag = 1; \
        -:   99:	writebuf_off = req_off; \
        -:  100:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  101:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  102:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:  103:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  104:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:  105:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL ); \
        -:  106:	err = read(fd->fd_sys, writebuf, writebuf_len); \
        -:  107:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL ); \
        -:  108:        if (err == -1) { \
        -:  109:            *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
        -:  110:					       MPIR_ERR_RECOVERABLE, myname, \
        -:  111:					       __LINE__, MPI_ERR_IO, \
        -:  112:					       "**ioRMWrdwr", 0); \
        -:  113:	    return; \
        -:  114:        } \
        -:  115:    } \
        -:  116:    write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
        -:  117:    memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
        -:  118:    while (write_sz != req_len) { \
        -:  119:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:  120:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  121:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:  122:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
        -:  123:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  124:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
        -:  125:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  126:        if (err == -1) err_flag = 1; \
        -:  127:        req_len -= write_sz; \
        -:  128:        userbuf_off += write_sz; \
        -:  129:        writebuf_off += writebuf_len; \
        -:  130:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  131:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  132:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:  133:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  134:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:  135:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL ); \
        -:  136:	err = read(fd->fd_sys, writebuf, writebuf_len); \
        -:  137:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL ); \
        -:  138:        if (err == -1) { \
        -:  139:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
        -:  140:					       MPIR_ERR_RECOVERABLE, myname, \
        -:  141:					       __LINE__, MPI_ERR_IO, \
        -:  142:					       "**ioRMWrdwr", 0); \
        -:  143:	    return; \
        -:  144:        } \
        -:  145:        write_sz = ADIOI_MIN(req_len, writebuf_len); \
        -:  146:        memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
        -:  147:    } \
        -:  148:}
        -:  149:#else
        -:  150:#define ADIOI_BUFFERED_WRITE \
        -:  151:{ \
        -:  152:    if (req_off >= writebuf_off + writebuf_len) { \
        -:  153:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  154:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  155:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  156:        if (err == -1) err_flag = 1; \
        -:  157:	writebuf_off = req_off; \
        -:  158:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  159:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  160:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  161:	err = read(fd->fd_sys, writebuf, writebuf_len); \
        -:  162:        if (err == -1) { \
        -:  163:            *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
        -:  164:					       MPIR_ERR_RECOVERABLE, myname, \
        -:  165:					       __LINE__, MPI_ERR_IO, \
        -:  166:					       "**ioRMWrdwr", 0); \
        -:  167:	    return; \
        -:  168:        } \
        -:  169:    } \
        -:  170:    write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
        -:  171:    memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
        -:  172:    while (write_sz != req_len) { \
        -:  173:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  174:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  175:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  176:        if (err == -1) err_flag = 1; \
        -:  177:        req_len -= write_sz; \
        -:  178:        userbuf_off += write_sz; \
        -:  179:        writebuf_off += writebuf_len; \
        -:  180:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  181:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  182:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  183:	err = read(fd->fd_sys, writebuf, writebuf_len); \
        -:  184:        if (err == -1) { \
        -:  185:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
        -:  186:					       MPIR_ERR_RECOVERABLE, myname, \
        -:  187:					       __LINE__, MPI_ERR_IO, \
        -:  188:					       "**ioRMWrdwr", 0); \
        -:  189:	    return; \
        -:  190:        } \
        -:  191:        write_sz = ADIOI_MIN(req_len, writebuf_len); \
        -:  192:        memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
        -:  193:    } \
        -:  194:}
        -:  195:#endif
        -:  196:
        -:  197:/* this macro is used when filetype is contig and buftype is not contig.
        -:  198:   it does not do a read-modify-write and does not lock*/
        -:  199:#ifdef ADIOI_MPE_LOGGING
        -:  200:#define ADIOI_BUFFERED_WRITE_WITHOUT_READ \
        -:  201:{ \
        -:  202:    if (req_off >= writebuf_off + writebuf_len) { \
        -:  203:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:  204:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  205:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:  206:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  207:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
        -:  208:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  209:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
        -:  210:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  211:        if (err == -1) err_flag = 1; \
        -:  212:	writebuf_off = req_off; \
        -:  213:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  214:    } \
        -:  215:    write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
        -:  216:    memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
        -:  217:    while (write_sz != req_len) { \
        -:  218:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:  219:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  220:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:  221:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  222:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
        -:  223:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  224:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
        -:  225:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  226:        if (err == -1) err_flag = 1; \
        -:  227:        req_len -= write_sz; \
        -:  228:        userbuf_off += write_sz; \
        -:  229:        writebuf_off += writebuf_len; \
        -:  230:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  231:        write_sz = ADIOI_MIN(req_len, writebuf_len); \
        -:  232:        memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
        -:  233:    } \
        -:  234:}
        -:  235:#else
        -:  236:#define ADIOI_BUFFERED_WRITE_WITHOUT_READ \
        -:  237:{ \
        -:  238:    if (req_off >= writebuf_off + writebuf_len) { \
        -:  239:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  240:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  241:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  242:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  243:        if (err == -1) err_flag = 1; \
        -:  244:	writebuf_off = req_off; \
        -:  245:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  246:    } \
        -:  247:    write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
        -:  248:    memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
        -:  249:    while (write_sz != req_len) { \
        -:  250:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
        -:  251:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  252:	err = write(fd->fd_sys, writebuf, writebuf_len); \
        -:  253:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
        -:  254:        if (err == -1) err_flag = 1; \
        -:  255:        req_len -= write_sz; \
        -:  256:        userbuf_off += write_sz; \
        -:  257:        writebuf_off += writebuf_len; \
        -:  258:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
        -:  259:        write_sz = ADIOI_MIN(req_len, writebuf_len); \
        -:  260:        memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
        -:  261:    } \
        -:  262:}
        -:  263:#endif
        -:  264:
        -:  265:
        -:  266:void ADIOI_NFS_WriteStrided(ADIO_File fd, void *buf, int count,
        -:  267:                       MPI_Datatype datatype, int file_ptr_type,
        -:  268:                       ADIO_Offset offset, ADIO_Status *status, int
        -:  269:                       *error_code)
    #####:  270:{
        -:  271:/* offset is in units of etype relative to the filetype. */
        -:  272:
        -:  273:    ADIOI_Flatlist_node *flat_buf, *flat_file;
    #####:  274:    int i, j, k, err=-1, bwr_size, fwr_size=0, st_index=0;
        -:  275:    int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
        -:  276:    int n_filetypes, etype_in_filetype;
    #####:  277:    ADIO_Offset abs_off_in_filetype=0;
        -:  278:    int filetype_size, etype_size, buftype_size, req_len;
        -:  279:    MPI_Aint filetype_extent, buftype_extent; 
        -:  280:    int buf_count, buftype_is_contig, filetype_is_contig;
        -:  281:    ADIO_Offset userbuf_off;
    #####:  282:    ADIO_Offset off, req_off, disp, end_offset=0, writebuf_off, start_off;
        -:  283:    char *writebuf, *value;
        -:  284:    int flag, st_fwr_size, st_n_filetypes, writebuf_len, write_sz;
    #####:  285:    int new_bwr_size, new_fwr_size, err_flag=0, info_flag, max_bufsize;
        -:  286:    static char myname[] = "ADIOI_NFS_WRITESTRIDED";
        -:  287:
    #####:  288:    ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
    #####:  289:    ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
        -:  290:
    #####:  291:    MPI_Type_size(fd->filetype, &filetype_size);
    #####:  292:    if ( ! filetype_size ) {
    #####:  293:	*error_code = MPI_SUCCESS; 
    #####:  294:	return;
        -:  295:    }
        -:  296:
    #####:  297:    MPI_Type_extent(fd->filetype, &filetype_extent);
    #####:  298:    MPI_Type_size(datatype, &buftype_size);
    #####:  299:    MPI_Type_extent(datatype, &buftype_extent);
    #####:  300:    etype_size = fd->etype_size;
        -:  301:
    #####:  302:    bufsize = buftype_size * count;
        -:  303:
        -:  304:/* get max_bufsize from the info object. */
        -:  305:
    #####:  306:    value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
    #####:  307:    MPI_Info_get(fd->info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, 
        -:  308:                 &info_flag);
    #####:  309:    max_bufsize = atoi(value);
    #####:  310:    ADIOI_Free(value);
        -:  311:
    #####:  312:    if (!buftype_is_contig && filetype_is_contig) {
        -:  313:
        -:  314:/* noncontiguous in memory, contiguous in file. */
        -:  315:
    #####:  316:	ADIOI_Flatten_datatype(datatype);
    #####:  317:	flat_buf = ADIOI_Flatlist;
    #####:  318:	while (flat_buf->type != datatype) flat_buf = flat_buf->next;
        -:  319:
    #####:  320:        off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : 
        -:  321:                 fd->disp + etype_size * offset;
        -:  322:
    #####:  323:        start_off = off;
    #####:  324:	end_offset = off + bufsize - 1;
    #####:  325:        writebuf_off = off;
    #####:  326:        writebuf = (char *) ADIOI_Malloc(max_bufsize);
    #####:  327:        writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));
        -:  328:
        -:  329:/* if atomicity is true, lock the region to be accessed */
    #####:  330:        if (fd->atomicity) 
    #####:  331:            ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  332:
    #####:  333:        for (j=0; j<count; j++) 
    #####:  334:            for (i=0; i<flat_buf->count; i++) {
    #####:  335:                userbuf_off = j*buftype_extent + flat_buf->indices[i];
    #####:  336:		req_off = off;
    #####:  337:		req_len = flat_buf->blocklens[i];
    #####:  338:		ADIOI_BUFFERED_WRITE_WITHOUT_READ
    #####:  339:                off += flat_buf->blocklens[i];
        -:  340:            }
        -:  341:
        -:  342:        /* write the buffer out finally */
        -:  343:#ifdef ADIOI_MPE_LOGGING
        -:  344:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:  345:#endif
    #####:  346:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); 
        -:  347:#ifdef ADIOI_MPE_LOGGING
        -:  348:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:  349:#endif
    #####:  350:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
        -:  351:#ifdef ADIOI_MPE_LOGGING
        -:  352:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
        -:  353:#endif
    #####:  354:	err = write(fd->fd_sys, writebuf, writebuf_len); 
        -:  355:#ifdef ADIOI_MPE_LOGGING
        -:  356:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
        -:  357:#endif
    #####:  358:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
    #####:  359:        if (err == -1) err_flag = 1; 
        -:  360:
    #####:  361:        if (fd->atomicity) 
    #####:  362:            ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  363:
    #####:  364:	ADIOI_Free(writebuf); /* malloced in the buffered_write macro */
        -:  365:
    #####:  366:        if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
    #####:  367:	if (err_flag) {
    #####:  368:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS,
        -:  369:					       MPIR_ERR_RECOVERABLE, myname,
        -:  370:					       __LINE__, MPI_ERR_IO, "**io",
        -:  371:					       "**io %s", strerror(errno));
        -:  372:	}
    #####:  373:	else *error_code = MPI_SUCCESS;
        -:  374:    }
        -:  375:
        -:  376:    else {  /* noncontiguous in file */
        -:  377:
        -:  378:/* filetype already flattened in ADIO_Open */
    #####:  379:	flat_file = ADIOI_Flatlist;
    #####:  380:	while (flat_file->type != fd->filetype) flat_file = flat_file->next;
    #####:  381:	disp = fd->disp;
        -:  382:
    #####:  383:	if (file_ptr_type == ADIO_INDIVIDUAL) {
        -:  384:       /* Wei-keng reworked type processing to be a bit more efficient */
    #####:  385:            offset       = fd->fp_ind - disp;
    #####:  386:            n_filetypes  = (offset - flat_file->indices[0]) / filetype_extent;
    #####:  387:            offset      -= (ADIO_Offset)n_filetypes * filetype_extent;
        -:  388:            /* now offset is local to this extent */
        -:  389:
        -:  390:            /* find the block where offset is located, skip blocklens[i]==0 */
    #####:  391:            for (i=0; i<flat_file->count; i++) {
        -:  392:                ADIO_Offset dist;
    #####:  393:                if (flat_file->blocklens[i] == 0) continue;
    #####:  394:                dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
        -:  395:                /* fwr_size is from offset to the end of block i */
    #####:  396:                if (dist == 0) {
    #####:  397:                    i++;
    #####:  398:                    offset   = flat_file->indices[i];
    #####:  399:                    fwr_size = flat_file->blocklens[i];
    #####:  400:                    break;
        -:  401:                }
    #####:  402:                if (dist > 0) {
    #####:  403:                    fwr_size = dist;
    #####:  404:                    break;
        -:  405:                }
        -:  406:            }
    #####:  407:            st_index = i;  /* starting index in flat_file->indices[] */
    #####:  408:            offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
        -:  409:        }
        -:  410:	else {
    #####:  411:	    n_etypes_in_filetype = filetype_size/etype_size;
    #####:  412:	    n_filetypes = (int) (offset / n_etypes_in_filetype);
    #####:  413:	    etype_in_filetype = (int) (offset % n_etypes_in_filetype);
    #####:  414:	    size_in_filetype = etype_in_filetype * etype_size;
        -:  415: 
    #####:  416:	    sum = 0;
    #####:  417:	    for (i=0; i<flat_file->count; i++) {
    #####:  418:		sum += flat_file->blocklens[i];
    #####:  419:		if (sum > size_in_filetype) {
    #####:  420:		    st_index = i;
    #####:  421:		    fwr_size = sum - size_in_filetype;
    #####:  422:		    abs_off_in_filetype = flat_file->indices[i] +
        -:  423:			size_in_filetype - (sum - flat_file->blocklens[i]);
    #####:  424:		    break;
        -:  425:		}
        -:  426:	    }
        -:  427:
        -:  428:	    /* abs. offset in bytes in the file */
    #####:  429:	    offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + 
        -:  430:		abs_off_in_filetype;
        -:  431:	}
        -:  432:
    #####:  433:        start_off = offset;
        -:  434:       /* Wei-keng Liao:write request is within single flat_file contig block*/
        -:  435:       /* this could happen, for example, with subarray types that are
        -:  436:        * actually fairly contiguous */
    #####:  437:        if (buftype_is_contig && bufsize <= fwr_size) {
    #####:  438:            ADIO_WriteContig(fd, buf, bufsize, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
        -:  439:                             offset, status, error_code);
        -:  440:
    #####:  441:           if (file_ptr_type == ADIO_INDIVIDUAL) {
        -:  442:                /* update MPI-IO file pointer to point to the first byte 
        -:  443:                * that can be accessed in the fileview. */
    #####:  444:                fd->fp_ind = offset + bufsize;
    #####:  445:                if (bufsize == fwr_size) {
        -:  446:                    do {
    #####:  447:                        st_index++;
    #####:  448:                        if (st_index == flat_file->count) {
    #####:  449:                            st_index = 0;
    #####:  450:                            n_filetypes++;
        -:  451:                        }
    #####:  452:                    } while (flat_file->blocklens[st_index] == 0);
    #####:  453:                    fd->fp_ind = disp + flat_file->indices[st_index]
        -:  454:                               + (ADIO_Offset)n_filetypes*filetype_extent;
        -:  455:                }
        -:  456:            }
    #####:  457:           fd->fp_sys_posn = -1;   /* set it to null. */ 
        -:  458:#ifdef HAVE_STATUS_SET_BYTES
    #####:  459:           MPIR_Status_set_bytes(status, datatype, bufsize);
        -:  460:#endif 
    #####:  461:            return;
        -:  462:        }
        -:  463:
        -:  464:       /* Calculate end_offset, the last byte-offset that will be accessed.
        -:  465:         e.g., if start_offset=0 and 100 bytes to be write, end_offset=99*/
        -:  466:
    #####:  467:	st_fwr_size = fwr_size;
    #####:  468:	st_n_filetypes = n_filetypes;
    #####:  469:	i = 0;
    #####:  470:	j = st_index;
    #####:  471:	off = offset;
    #####:  472:	fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
    #####:  473:	while (i < bufsize) {
    #####:  474:	    i += fwr_size;
    #####:  475:	    end_offset = off + fwr_size - 1;
    #####:  476:            j = (j+1) % flat_file->count;
    #####:  477:            n_filetypes += (j == 0) ? 1 : 0;
    #####:  478:            while (flat_file->blocklens[j]==0) {
    #####:  479:                j = (j+1) % flat_file->count;
    #####:  480:                n_filetypes += (j == 0) ? 1 : 0;
        -:  481:	    }
        -:  482:
    #####:  483:	    off = disp + flat_file->indices[j] + 
        -:  484:		    (ADIO_Offset) n_filetypes*filetype_extent;
    #####:  485:	    fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
        -:  486:	}
        -:  487:
        -:  488:/* if atomicity is true, lock the region to be accessed */
    #####:  489:        if (fd->atomicity) 
    #####:  490:            ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  491:
        -:  492:        /* initial read for the read-modify-write */
    #####:  493:        writebuf_off = offset;
    #####:  494:        writebuf = (char *) ADIOI_Malloc(max_bufsize);
    #####:  495:        writebuf_len = (int)(ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));
    #####:  496:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
        -:  497:#ifdef ADIOI_MPE_LOGGING
        -:  498:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:  499:#endif
    #####:  500:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); 
        -:  501:#ifdef ADIOI_MPE_LOGGING
        -:  502:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:  503:#endif
        -:  504:#ifdef ADIOI_MPE_LOGGING
        -:  505:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
        -:  506:#endif
    #####:  507:	err = read(fd->fd_sys, writebuf, writebuf_len); 
        -:  508:#ifdef ADIOI_MPE_LOGGING
        -:  509:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
        -:  510:#endif
    #####:  511:        if (err == -1) {
    #####:  512:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS,
        -:  513:					       MPIR_ERR_RECOVERABLE,
        -:  514:					       myname, __LINE__,
        -:  515:					       MPI_ERR_IO,
        -:  516:					       "ADIOI_NFS_WriteStrided: ROMIO tries to optimize this access by doing a read-modify-write, but is unable to read the file. Please give the file read permission and open it with MPI_MODE_RDWR.", 0);
    #####:  517:	    return;
        -:  518:        } 
        -:  519:
    #####:  520:	if (buftype_is_contig && !filetype_is_contig) {
        -:  521:
        -:  522:/* contiguous in memory, noncontiguous in file. should be the most
        -:  523:   common case. */
        -:  524:
    #####:  525:	    i = 0;
    #####:  526:	    j = st_index;
    #####:  527:	    off = offset;
    #####:  528:	    n_filetypes = st_n_filetypes;
    #####:  529:	    fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
    #####:  530:	    while (i < bufsize) {
    #####:  531:                if (fwr_size) { 
        -:  532:                    /* TYPE_UB and TYPE_LB can result in 
        -:  533:                       fwr_size = 0. save system call in such cases */ 
        -:  534:		    /* lseek(fd->fd_sys, off, SEEK_SET);
        -:  535:		    err = write(fd->fd_sys, ((char *) buf) + i, fwr_size);*/
        -:  536:
    #####:  537:		    req_off = off;
    #####:  538:		    req_len = fwr_size;
    #####:  539:		    userbuf_off = i;
    #####:  540:		    ADIOI_BUFFERED_WRITE
        -:  541:		}
    #####:  542:		i += fwr_size;
        -:  543:
    #####:  544:                if (off + fwr_size < disp + flat_file->indices[j] +
        -:  545:                   flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
    #####:  546:                       off += fwr_size;
        -:  547:                /* did not reach end of contiguous block in filetype.
        -:  548:                   no more I/O needed. off is incremented by fwr_size. */
        -:  549:                else {
    #####:  550:                    j = (j+1) % flat_file->count;
    #####:  551:                    n_filetypes += (j == 0) ? 1 : 0;
    #####:  552:                    while (flat_file->blocklens[j]==0) {
    #####:  553:                        j = (j+1) % flat_file->count;
    #####:  554:                        n_filetypes += (j == 0) ? 1 : 0;
        -:  555:                    }
    #####:  556:		    off = disp + flat_file->indices[j] + 
        -:  557:                                      (ADIO_Offset) n_filetypes*filetype_extent;
    #####:  558:		    fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
        -:  559:		}
        -:  560:	    }
        -:  561:	}
        -:  562:	else {
        -:  563:/* noncontiguous in memory as well as in file */
        -:  564:
    #####:  565:	    ADIOI_Flatten_datatype(datatype);
    #####:  566:	    flat_buf = ADIOI_Flatlist;
    #####:  567:	    while (flat_buf->type != datatype) flat_buf = flat_buf->next;
        -:  568:
    #####:  569:	    k = num = buf_count = 0;
    #####:  570:	    i = (int) (flat_buf->indices[0]);
    #####:  571:	    j = st_index;
    #####:  572:	    off = offset;
    #####:  573:	    n_filetypes = st_n_filetypes;
    #####:  574:	    fwr_size = st_fwr_size;
    #####:  575:	    bwr_size = flat_buf->blocklens[0];
        -:  576:
    #####:  577:	    while (num < bufsize) {
    #####:  578:		size = ADIOI_MIN(fwr_size, bwr_size);
    #####:  579:		if (size) {
        -:  580:		    /* lseek(fd->fd_sys, off, SEEK_SET);
        -:  581:		    err = write(fd->fd_sys, ((char *) buf) + i, size); */
        -:  582:
    #####:  583:		    req_off = off;
    #####:  584:		    req_len = size;
    #####:  585:		    userbuf_off = i;
    #####:  586:		    ADIOI_BUFFERED_WRITE
        -:  587:		}
        -:  588:
    #####:  589:		new_fwr_size = fwr_size;
    #####:  590:		new_bwr_size = bwr_size;
        -:  591:
    #####:  592:		if (size == fwr_size) {
        -:  593:/* reached end of contiguous block in file */
    #####:  594:                   j = (j+1) % flat_file->count;
    #####:  595:                   n_filetypes += (j == 0) ? 1 : 0;
    #####:  596:                   while (flat_file->blocklens[j]==0) {
    #####:  597:                       j = (j+1) % flat_file->count;
    #####:  598:                       n_filetypes += (j == 0) ? 1 : 0;
        -:  599:		    }
        -:  600:
    #####:  601:		    off = disp + flat_file->indices[j] + 
        -:  602:                                  (ADIO_Offset) n_filetypes*filetype_extent;
        -:  603:
    #####:  604:		    new_fwr_size = flat_file->blocklens[j];
    #####:  605:		    if (size != bwr_size) {
    #####:  606:			i += size;
    #####:  607:			new_bwr_size -= size;
        -:  608:		    }
        -:  609:		}
        -:  610:
    #####:  611:		if (size == bwr_size) {
        -:  612:/* reached end of contiguous block in memory */
        -:  613:
    #####:  614:		    k = (k + 1)%flat_buf->count;
    #####:  615:		    buf_count++;
    #####:  616:		    i = (int) (buftype_extent*(buf_count/flat_buf->count) +
        -:  617:			flat_buf->indices[k]); 
    #####:  618:		    new_bwr_size = flat_buf->blocklens[k];
    #####:  619:		    if (size != fwr_size) {
    #####:  620:			off += size;
    #####:  621:			new_fwr_size -= size;
        -:  622:		    }
        -:  623:		}
    #####:  624:		num += size;
    #####:  625:		fwr_size = new_fwr_size;
    #####:  626:                bwr_size = new_bwr_size;
        -:  627:	    }
        -:  628:	}
        -:  629:
        -:  630:        /* write the buffer out finally */	
        -:  631:#ifdef ADIOI_MPE_LOGGING
        -:  632:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:  633:#endif
    #####:  634:	lseek(fd->fd_sys, writebuf_off, SEEK_SET); 
        -:  635:#ifdef ADIOI_MPE_LOGGING
        -:  636:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:  637:#endif
    #####:  638:	if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
        -:  639:#ifdef ADIOI_MPE_LOGGING
        -:  640:        MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
        -:  641:#endif
    #####:  642:	err = write(fd->fd_sys, writebuf, writebuf_len); 
        -:  643:#ifdef ADIOI_MPE_LOGGING
        -:  644:        MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
        -:  645:#endif
        -:  646:
    #####:  647:        if (!(fd->atomicity))
    #####:  648:	    ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
    #####:  649:	else ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  650:
    #####:  651:        if (err == -1) err_flag = 1; 
        -:  652:
    #####:  653:	ADIOI_Free(writebuf); /* malloced in the buffered_write macro */
        -:  654:
    #####:  655:	if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
    #####:  656:	if (err_flag) {
    #####:  657:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS,
        -:  658:					       MPIR_ERR_RECOVERABLE, myname,
        -:  659:					       __LINE__, MPI_ERR_IO, "**io",
        -:  660:					       "**io %s", strerror(errno));
        -:  661:	}
    #####:  662:	else *error_code = MPI_SUCCESS;
        -:  663:    }
        -:  664:
    #####:  665:    fd->fp_sys_posn = -1;   /* set it to null. */
        -:  666:
        -:  667:#ifdef HAVE_STATUS_SET_BYTES
    #####:  668:    MPIR_Status_set_bytes(status, datatype, bufsize);
        -:  669:/* This is a temporary way of filling in status. The right way is to 
        -:  670:   keep track of how much data was actually written by ADIOI_BUFFERED_WRITE. */
        -:  671:#endif
        -:  672:
    #####:  673:    if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
        -:  674:}