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