root/ompi/mca/io/romio321/romio/adio/ad_xfs/ad_xfs_write.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_XFS_WriteContig
  2. ADIOI_XFS_Aligned_Mem_File_Write

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *
   4  *   Copyright (C) 1997 University of Chicago. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include "ad_xfs.h"
   9 
  10 #ifdef HAVE_MALLOC_H
  11 #include <malloc.h>
  12 #endif
  13 
  14 /* style: allow:free:2 sig:0 */
  15 
  16 static int ADIOI_XFS_Aligned_Mem_File_Write(ADIO_File fd, void *buf,
  17                                                   ADIO_Offset len, ADIO_Offset offset);
  18 
  19 void ADIOI_XFS_WriteContig(ADIO_File fd, void *buf, int count, 
  20                      MPI_Datatype datatype, int file_ptr_type,
  21                      ADIO_Offset offset, ADIO_Status *status, int *error_code)
  22 {
  23     int diff, size;
  24     MPI_Count err=-1, datatype_size;
  25     ssize_t len;
  26     void *newbuf;
  27     static char myname[] = "ADIOI_XFS_WRITECONTIG";
  28 
  29     MPI_Type_size_x(datatype, &datatype_size);
  30     len = datatype_size * count;
  31 
  32     fd->fp_sys_posn = -1; /* set it to null, since we are using pwrite */
  33 
  34     if (file_ptr_type == ADIO_INDIVIDUAL) offset = fd->fp_ind;
  35 
  36     if (!(fd->direct_write)) {    /* direct I/O not enabled */
  37         err = pwrite(fd->fd_sys, buf, len, offset);
  38         if (err < 0) {goto leaving;}
  39     } else {       /* direct I/O enabled */
  40 
  41         /* (1) if mem_aligned && file_aligned 
  42                     use direct I/O to write up to correct io_size
  43                     use buffered I/O for remaining  */
  44 
  45         if (!(((long) buf) % fd->d_mem) && !(offset % fd->d_miniosz)) {
  46             err = ADIOI_XFS_Aligned_Mem_File_Write(fd, buf, len, offset);
  47             if (err < 0) {goto leaving;}
  48 
  49         /* (2) if !file_aligned
  50                     use buffered I/O to write up to file_aligned
  51                     At that point, if still mem_aligned, use (1)
  52                         else copy into aligned buf and then use (1) */
  53         } else if (offset % fd->d_miniosz) {
  54             diff = fd->d_miniosz - (offset % fd->d_miniosz);
  55             diff = ADIOI_MIN(diff, len);
  56             err = pwrite(fd->fd_sys, buf, diff, offset);
  57             if (err < 0) {goto leaving;}
  58 
  59             buf = ((char *) buf) + diff;
  60             offset += diff;
  61             size = len - diff;
  62             if (!(((long) buf) % fd->d_mem)) {
  63                 err = ADIOI_XFS_Aligned_Mem_File_Write(fd, buf, size, offset);
  64                 if (err < 0) {goto leaving;}
  65             }
  66             else {
  67                 newbuf = (void *) memalign(XFS_MEMALIGN, size);
  68                 if (newbuf) {
  69                     memcpy(newbuf, buf, size);
  70                     err = ADIOI_XFS_Aligned_Mem_File_Write(fd, newbuf, size, offset);
  71                     ADIOI_Free(newbuf);
  72                     if (err < 0) {goto leaving;}
  73                 } else {
  74                     err = pwrite(fd->fd_sys, buf, size, offset);
  75                     if (err < 0) {goto leaving;}
  76                 }
  77             }
  78         }
  79 
  80         /* (3) if !mem_aligned && file_aligned
  81                     copy into aligned buf, then use (1)  */
  82         else {
  83             newbuf = (void *) memalign(XFS_MEMALIGN, len);
  84             if (newbuf) {
  85                 memcpy(newbuf, buf, len);
  86                 err = ADIOI_XFS_Aligned_Mem_File_Write(fd, newbuf, len, offset);
  87                 ADIOI_Free(newbuf);
  88             } else {
  89                  err = pwrite(fd->fd_sys, buf, len, offset);
  90             }
  91 
  92             if (err < 0) {goto leaving;}
  93         }
  94     }
  95 
  96     if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind += len;
  97 
  98 #ifdef HAVE_STATUS_SET_BYTES
  99     if (err != -1) MPIR_Status_set_bytes(status, datatype, len);
 100 #endif
 101 leaving:
 102     if (err == -1) {
 103         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 104                                            myname, __LINE__, MPI_ERR_IO, "**io",
 105                                            "**io %s", strerror(errno));
 106     }
 107     else *error_code = MPI_SUCCESS;
 108 }
 109 
 110 
 111 static int
 112 ADIOI_XFS_Aligned_Mem_File_Write(ADIO_File fd, void *buf, ADIO_Offset len, 
 113               ADIO_Offset offset)
 114 {
 115     unsigned write_chunk_sz = fd->hints->fs_hints.xfs.write_chunk_sz;
 116     ADIO_Offset nbytes, rem, newrem, size;
 117     int ntimes, i;
 118 
 119     /* memory buffer is aligned, offset in file is aligned,
 120        io_size may or may not be of the right size.
 121        use direct I/O to write up to correct io_size,
 122        use buffered I/O for remaining. */
 123 
 124     if (!(len % fd->d_miniosz) && 
 125          (len >= fd->d_miniosz) && (len <= write_chunk_sz)) {
 126         nbytes = pwrite(fd->fd_direct, buf, len, offset);
 127         if (nbytes < 0) {return -1;}
 128     } else if (len < fd->d_miniosz) {
 129         nbytes = pwrite(fd->fd_sys, buf, len, offset);
 130         if (nbytes < 0) {return -1;}
 131     } else if (len > write_chunk_sz) {
 132         ntimes = len/(write_chunk_sz);
 133         rem = len - ntimes * write_chunk_sz;
 134         nbytes = 0;
 135         for (i=0; i<ntimes; i++) {
 136             nbytes = pwrite(fd->fd_direct, ((char *)buf) + i * write_chunk_sz,
 137                          write_chunk_sz, offset);
 138             offset += write_chunk_sz;
 139             if (nbytes < 0) {return -1;}
 140         }
 141         if (rem) {
 142             if (!(rem % fd->d_miniosz)) {
 143                 nbytes = pwrite(fd->fd_direct, 
 144                              ((char *)buf) + ntimes * write_chunk_sz, rem, offset);
 145                 if (nbytes < 0) {return -1;}
 146             } else {
 147                 newrem = rem % fd->d_miniosz;
 148                 size = rem - newrem;
 149                 if (size) {
 150                     nbytes = pwrite(fd->fd_direct, 
 151                             ((char *)buf) + ntimes * write_chunk_sz, size, offset);
 152                     offset += size;
 153                     if (nbytes < 0) {return -1;}
 154                 }
 155                 nbytes = pwrite(fd->fd_sys, 
 156                       ((char *)buf) + ntimes * write_chunk_sz + size, newrem, offset);
 157                 if (nbytes < 0) {return -1;}
 158             }
 159         }
 160     }
 161     else {
 162         rem = len % fd->d_miniosz;
 163         size = len - rem;
 164         nbytes = pwrite(fd->fd_direct, buf, size, offset);
 165         if (nbytes < 0) {return -1;}
 166         nbytes = pwrite(fd->fd_sys, (char *)buf + size, rem, offset+size);
 167         if (nbytes < 0) {return -1;}
 168     }
 169 
 170     return 0;
 171 }

/* [<][>][^][v][top][bottom][index][help] */