00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ad_piofs.h"
00010 #include "adio_extern.h"
00011
00012 void ADIOI_PIOFS_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code)
00013 {
00014 MPI_Datatype copy_etype, copy_filetype;
00015 int combiner, i, j, k, filetype_is_contig, ntimes, err;
00016 ADIOI_Flatlist_node *flat_file;
00017 ADIO_Offset curr_fsize, alloc_size, size, len, done;
00018 ADIO_Status status;
00019 char *buf;
00020 piofs_change_view_t *piofs_change_view;
00021 #ifndef PRINT_ERR_MSG
00022 static char myname[] = "ADIOI_PIOFS_FCNTL";
00023 #endif
00024
00025 switch(flag) {
00026 case ADIO_FCNTL_SET_VIEW:
00027
00028
00029
00030 MPI_Type_get_envelope(fd->etype, &i, &j, &k, &combiner);
00031 if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->etype));
00032
00033 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00034 if (!filetype_is_contig) ADIOI_Delete_flattened(fd->filetype);
00035
00036 MPI_Type_get_envelope(fd->filetype, &i, &j, &k, &combiner);
00037 if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->filetype));
00038
00039
00040 ADIO_SetInfo(fd, fcntl_struct->info, &err);
00041
00042
00043
00044 MPI_Type_get_envelope(fcntl_struct->etype, &i, &j, &k, &combiner);
00045 if (combiner == MPI_COMBINER_NAMED) fd->etype = fcntl_struct->etype;
00046 else {
00047 MPI_Type_contiguous(1, fcntl_struct->etype, ©_etype);
00048 MPI_Type_commit(©_etype);
00049 fd->etype = copy_etype;
00050 }
00051 MPI_Type_get_envelope(fcntl_struct->filetype, &i, &j, &k, &combiner);
00052 if (combiner == MPI_COMBINER_NAMED)
00053 fd->filetype = fcntl_struct->filetype;
00054 else {
00055 MPI_Type_contiguous(1, fcntl_struct->filetype, ©_filetype);
00056 MPI_Type_commit(©_filetype);
00057 fd->filetype = copy_filetype;
00058 ADIOI_Flatten_datatype(fd->filetype);
00059
00060
00061 }
00062
00063 MPI_Type_size(fd->etype, &(fd->etype_size));
00064 fd->disp = fcntl_struct->disp;
00065
00066
00067
00068
00069 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00070 if (filetype_is_contig) fd->fp_ind = fcntl_struct->disp;
00071 else {
00072 flat_file = ADIOI_Flatlist;
00073 while (flat_file->type != fd->filetype)
00074 flat_file = flat_file->next;
00075 for (i=0; i<flat_file->count; i++) {
00076 if (flat_file->blocklens[i]) {
00077 fd->fp_ind = fcntl_struct->disp + flat_file->indices[i];
00078 break;
00079 }
00080 }
00081 }
00082 *error_code = MPI_SUCCESS;
00083 break;
00084
00085 case ADIO_FCNTL_GET_FSIZE:
00086 fcntl_struct->fsize = llseek(fd->fd_sys, 0, SEEK_END);
00087 if (fd->fp_sys_posn != -1)
00088 llseek(fd->fd_sys, fd->fp_sys_posn, SEEK_SET);
00089 #ifdef PRINT_ERR_MSG
00090 *error_code = (fcntl_struct->fsize == -1) ? MPI_ERR_UNKNOWN : MPI_SUCCESS;
00091 #else
00092 if (fcntl_struct->fsize == -1) {
00093 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00094 myname, "I/O Error", "%s", strerror(errno));
00095 ADIOI_Error(fd, *error_code, myname);
00096 }
00097 else *error_code = MPI_SUCCESS;
00098 #endif
00099 break;
00100
00101 case ADIO_FCNTL_SET_DISKSPACE:
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 curr_fsize = llseek(fd->fd_sys, 0, SEEK_END);
00112 alloc_size = fcntl_struct->diskspace;
00113
00114 size = ADIOI_MIN(curr_fsize, alloc_size);
00115
00116 ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
00117 buf = (char *) ADIOI_Malloc(ADIOI_PREALLOC_BUFSZ);
00118 done = 0;
00119
00120 for (i=0; i<ntimes; i++) {
00121 len = ADIOI_MIN(size-done, ADIOI_PREALLOC_BUFSZ);
00122 ADIO_ReadContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, done,
00123 &status, error_code);
00124 if (*error_code != MPI_SUCCESS) {
00125 #ifdef PRINT_ERR_MSG
00126 FPRINTF(stderr, "ADIOI_PIOFS_Fcntl: To preallocate disk space, ROMIO needs to read the file and write it back, but is unable to read the file. Please give the file read permission and open it with MPI_MODE_RDWR.\n");
00127 MPI_Abort(MPI_COMM_WORLD, 1);
00128 #else
00129 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_PREALLOC_PERM,
00130 myname, (char *) 0, (char *) 0);
00131 ADIOI_Error(fd, *error_code, myname);
00132 return;
00133 #endif
00134 }
00135 ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, done,
00136 &status, error_code);
00137 if (*error_code != MPI_SUCCESS) return;
00138 done += len;
00139 }
00140
00141 if (alloc_size > curr_fsize) {
00142 memset(buf, 0, ADIOI_PREALLOC_BUFSZ);
00143 size = alloc_size - curr_fsize;
00144 ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
00145 for (i=0; i<ntimes; i++) {
00146 len = ADIOI_MIN(alloc_size-done, ADIOI_PREALLOC_BUFSZ);
00147 ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00148 done, &status, error_code);
00149 if (*error_code != MPI_SUCCESS) return;
00150 done += len;
00151 }
00152 }
00153 ADIOI_Free(buf);
00154 if (fd->fp_sys_posn != -1)
00155 llseek(fd->fd_sys, fd->fp_sys_posn, SEEK_SET);
00156 *error_code = MPI_SUCCESS;
00157 break;
00158
00159 case ADIO_FCNTL_SET_IOMODE:
00160
00161
00162 if (fd->iomode != fcntl_struct->iomode) {
00163 fd->iomode = fcntl_struct->iomode;
00164 MPI_Barrier(MPI_COMM_WORLD);
00165 }
00166 *error_code = MPI_SUCCESS;
00167 break;
00168
00169 case ADIO_FCNTL_SET_ATOMICITY:
00170 piofs_change_view = (piofs_change_view_t *)
00171 ADIOI_Malloc(sizeof(piofs_change_view_t));
00172 piofs_change_view->Vbs = piofs_change_view->Vn =
00173 piofs_change_view->Hbs = piofs_change_view->Hn = 1;
00174 piofs_change_view->subfile = 0;
00175 piofs_change_view->flags = (fcntl_struct->atomicity == 0)
00176 ? (ACTIVE | NORMAL) : (ACTIVE | CAUTIOUS);
00177 err = piofsioctl(fd->fd_sys, PIOFS_CHANGE_VIEW, piofs_change_view);
00178 ADIOI_Free(piofs_change_view);
00179 fd->atomicity = (fcntl_struct->atomicity == 0) ? 0 : 1;
00180 #ifdef PRINT_ERR_MSG
00181 *error_code = (err == 0) ? MPI_SUCCESS : MPI_ERR_UNKNOWN;
00182 #else
00183 if (err == -1) {
00184 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00185 myname, "I/O Error", "%s", strerror(errno));
00186 ADIOI_Error(fd, *error_code, myname);
00187 }
00188 else *error_code = MPI_SUCCESS;
00189 #endif
00190 break;
00191
00192 default:
00193 FPRINTF(stderr, "Unknown flag passed to ADIOI_PIOFS_Fcntl\n");
00194 MPI_Abort(MPI_COMM_WORLD, 1);
00195 }
00196 }