00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "ad_nfs.h"
00009 #include "adio_extern.h"
00010 
00011 void ADIOI_NFS_WriteContig(ADIO_File fd, void *buf, int count, 
00012                      MPI_Datatype datatype, int file_ptr_type,
00013              ADIO_Offset offset, ADIO_Status *status, int *error_code)
00014 {
00015     int err=-1, datatype_size, len;
00016     static char myname[] = "ADIOI_NFS_WRITECONTIG";
00017 
00018     MPI_Type_size(datatype, &datatype_size);
00019     len = datatype_size * count;
00020 
00021     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00022     if (fd->fp_sys_posn != offset) {
00023 #ifdef ADIOI_MPE_LOGGING
00024             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00025 #endif
00026         lseek(fd->fd_sys, offset, SEEK_SET);
00027 #ifdef ADIOI_MPE_LOGGING
00028             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00029 #endif
00030         }
00031     ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00032 #ifdef ADIOI_MPE_LOGGING
00033         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00034 #endif
00035     err = write(fd->fd_sys, buf, len);
00036 #ifdef ADIOI_MPE_LOGGING
00037         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00038 #endif
00039     ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00040     fd->fp_sys_posn = offset + err;
00041             
00042     }
00043     else { 
00044     offset = fd->fp_ind;
00045     if (fd->fp_sys_posn != fd->fp_ind) {
00046 #ifdef ADIOI_MPE_LOGGING
00047             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00048 #endif
00049         lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00050 #ifdef ADIOI_MPE_LOGGING
00051             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00052 #endif
00053         }
00054     ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00055 #ifdef ADIOI_MPE_LOGGING
00056         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00057 #endif
00058     err = write(fd->fd_sys, buf, len);
00059 #ifdef ADIOI_MPE_LOGGING
00060         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00061 #endif
00062     ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00063     fd->fp_ind += err;
00064     fd->fp_sys_posn = fd->fp_ind;
00065     }
00066 
00067     
00068     if (err == -1) {
00069     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00070                        myname, __LINE__, MPI_ERR_IO,
00071                        "**io",
00072                        "**io %s", strerror(errno));
00073     return;
00074     }
00075     
00076 
00077 #ifdef HAVE_STATUS_SET_BYTES
00078     MPIR_Status_set_bytes(status, datatype, err);
00079 #endif
00080 
00081     *error_code = MPI_SUCCESS;
00082 }
00083 
00084 
00085 
00086 
00087 #ifdef ADIOI_MPE_LOGGING
00088 #define ADIOI_BUFFERED_WRITE \
00089 { \
00090     if (req_off >= writebuf_off + writebuf_len) { \
00091         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
00092     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00093         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
00094         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
00095     err = write(fd->fd_sys, writebuf, writebuf_len); \
00096         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
00097         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00098         if (err == -1) err_flag = 1; \
00099     writebuf_off = req_off; \
00100         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00101     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00102         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
00103     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00104         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
00105         MPE_Log_event( ADIOI_MPE_read_a, 0, NULL ); \
00106     err = read(fd->fd_sys, writebuf, writebuf_len); \
00107         MPE_Log_event( ADIOI_MPE_read_b, 0, NULL ); \
00108         if (err == -1) { \
00109             *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
00110                            MPIR_ERR_RECOVERABLE, myname, \
00111                            __LINE__, MPI_ERR_IO, \
00112                            "**ioRMWrdwr", 0); \
00113         return; \
00114         } \
00115     } \
00116     write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00117     memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00118     while (write_sz != req_len) { \
00119         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
00120     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00121         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
00122         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
00123     err = write(fd->fd_sys, writebuf, writebuf_len); \
00124         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
00125         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00126         if (err == -1) err_flag = 1; \
00127         req_len -= write_sz; \
00128         userbuf_off += write_sz; \
00129         writebuf_off += writebuf_len; \
00130         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00131     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00132         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
00133     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00134         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
00135         MPE_Log_event( ADIOI_MPE_read_a, 0, NULL ); \
00136     err = read(fd->fd_sys, writebuf, writebuf_len); \
00137         MPE_Log_event( ADIOI_MPE_read_b, 0, NULL ); \
00138         if (err == -1) { \
00139         *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
00140                            MPIR_ERR_RECOVERABLE, myname, \
00141                            __LINE__, MPI_ERR_IO, \
00142                            "**ioRMWrdwr", 0); \
00143         return; \
00144         } \
00145         write_sz = ADIOI_MIN(req_len, writebuf_len); \
00146         memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00147     } \
00148 }
00149 #else
00150 #define ADIOI_BUFFERED_WRITE \
00151 { \
00152     if (req_off >= writebuf_off + writebuf_len) { \
00153     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00154     err = write(fd->fd_sys, writebuf, writebuf_len); \
00155         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00156         if (err == -1) err_flag = 1; \
00157     writebuf_off = req_off; \
00158         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00159     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00160     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00161     err = read(fd->fd_sys, writebuf, writebuf_len); \
00162         if (err == -1) { \
00163             *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
00164                            MPIR_ERR_RECOVERABLE, myname, \
00165                            __LINE__, MPI_ERR_IO, \
00166                            "**ioRMWrdwr", 0); \
00167         return; \
00168         } \
00169     } \
00170     write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00171     memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00172     while (write_sz != req_len) { \
00173     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00174     err = write(fd->fd_sys, writebuf, writebuf_len); \
00175         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00176         if (err == -1) err_flag = 1; \
00177         req_len -= write_sz; \
00178         userbuf_off += write_sz; \
00179         writebuf_off += writebuf_len; \
00180         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00181     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00182     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00183     err = read(fd->fd_sys, writebuf, writebuf_len); \
00184         if (err == -1) { \
00185         *error_code = MPIO_Err_create_code(MPI_SUCCESS, \
00186                            MPIR_ERR_RECOVERABLE, myname, \
00187                            __LINE__, MPI_ERR_IO, \
00188                            "**ioRMWrdwr", 0); \
00189         return; \
00190         } \
00191         write_sz = ADIOI_MIN(req_len, writebuf_len); \
00192         memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00193     } \
00194 }
00195 #endif
00196 
00197 
00198 
00199 #ifdef ADIOI_MPE_LOGGING
00200 #define ADIOI_BUFFERED_WRITE_WITHOUT_READ \
00201 { \
00202     if (req_off >= writebuf_off + writebuf_len) { \
00203         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
00204     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00205         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
00206     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00207         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
00208     err = write(fd->fd_sys, writebuf, writebuf_len); \
00209         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
00210         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00211         if (err == -1) err_flag = 1; \
00212     writebuf_off = req_off; \
00213         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00214     } \
00215     write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00216     memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00217     while (write_sz != req_len) { \
00218         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
00219     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00220         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
00221     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00222         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); \
00223     err = write(fd->fd_sys, writebuf, writebuf_len); \
00224         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); \
00225         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00226         if (err == -1) err_flag = 1; \
00227         req_len -= write_sz; \
00228         userbuf_off += write_sz; \
00229         writebuf_off += writebuf_len; \
00230         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00231         write_sz = ADIOI_MIN(req_len, writebuf_len); \
00232         memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00233     } \
00234 }
00235 #else
00236 #define ADIOI_BUFFERED_WRITE_WITHOUT_READ \
00237 { \
00238     if (req_off >= writebuf_off + writebuf_len) { \
00239     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00240     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00241     err = write(fd->fd_sys, writebuf, writebuf_len); \
00242         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00243         if (err == -1) err_flag = 1; \
00244     writebuf_off = req_off; \
00245         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00246     } \
00247     write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00248     memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00249     while (write_sz != req_len) { \
00250     lseek(fd->fd_sys, writebuf_off, SEEK_SET); \
00251     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00252     err = write(fd->fd_sys, writebuf, writebuf_len); \
00253         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00254         if (err == -1) err_flag = 1; \
00255         req_len -= write_sz; \
00256         userbuf_off += write_sz; \
00257         writebuf_off += writebuf_len; \
00258         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00259         write_sz = ADIOI_MIN(req_len, writebuf_len); \
00260         memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00261     } \
00262 }
00263 #endif
00264 
00265 
00266 void ADIOI_NFS_WriteStrided(ADIO_File fd, void *buf, int count,
00267                        MPI_Datatype datatype, int file_ptr_type,
00268                        ADIO_Offset offset, ADIO_Status *status, int
00269                        *error_code)
00270 {
00271 
00272 
00273     ADIOI_Flatlist_node *flat_buf, *flat_file;
00274     int i, j, k, err=-1, bwr_size, fwr_size=0, st_index=0;
00275     int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
00276     int n_filetypes, etype_in_filetype;
00277     ADIO_Offset abs_off_in_filetype=0;
00278     int filetype_size, etype_size, buftype_size, req_len;
00279     MPI_Aint filetype_extent, buftype_extent; 
00280     int buf_count, buftype_is_contig, filetype_is_contig;
00281     ADIO_Offset userbuf_off;
00282     ADIO_Offset off, req_off, disp, end_offset=0, writebuf_off, start_off;
00283     char *writebuf, *value;
00284     int st_fwr_size, st_n_filetypes, writebuf_len, write_sz;
00285     int new_bwr_size, new_fwr_size, err_flag=0, info_flag, max_bufsize;
00286     static char myname[] = "ADIOI_NFS_WRITESTRIDED";
00287 
00288     ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00289     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00290 
00291     MPI_Type_size(fd->filetype, &filetype_size);
00292     if ( ! filetype_size ) {
00293     *error_code = MPI_SUCCESS; 
00294     return;
00295     }
00296 
00297     MPI_Type_extent(fd->filetype, &filetype_extent);
00298     MPI_Type_size(datatype, &buftype_size);
00299     MPI_Type_extent(datatype, &buftype_extent);
00300     etype_size = fd->etype_size;
00301 
00302     bufsize = buftype_size * count;
00303 
00304 
00305 
00306     value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00307     ADIOI_Info_get(fd->info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, 
00308                  &info_flag);
00309     max_bufsize = atoi(value);
00310     ADIOI_Free(value);
00311 
00312     if (!buftype_is_contig && filetype_is_contig) {
00313 
00314 
00315 
00316     ADIOI_Flatten_datatype(datatype);
00317     flat_buf = CtvAccess(ADIOI_Flatlist);
00318     while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00319 
00320         off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : 
00321                  fd->disp + etype_size * offset;
00322 
00323         start_off = off;
00324     end_offset = off + bufsize - 1;
00325         writebuf_off = off;
00326         writebuf = (char *) ADIOI_Malloc(max_bufsize);
00327         writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));
00328 
00329 
00330         if (fd->atomicity) 
00331             ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00332 
00333         for (j=0; j<count; j++) 
00334             for (i=0; i<flat_buf->count; i++) {
00335                 userbuf_off = j*buftype_extent + flat_buf->indices[i];
00336         req_off = off;
00337         req_len = flat_buf->blocklens[i];
00338         ADIOI_BUFFERED_WRITE_WITHOUT_READ
00339                 off += flat_buf->blocklens[i];
00340             }
00341 
00342         
00343 #ifdef ADIOI_MPE_LOGGING
00344         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00345 #endif
00346     lseek(fd->fd_sys, writebuf_off, SEEK_SET); 
00347 #ifdef ADIOI_MPE_LOGGING
00348         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00349 #endif
00350     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00351 #ifdef ADIOI_MPE_LOGGING
00352         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00353 #endif
00354     err = write(fd->fd_sys, writebuf, writebuf_len); 
00355 #ifdef ADIOI_MPE_LOGGING
00356         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00357 #endif
00358         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00359         if (err == -1) err_flag = 1; 
00360 
00361         if (fd->atomicity) 
00362             ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00363 
00364     ADIOI_Free(writebuf); 
00365 
00366         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00367     if (err_flag) {
00368         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00369                            MPIR_ERR_RECOVERABLE, myname,
00370                            __LINE__, MPI_ERR_IO, "**io",
00371                            "**io %s", strerror(errno));
00372     }
00373     else *error_code = MPI_SUCCESS;
00374     }
00375 
00376     else {  
00377 
00378 
00379     flat_file = CtvAccess(ADIOI_Flatlist);
00380     while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00381     disp = fd->disp;
00382 
00383     if (file_ptr_type == ADIO_INDIVIDUAL) {
00384        
00385             offset       = fd->fp_ind - disp;
00386             n_filetypes  = (offset - flat_file->indices[0]) / filetype_extent;
00387             offset      -= (ADIO_Offset)n_filetypes * filetype_extent;
00388             
00389 
00390             
00391             for (i=0; i<flat_file->count; i++) {
00392                 ADIO_Offset dist;
00393                 if (flat_file->blocklens[i] == 0) continue;
00394                 dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
00395                 
00396                 if (dist == 0) {
00397                     i++;
00398                     offset   = flat_file->indices[i];
00399                     fwr_size = flat_file->blocklens[i];
00400                     break;
00401                 }
00402                 if (dist > 0) {
00403                     fwr_size = dist;
00404                     break;
00405                 }
00406             }
00407             st_index = i;  
00408             offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
00409         }
00410     else {
00411         n_etypes_in_filetype = filetype_size/etype_size;
00412         n_filetypes = (int) (offset / n_etypes_in_filetype);
00413         etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00414         size_in_filetype = etype_in_filetype * etype_size;
00415  
00416         sum = 0;
00417         for (i=0; i<flat_file->count; i++) {
00418         sum += flat_file->blocklens[i];
00419         if (sum > size_in_filetype) {
00420             st_index = i;
00421             fwr_size = sum - size_in_filetype;
00422             abs_off_in_filetype = flat_file->indices[i] +
00423             size_in_filetype - (sum - flat_file->blocklens[i]);
00424             break;
00425         }
00426         }
00427 
00428         
00429         offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + 
00430         abs_off_in_filetype;
00431     }
00432 
00433         start_off = offset;
00434        
00435        
00436 
00437         if (buftype_is_contig && bufsize <= fwr_size) {
00438             ADIO_WriteContig(fd, buf, bufsize, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00439                              offset, status, error_code);
00440 
00441            if (file_ptr_type == ADIO_INDIVIDUAL) {
00442                 
00443 
00444                 fd->fp_ind = offset + bufsize;
00445                 if (bufsize == fwr_size) {
00446                     do {
00447                         st_index++;
00448                         if (st_index == flat_file->count) {
00449                             st_index = 0;
00450                             n_filetypes++;
00451                         }
00452                     } while (flat_file->blocklens[st_index] == 0);
00453                     fd->fp_ind = disp + flat_file->indices[st_index]
00454                                + (ADIO_Offset)n_filetypes*filetype_extent;
00455                 }
00456             }
00457            fd->fp_sys_posn = -1;    
00458 #ifdef HAVE_STATUS_SET_BYTES
00459            MPIR_Status_set_bytes(status, datatype, bufsize);
00460 #endif 
00461             return;
00462         }
00463 
00464        
00465 
00466 
00467     st_fwr_size = fwr_size;
00468     st_n_filetypes = n_filetypes;
00469     i = 0;
00470     j = st_index;
00471     off = offset;
00472     fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
00473     while (i < bufsize) {
00474         i += fwr_size;
00475         end_offset = off + fwr_size - 1;
00476             j = (j+1) % flat_file->count;
00477             n_filetypes += (j == 0) ? 1 : 0;
00478             while (flat_file->blocklens[j]==0) {
00479                 j = (j+1) % flat_file->count;
00480                 n_filetypes += (j == 0) ? 1 : 0;
00481         }
00482 
00483         off = disp + flat_file->indices[j] + 
00484             (ADIO_Offset) n_filetypes*filetype_extent;
00485         fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00486     }
00487 
00488 
00489         if (fd->atomicity) 
00490             ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00491 
00492         
00493         writebuf_off = offset;
00494         writebuf = (char *) ADIOI_Malloc(max_bufsize);
00495         writebuf_len = (int)(ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));
00496     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00497 #ifdef ADIOI_MPE_LOGGING
00498         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00499 #endif
00500     lseek(fd->fd_sys, writebuf_off, SEEK_SET); 
00501 #ifdef ADIOI_MPE_LOGGING
00502         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00503 #endif
00504 #ifdef ADIOI_MPE_LOGGING
00505         MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
00506 #endif
00507     err = read(fd->fd_sys, writebuf, writebuf_len); 
00508 #ifdef ADIOI_MPE_LOGGING
00509         MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
00510 #endif
00511         if (err == -1) {
00512         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00513                            MPIR_ERR_RECOVERABLE,
00514                            myname, __LINE__,
00515                            MPI_ERR_IO,
00516                            "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);
00517         return;
00518         } 
00519 
00520     if (buftype_is_contig && !filetype_is_contig) {
00521 
00522 
00523 
00524 
00525         i = 0;
00526         j = st_index;
00527         off = offset;
00528         n_filetypes = st_n_filetypes;
00529         fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
00530         while (i < bufsize) {
00531                 if (fwr_size) { 
00532                     
00533  
00534             
00535 
00536 
00537             req_off = off;
00538             req_len = fwr_size;
00539             userbuf_off = i;
00540             ADIOI_BUFFERED_WRITE
00541         }
00542         i += fwr_size;
00543 
00544                 if (off + fwr_size < disp + flat_file->indices[j] +
00545                    flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
00546                        off += fwr_size;
00547                 
00548 
00549                 else {
00550                     j = (j+1) % flat_file->count;
00551                     n_filetypes += (j == 0) ? 1 : 0;
00552                     while (flat_file->blocklens[j]==0) {
00553                         j = (j+1) % flat_file->count;
00554                         n_filetypes += (j == 0) ? 1 : 0;
00555                     }
00556             off = disp + flat_file->indices[j] + 
00557                                       (ADIO_Offset) n_filetypes*filetype_extent;
00558             fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00559         }
00560         }
00561     }
00562     else {
00563 
00564 
00565         ADIOI_Flatten_datatype(datatype);
00566         flat_buf = CtvAccess(ADIOI_Flatlist);
00567         while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00568 
00569         k = num = buf_count = 0;
00570         i = (int) (flat_buf->indices[0]);
00571         j = st_index;
00572         off = offset;
00573         n_filetypes = st_n_filetypes;
00574         fwr_size = st_fwr_size;
00575         bwr_size = flat_buf->blocklens[0];
00576 
00577         while (num < bufsize) {
00578         size = ADIOI_MIN(fwr_size, bwr_size);
00579         if (size) {
00580             
00581 
00582 
00583             req_off = off;
00584             req_len = size;
00585             userbuf_off = i;
00586             ADIOI_BUFFERED_WRITE
00587         }
00588 
00589         new_fwr_size = fwr_size;
00590         new_bwr_size = bwr_size;
00591 
00592         if (size == fwr_size) {
00593 
00594                    j = (j+1) % flat_file->count;
00595                    n_filetypes += (j == 0) ? 1 : 0;
00596                    while (flat_file->blocklens[j]==0) {
00597                        j = (j+1) % flat_file->count;
00598                        n_filetypes += (j == 0) ? 1 : 0;
00599             }
00600 
00601             off = disp + flat_file->indices[j] + 
00602                                   (ADIO_Offset) n_filetypes*filetype_extent;
00603 
00604             new_fwr_size = flat_file->blocklens[j];
00605             if (size != bwr_size) {
00606             i += size;
00607             new_bwr_size -= size;
00608             }
00609         }
00610 
00611         if (size == bwr_size) {
00612 
00613 
00614             k = (k + 1)%flat_buf->count;
00615             buf_count++;
00616             i = (int) (buftype_extent*(buf_count/flat_buf->count) +
00617             flat_buf->indices[k]); 
00618             new_bwr_size = flat_buf->blocklens[k];
00619             if (size != fwr_size) {
00620             off += size;
00621             new_fwr_size -= size;
00622             }
00623         }
00624         num += size;
00625         fwr_size = new_fwr_size;
00626                 bwr_size = new_bwr_size;
00627         }
00628     }
00629 
00630           
00631 #ifdef ADIOI_MPE_LOGGING
00632         MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00633 #endif
00634     lseek(fd->fd_sys, writebuf_off, SEEK_SET); 
00635 #ifdef ADIOI_MPE_LOGGING
00636         MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00637 #endif
00638     if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00639 #ifdef ADIOI_MPE_LOGGING
00640         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00641 #endif
00642     err = write(fd->fd_sys, writebuf, writebuf_len); 
00643 #ifdef ADIOI_MPE_LOGGING
00644         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00645 #endif
00646 
00647         if (!(fd->atomicity))
00648         ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00649     else ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00650 
00651         if (err == -1) err_flag = 1; 
00652 
00653     ADIOI_Free(writebuf); 
00654 
00655     if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00656     if (err_flag) {
00657         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00658                            MPIR_ERR_RECOVERABLE, myname,
00659                            __LINE__, MPI_ERR_IO, "**io",
00660                            "**io %s", strerror(errno));
00661     }
00662     else *error_code = MPI_SUCCESS;
00663     }
00664 
00665     fd->fp_sys_posn = -1;   
00666 
00667 #ifdef HAVE_STATUS_SET_BYTES
00668     MPIR_Status_set_bytes(status, datatype, bufsize);
00669 
00670 
00671 #endif
00672 
00673     if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00674 }