00001
00002
00003
00004
00005
00006
00007
00008 #include "ad_xfs.h"
00009
00010 #ifdef HAVE_MALLOC_H
00011 #include <malloc.h>
00012 #endif
00013
00014
00015
00016 static int ADIOI_XFS_Aligned_Mem_File_Write(ADIO_File fd, void *buf,
00017 ADIO_Offset len, ADIO_Offset offset);
00018
00019 void ADIOI_XFS_WriteContig(ADIO_File fd, void *buf, int count,
00020 MPI_Datatype datatype, int file_ptr_type,
00021 ADIO_Offset offset, ADIO_Status *status, int *error_code)
00022 {
00023 int err=-1, datatype_size, diff, size;
00024 ssize_t len;
00025 void *newbuf;
00026 static char myname[] = "ADIOI_XFS_WRITECONTIG";
00027
00028 MPI_Type_size(datatype, &datatype_size);
00029 len = datatype_size * count;
00030
00031 fd->fp_sys_posn = -1;
00032
00033 if (file_ptr_type == ADIO_INDIVIDUAL) offset = fd->fp_ind;
00034
00035 if (!(fd->direct_write)) {
00036 err = pwrite(fd->fd_sys, buf, len, offset);
00037 if (err < 0) {goto leaving;}
00038 } else {
00039
00040
00041
00042
00043
00044 if (!(((long) buf) % fd->d_mem) && !(offset % fd->d_miniosz)) {
00045 err = ADIOI_XFS_Aligned_Mem_File_Write(fd, buf, len, offset);
00046 if (err < 0) {goto leaving;}
00047
00048
00049
00050
00051
00052 } else if (offset % fd->d_miniosz) {
00053 diff = fd->d_miniosz - (offset % fd->d_miniosz);
00054 diff = ADIOI_MIN(diff, len);
00055 err = pwrite(fd->fd_sys, buf, diff, offset);
00056 if (err < 0) {goto leaving;}
00057
00058 buf = ((char *) buf) + diff;
00059 offset += diff;
00060 size = len - diff;
00061 if (!(((long) buf) % fd->d_mem)) {
00062 err = ADIOI_XFS_Aligned_Mem_File_Write(fd, buf, size, offset);
00063 if (err < 0) {goto leaving;}
00064 }
00065 else {
00066 newbuf = (void *) memalign(XFS_MEMALIGN, size);
00067 if (newbuf) {
00068 memcpy(newbuf, buf, size);
00069 err = ADIOI_XFS_Aligned_Mem_File_Write(fd, newbuf, size, offset);
00070 ADIOI_Free(newbuf);
00071 if (err < 0) {goto leaving;}
00072 } else {
00073 err = pwrite(fd->fd_sys, buf, size, offset);
00074 if (err < 0) {goto leaving;}
00075 }
00076 }
00077 }
00078
00079
00080
00081 else {
00082 newbuf = (void *) memalign(XFS_MEMALIGN, len);
00083 if (newbuf) {
00084 memcpy(newbuf, buf, len);
00085 err = ADIOI_XFS_Aligned_Mem_File_Write(fd, newbuf, len, offset);
00086 ADIOI_Free(newbuf);
00087 } else {
00088 err = pwrite(fd->fd_sys, buf, len, offset);
00089 }
00090
00091 if (err < 0) {goto leaving;}
00092 }
00093 }
00094
00095 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind += len;
00096
00097 #ifdef HAVE_STATUS_SET_BYTES
00098 if (err != -1) MPIR_Status_set_bytes(status, datatype, len);
00099 #endif
00100 leaving:
00101 if (err == -1) {
00102 *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00103 myname, __LINE__, MPI_ERR_IO, "**io",
00104 "**io %s", strerror(errno));
00105 }
00106 else *error_code = MPI_SUCCESS;
00107 }
00108
00109
00110 static int
00111 ADIOI_XFS_Aligned_Mem_File_Write(ADIO_File fd, void *buf, ADIO_Offset len,
00112 ADIO_Offset offset)
00113 {
00114 unsigned write_chunk_sz = fd->hints->fs_hints.xfs.write_chunk_sz;
00115 ADIO_Offset nbytes, rem, newrem, size;
00116 int ntimes, i;
00117
00118
00119
00120
00121
00122
00123 if (!(len % fd->d_miniosz) &&
00124 (len >= fd->d_miniosz) && (len <= write_chunk_sz)) {
00125 nbytes = pwrite(fd->fd_direct, buf, len, offset);
00126 if (nbytes < 0) {return -1;}
00127 } else if (len < fd->d_miniosz) {
00128 nbytes = pwrite(fd->fd_sys, buf, len, offset);
00129 if (nbytes < 0) {return -1;}
00130 } else if (len > write_chunk_sz) {
00131 ntimes = len/(write_chunk_sz);
00132 rem = len - ntimes * write_chunk_sz;
00133 nbytes = 0;
00134 for (i=0; i<ntimes; i++) {
00135 nbytes = pwrite(fd->fd_direct, ((char *)buf) + i * write_chunk_sz,
00136 write_chunk_sz, offset);
00137 offset += write_chunk_sz;
00138 if (nbytes < 0) {return -1;}
00139 }
00140 if (rem) {
00141 if (!(rem % fd->d_miniosz)) {
00142 nbytes = pwrite(fd->fd_direct,
00143 ((char *)buf) + ntimes * write_chunk_sz, rem, offset);
00144 if (nbytes < 0) {return -1;}
00145 } else {
00146 newrem = rem % fd->d_miniosz;
00147 size = rem - newrem;
00148 if (size) {
00149 nbytes = pwrite(fd->fd_direct,
00150 ((char *)buf) + ntimes * write_chunk_sz, size, offset);
00151 offset += size;
00152 if (nbytes < 0) {return -1;}
00153 }
00154 nbytes = pwrite(fd->fd_sys,
00155 ((char *)buf) + ntimes * write_chunk_sz + size, newrem, offset);
00156 if (nbytes < 0) {return -1;}
00157 }
00158 }
00159 }
00160 else {
00161 rem = len % fd->d_miniosz;
00162 size = len - rem;
00163 nbytes = pwrite(fd->fd_direct, buf, size, offset);
00164 if (nbytes < 0) {return -1;}
00165 nbytes = pwrite(fd->fd_sys, (char *)buf + size, rem, offset+size);
00166 if (nbytes < 0) {return -1;}
00167 }
00168
00169 return 0;
00170 }