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