_ffopen_t _sqb_open( const char *name, int flags, mode_t mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { _ffopen_t nextfio; long bs; int i,nb; int ret; struct sqb_f *sqb_info; struct sqbio *sqptr; union spec_u *nspec; struct ffc_info_s ffci; struct stat sysstat; struct ffsw dumstat; int isvalid; char *buf; /* * Allocate private storage */ sqb_info = (struct sqb_f *)calloc(sizeof(struct sqb_f), 1); if (sqb_info == NULL) { errno = FDC_ERR_NOMEM; goto errret; } fio->lyr_info = (char *)sqb_info; /* * Set flag if -m on is assigned. bufa layer handles -m on by * default. */ if (oinf->aip != NULL) { if (oinf->aip->m_multup_flg && oinf->aip->m_multup) { oinf->aip->m_multup_flg |= ATTR_USED; } } nspec = spec; NEXT_SPEC(nspec); nextfio = _ffopen(name, flags, mode, nspec, stat, cbits, cblks, NULL, oinf); if (nextfio == _FFOPEN_ERR) return(_FFOPEN_ERR); fio->fioptr = (struct fdinfo *)nextfio; ret = XRCALL(fio->fioptr, fcntlrtn) fio->fioptr, FC_GETINFO, &ffci, stat); if (ret < 0) { (void)XRCALL(fio->fioptr, closertn) fio->fioptr, &dumstat); free(sqb_info); return(_FFOPEN_ERR); }
/* * _evnt_open * * Open routine for "event" layer. * * Input: * name - name of file to open * oflags * mode * fio - ffio file descriptor * spec * stat - pointer to status return word * cbits * cblks * oinf * * Output: * Returns: pointer to fdinfo block from next lower layer on success. * -1 if an error occurred. */ _ffopen_t _evnt_open(const char *name, int oflags, mode_t mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { _ffopen_t nextfio; int ret; union spec_u *nspec; int status; struct evnt_f *evnt_info; struct stat fstat; int trc_file_number = 0; rtc_t start_rtc, finish_rtc; struct ffsw log_stat; int log_ubc = 0; #if !defined(__mips) && !defined(_LITTLE_ENDIAN) int end_open_link = _evnt_OPEN_LINK; #elif defined(__mips) struct dioattr dio; #endif int isvalid; static int evnt_atexit_called = FALSE; struct EVNT_FILE_TRACE *trace_file; /* * post atexit so we can call it to close our * diagnostic and trace files */ if (evnt_atexit_called == FALSE) { evnt_atexit_called = TRUE; atexit(_evnt_atexit); } fio->lyr_info = NULL; /* set to NULL for the benefit of _evnt_clfree */ evnt_info = (struct evnt_f *) calloc(1, sizeof(struct evnt_f)); if (evnt_info == NULL) goto nomem; fio->lyr_info = (char *) evnt_info; /* * set default layer options in envt_info */ evnt_info->optflags.diag = TRUE; /* default is full diagnostics*/ evnt_info->optflags.full_diag = TRUE; /* default is full diagnostics*/ evnt_info->optflags.summary = FALSE; evnt_info->optflags.brief = FALSE; evnt_info->optflags.trace = FALSE; evnt_info->optflags.rtc = RTC_MODE;/* use rtc by default */ evnt_info->optflags.k = FALSE; evnt_info->optflags.m = FALSE; evnt_info->optflags.g = FALSE; evnt_info->optflags.bytes = TRUE; /* default units */ evnt_info->optflags.words = FALSE; evnt_info->optflags.blocks = FALSE; evnt_info->do_zeros = TRUE; /* zero fill diag fields by default */ evnt_info->extend_trackers_failed = FALSE; /* * malloc space for async tracker structures */ if ((evnt_info->async_tracker = _evnt_add_trackers(NUM_TRACKERS)) == NULL) goto nomem; evnt_info->num_async_trackers = NUM_TRACKERS; /* * pick up user requested options - * get values from the FFIO spec */ _evnt_getopts(evnt_info, spec); /* * open diagnostics file */ if (evnt_info->optflags.diag == TRUE) { if(_evnt_open_log_file(evnt_info) == ERR) { goto badret; } else { if (_GL_ffio_logptr != NULL) _GL_evnt_logptr = _GL_ffio_logptr; else _GL_evnt_logptr = stderr; } } /* * open trace file if we're tracing */ #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace == TRUE) { trc_file_number = _ff_nparm_getv(spec, 1, &isvalid); /* * check for valid file number - issue message to stats file */ if (evnt_info->optflags.diag == TRUE && trc_file_number < 0 || trc_file_number > 9) { fprintf(_GL_evnt_logptr, "Invalid trace file number specified: %d. Valid numbers are 0-9.\n ffio.trace will be used\n", trc_file_number); trc_file_number = 0; } evnt_info->trc_file_number = trc_file_number; trace_file = &(_GL_evnt_trc_file[trc_file_number]); if (_evnt_open_trace_file(fio, name, evnt_info) == ERR) goto badret; } #endif #ifdef EVNT_DEBUG fprintf(stderr,"event layer options:\n"); fprintf(stderr, "diagnostics: diag = %d, full_diag = %d, summary = %d, brief = %d\n", evnt_info->optflags.diag, evnt_info->optflags.full_diag, evnt_info->optflags.summary, evnt_info->optflags.brief); fprintf(stderr,"tracing: trace = %d\n", evnt_info->optflags.trace); fprintf(stderr,"trc_file_number = %d\n", trc_file_number); fprintf(stderr,"clock: rtc = %d\n", evnt_info->optflags.rtc); fprintf(stderr,"units: bytes = %d, words = %d, blocks = %d\n", evnt_info->optflags.bytes, evnt_info->optflags.words, evnt_info->optflags.blocks); fprintf(stderr,"size: k = %d, m = %d, g = %d\n", evnt_info->optflags.k, evnt_info->optflags.m, evnt_info->optflags.g); #endif /* * initialize minimums to large values for diagnostics */ if (evnt_info->optflags.diag) { long bigmin; if (sizeof(size_t) == sizeof(long)){ bigmin = LONG_MAX; } else { bigmin = INT_MAX; } evnt_info->listio_write.min = bigmin; evnt_info->listio_writea.min = bigmin; evnt_info->listio_read.min = bigmin; evnt_info->listio_reada.min = bigmin; evnt_info->write.min = bigmin; evnt_info->writea.min = bigmin; evnt_info->read.min = bigmin; evnt_info->reada.min = bigmin; strncpy(evnt_info->name, name, NAMLEN); } /* * Get the FFIO spec for the next lower layer. */ nspec = spec; NEXT_SPEC(nspec); /* * Open the layers below this one. */ #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace == TRUE) trace_file->open_level_count++; #endif start_rtc = RTC(); nextfio = _ffopen(name, oflags, mode, nspec, stat, cbits, cblks, NULL, oinf); finish_rtc = RTC(); #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace == TRUE) trace_file->open_level_count--; #endif evnt_info->open_time = finish_rtc - start_rtc; if (nextfio == _FFOPEN_ERR) goto badret; if (1) { struct fdinfo *nfioptr; nfioptr = (struct fdinfo *) nextfio; ret = XRCALL(nfioptr, fcntlrtn) nfioptr, FC_STAT, &fstat, stat); if (oflags & O_TRUNC) evnt_info->cur_size = 0; else evnt_info->cur_size = fstat.st_size; if (oflags & O_APPEND) evnt_info->cur_pos = evnt_info->cur_size; else evnt_info->cur_pos = 0; #ifdef __mips ret = XRCALL(nfioptr, fcntlrtn) nfioptr, FC_DIOINFO, &dio, stat); if (ret == ERR)evnt_info->odirect = 0; else { evnt_info->odirect = 1; evnt_info->miniosize = dio.d_miniosz; evnt_info->chunksize = dio.d_miniosz; evnt_info->diskalign = dio.d_miniosz; evnt_info->maxiosize = dio.d_maxiosz; evnt_info->memalign = dio.d_mem; } #endif evnt_info->max_size = evnt_info->cur_size; evnt_info->oflags = oflags; evnt_info->cbits = cbits; evnt_info->cblks = cblks; #ifdef DO_WE_WANT_FAKE_SDS if (get out of * oinf) { evnt_info->fake_sds = TRUE; evnt_info->sector_mask = 4095; } else { evnt_info->fake_sds = FALSE; evnt_info->sector_mask = fstat.st_blksize - 1; } #endif /* we're not monitoring ssreads yet */ evnt_info->fake_sds = FALSE; evnt_info->sector_mask = fstat.st_blksize - 1; } /* * write some initial information to the trace file */ #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace) { if (trace_file->ptr) { struct evnt_open_info *open_info; int next_open_link; open_info = &(evnt_info->open_info); evnt_info->fd = (trace_file->file_info.open_count) << 48; open_info->fd = _evnt_OPEN | evnt_info->fd; open_info->oflags = oflags; open_info->mode = mode; strncpy(open_info->name, name, 80); open_info->name[79] = 0; open_info->open_size = evnt_info->cur_size; open_info->rtc_14 = RTC(); open_info->rtc_15 = RTC(); open_info->nextfio = nextfio; strcpy(open_info->parent_child, "??? <-> ???"); open_info->next_open_pos = 'UNUSED'; open_info->max_size = evnt_info->max_size; open_info->close_rtc = 0; open_info->event_count = 0; open_info->start_rtc = start_rtc; open_info->finish_rtc = finish_rtc; open_info->d_nextfio = nextfio; next_open_link = EVNT_XR_TELL(); evnt_info->open_pos = next_open_link + 8; if (trace_file->program_info.open_count == 0) trace_file->program_info.first_open_pos = next_open_link; if (trace_file->file_info.open_count == 0) { trace_file->file_info.first_open_pos = next_open_link; } else { long link_word; status = EVNT_XR_SEEK(trace_file->file_info.last_open_link, SEEK_SET); link_word = _evnt_OPEN_LINK | next_open_link; status = EVNT_XR_WRITE(&link_word, 8, 1); status = EVNT_XR_SEEK(0, SEEK_END); } trace_file->file_info.last_open_link = next_open_link; status = EVNT_XR_WRITE(&end_open_link, 1, sizeof(int)); status = EVNT_XR_WRITE(open_info, 1, sizeof(struct evnt_open_info)); } evnt_info->logged_count = &(_GL_evnt_trc_file[evnt_info->trc_file_number].program_info.event_count); trace_file->file_info.open_count++; trace_file->program_info.open_count++; EVNT_TRACE_SIZE; INC_GLOBAL_LOG_COUNT(open); _evnt_trace_flush(fio, evnt_info); evnt_info->need_parent_child = TRUE; } #endif evnt_info->counts.size_changes = 0; evnt_info->counts.open = 1; evnt_info->counts.total = 1; return (nextfio); nomem: badret: _evnt_clfree(fio); return (_FFOPEN_ERR); }
int _cdc_open( const char *name, int flags, int mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { int nextfio = 0; int ll_blocked; char *ptr; union spec_u *nspec; int recsize, blksize; struct ffsw *dumstat; struct cdc_f *cdc_info; recsize = 0; /* this is ignored */ /* * Blocksize is 512 60 bit words, or 5120 6-bit characters */ blksize = 5120*6; /* other block sizes not allowed */ /* * Internally, both blksize and recsize are in bits! */ switch(spec->fld.recfmt) { case TR_CDC_CZ: fio->maxrecsize = recsize; break; case TR_CDC_CS: case TR_CDC_IW: case TR_CDC_CW: fio->maxrecsize = -1; break; } fio->maxblksize = blksize; /* * Allocate buffer: * block size plus possible 48 bit block terminator plus one 60-bit word * plus 16 slop bytes. */ fio->_ffbufsiz = blksize + 48 + 64 + 64 + 7; /* bufsiz in bytes + fudge */ ptr = malloc((fio->_ffbufsiz >> 3) + 16); if (ptr == NULL) goto nomem; /* * Allocate private storage area */ cdc_info = (struct cdc_f *)calloc(sizeof(struct cdc_f), 1); if (cdc_info == NULL) goto nomem; fio->lyr_info = (char *)cdc_info; SET_BPTR(fio->_base, CPTR2BP(ptr)); fio->rwflag = POSITIN; fio->segbits = 0; fio->_cnt = 0; fio->_ptr = fio->_base; /* * Now, open the lower layers... */ nspec = spec; NEXT_SPEC(nspec); nextfio = _ffopen(name, flags, mode, nspec, stat, cbits, cblks, NULL, oinf); if (nextfio < 0) goto badret; fio->fioptr = (struct fdinfo *)nextfio; XRCALL(fio->fioptr, fcntlrtn) fio->fioptr, FC_GETINFO, &cdc_info->ffci, &dumstat); ll_blocked = cdc_info->ffci.ffc_flags & FFC_REC; switch(fio->subtype) { case TR_CDC_BT_DISK: break; /* either record or stream is OK */ case TR_CDC_BT_SI: case TR_CDC_BT_I: if (ll_blocked == 0) /* if not blocked */ { _SETERROR(stat, FDC_ERR_NOBDRY, 0); goto badret; } break; } DUMP_IOB(fio); /* debugging only */ return(nextfio); nomem: _SETERROR(stat, FDC_ERR_NOMEM, 0); badret: if (nextfio > 0) XRCALL(fio->fioptr, closertn) fio->fioptr, &dumstat); if (BPTR2CP(fio->_base) != NULL) free(BPTR2CP(fio->_base)); if (fio->lyr_info != NULL) free(fio->lyr_info); return(ERR); }
int _sds_open( const char *name, int flags, int mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { char *ptr; int nextfio; int bs, ret; long mininc; struct fdinfo *nfioptr; union spec_u *nspec; struct sds_f *sds_info; struct ffsw clstat; struct stat statbuf; /* * Allocate private storage */ sds_info = (struct sds_f *) calloc(sizeof(struct sds_f),1); if (sds_info == NULL) goto nomem; fio->lyr_info = (char *)sds_info; sds_info->bdfd = -1; /* also used as a flag */ sds_info->name = strdup(name); if (sds_info->name == NULL) goto badret; /* * Internally, both blksize and recsize are in bits! */ bs = 4096 * 8; /* one sector buffer */ fio->_ffbufsiz = bs; /* bit size of buffer, 1 sector */ ptr = malloc((bs >> 3)+16); if (ptr == NULL) goto nomem; SET_BPTR(fio->_base, CPTR2BP(ptr)); fio->rwflag = POSITIN; sds_info->sdsdirty = 0; sds_info->overflowed = NO; sds_info->ovoff = 0; fio->segbits = 0; fio->_cnt = 0; fio->_ptr = fio->_base; /* * Open the lower layers */ nspec = spec; NEXT_SPEC(nspec); if (fio->rtype != TR_FSS_SCR || fio->subtype != FSS_OPT_NOVFL) { int write_only = 0; int llflags = flags; /* * The lower level file must be readable to allow loading into * memory. */ if ((llflags & O_ACCMODE) == O_WRONLY) { write_only = 1; llflags &= ~O_ACCMODE; llflags |= O_RDWR; } nextfio = _ffopen(name, llflags, mode, nspec, stat, cbits, cblks, NULL, oinf); /* * If write_only and file has no read permissions, then it * may be opened O_WRONLY. But it better be empty, because if not * _sds_load will get an error later. */ if (nextfio < 0 && write_only) { llflags = flags; nextfio = _ffopen(name, llflags, mode, nspec, stat, cbits, cblks, NULL, oinf); } if (nextfio < 0) goto badret; ret = XRCALL((struct fdinfo *)nextfio, fcntlrtn) (struct fdinfo *)nextfio, FC_STAT, &statbuf, stat); if (ret < 0) goto close_badret; sds_info->dsk_blksize = statbuf.st_blksize; }
_ffopen_t _gen_fopen( const char *name, int flags, mode_t mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { char *ptr; union spec_u *nspec; long recsize, blksize; /* bits */ long rsz, mbs; /* bytes */ _ffopen_t nextfio; int rtype; struct gen_ff *ff_dat; /* * convert 8-bit bytes to bits */ rsz = spec->fld.recsize; mbs = spec->fld.mbs; rtype = spec->fld.recfmt; if (rtype < 0 || rtype >= NUM_F_TYPES) { _SETERROR(stat, FDC_ERR_BADSPC, 0); return(_FFOPEN_ERR); } /* * General limit checks from table. */ if (rsz == 0) { _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } if (rsz < _F_limits[rtype].min_rsz || rsz > _F_limits[rtype].max_rsz) { _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } if (mbs != 0) if (mbs < _F_limits[rtype].min_mbs || mbs > _F_limits[rtype].max_mbs) { _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } switch(rtype) { case TR_IBM_F: /* * if mbs and rsz specified with * F format and mbs != rsz then error */ if (mbs != rsz && mbs != 0) { _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } case TR_IBM_FB: if (mbs == 0) mbs = rsz; /* dflt mbs = rsz */ /* must be exact multiple */ if ((mbs % rsz) != 0) { _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } break; case TR_VMS_F_DSK: case TR_VMS_F_TP: case TR_VMS_F_TR: if (mbs == 0) /* unspecified */ { /* deflt mbs=rsz */ if (rtype != TR_VMS_F_TP) /* deflt mbs=rsz */ mbs = rsz; else if(rtype == TR_VMS_F_TP) { /* dflt mbs=2048 */ mbs = 2048; if (rsz > mbs) mbs = rsz; } } if (rsz > mbs) { _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } break; default: _SETERROR(stat, FDC_ERR_BADSPC, 0); goto badret; } recsize = rsz << 3; blksize = mbs << 3; /* * Internally, both blksize and recsize are in bits! */ fio->maxrecsize = recsize; fio->maxblksize = blksize; fio->_ffbufsiz = blksize; /* bit size of buffer */ /* * Allocate buffer */ ptr = malloc((blksize >> 3) + 16); if (ptr == NULL) goto nomem; /* * Allocate private data area */ fio->lyr_info = (char *)calloc(sizeof(struct gen_ff), 1); if (fio->lyr_info == NULL) goto nomem; /* load up record characteristics */ ff_dat = (struct gen_ff *)fio->lyr_info; *ff_dat = _Frec_def_tab[rtype]; SET_BPTR(fio->_base, CPTR2BP(ptr)); fio->rwflag = POSITIN; fio->segbits = 0; fio->_cnt = 0; fio->_ptr = fio->_base; /* * First, open the lower layers */ nspec = spec; NEXT_SPEC(nspec); nextfio = _ffopen(name, flags, mode, nspec, stat, cbits, cblks, NULL, oinf); if (nextfio == _FFOPEN_ERR) goto badret; DUMP_IOB(fio); /* debugging only */ return(nextfio); nomem: _SETERROR(stat, FDC_ERR_NOMEM, 0); badret: if (BPTR2CP(fio->_base) != NULL) free(BPTR2CP(fio->_base)); if (fio->lyr_info != NULL) free(fio->lyr_info); return(_FFOPEN_ERR); }
int _trc_open( const char *name, int flags, int mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { union spec_u *nspec; struct trace_f *trc_info; int *hp; char *ptr = NULL; int nextfio, namlen, trcfd; namlen = strlen(name); ptr = malloc(namlen + strlen(SUFFIX) + 1); if (ptr == NULL) goto badopen; trc_info = (struct trace_f *)calloc(sizeof(struct trace_f), 1); if (trc_info == NULL) goto badopen; fio->lyr_info = (char *)trc_info; strcpy(ptr, name); strcat(ptr, SUFFIX); trcfd = open(ptr, O_WRONLY | O_APPEND | O_CREAT, 0666); hp = (int *)malloc((HIST_INIT+1)*8); if (hp == NULL) goto badopen; trc_info->hist = hp; trc_info->histsiz = HIST_INIT; trc_info->histmax = HIST_MAX; trc_info->histincr = HIST_INCR; trc_info->histbkt = HIST_BKT; trc_info->lastseek = NO; /* * Yes, ignore errors on open. */ trc_info->name = ptr; trc_info->trcfd = trcfd; ptr[namlen] = '\0'; _trc_enter(fio, TRC_OPEN); _trc_info(fio, "(\"%s\", %o, %o, &statw[%d], %o);\n", name, flags, mode, stat, cbits); /* * Now, open the lower layers */ nspec = spec; NEXT_SPEC(nspec); nextfio = _ffopen(name, flags, mode, nspec, stat, cbits, cblks, NULL, oinf); _trc_exit(fio, nextfio, stat); if (nextfio >= 0) { DUMP_IOB(fio); /* debugging only */ return(nextfio); } /* * Error. no memory. */ badopen: if (ptr != NULL) free(ptr); if (fio->lyr_info != NULL) free(fio->lyr_info); ERETURN(stat, FDC_ERR_NOMEM, 0); }
_ffopen_t _gen_xopen( const char *name, int flags, mode_t mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf ) { char *ptr; union spec_u *nspec; int blksize; _ffopen_t nextfio; int isvalid; struct gen_xf *xf_info; /* * Allocate private storage */ xf_info = (struct gen_xf *)calloc(sizeof(struct gen_xf),1); if (xf_info == NULL) goto nomem; fio->lyr_info = (char *)xf_info; /* * select parameters based on record type */ switch(fio->rtype) { case TR_NVE_V: xf_info->rdwlen = 112; /* bits */ break; case TR_CRAY_V: xf_info->rdwlen = 64; /* bits */ break; #ifdef _OLD_F77 case TR_UX_VAX: case TR_UX_SUN: xf_info->rdwlen = 32; /* bits */ break; #endif case TR_205_W: xf_info->rdwlen = 64; /* bits */ break; } xf_info->last_lrdwaddr = 0; xf_info->lrdwaddr = 0; /* * Record the maximum record size in bits. * A value of 0 is stored if this is unspecified. */ fio->maxrecsize = _ff_nparm_getv(spec, 1, &isvalid) * 8; /* * Record the buffer size in bits. */ blksize = _ff_nparm_getv(spec, 2, &isvalid) * 8; if (! isvalid || blksize < 256) /* bits, mighty small! */ blksize = X_BUFSIZ * BITPBLOCK; else blksize = (blksize + 077) & (~077);/* round to word size */ /* * Although the _ffbufsiz field is declared as long, * these routines use GETDATA and PUTDATA. Those macros * assign the amount to be written to integers. So, to * make this all work we need to be sure that the buffer size * does not exceed the size of an integer. */ if (blksize > (1<<sizeof(int)*8-5)){ _SETERROR(stat, FDC_ERR_BUFSIZ, 0); goto badret; } fio->_ffbufsiz = blksize; /* bit size of buffer */ ptr = malloc((blksize >> 3) + 16); if (ptr == NULL) goto nomem; SET_BPTR(fio->_base, CPTR2BP(ptr)); fio->scc = SCCFULL; fio->lastscc = SCCFULL; fio->rwflag = POSITIN; fio->segbits = 0; fio->_cnt = 0; fio->_ptr = fio->_base; /* * Now, open the lower layers */ nspec = spec; NEXT_SPEC(nspec); nextfio = _ffopen(name, flags, mode, nspec, stat, cbits, cblks, NULL, oinf); if (nextfio < 0) goto badret; DUMP_IOB(fio); /* debugging only */ return(nextfio); nomem: _SETERROR(stat, FDC_ERR_NOMEM, 0); badret: if (BPTR2CP(fio->_base) != NULL) free(BPTR2CP(fio->_base)); if (fio->lyr_info != NULL) free(fio->lyr_info); return(_FFOPEN_ERR); }
_ffopen_t _cch_open( const char *name, int oflags, mode_t mode, struct fdinfo *fio, union spec_u *spec, struct ffsw *stat, long cbits, int cblks, struct gl_o_inf *oinf) { int i; _ffopen_t nextfio; int nb; /* number of buffers */ int64 bs; /* size of each buffer in bits */ int ret; int isvalid; char *s; bitptr bptr; struct fdinfo *nfioptr; union spec_u *nspec; struct cch_f *cch_info; struct cch_buf *cbufs; struct stat fstat; struct ffsw clstat; struct ffc_info_s layer_info; int64 bypass; #ifdef __mips struct dioattr dio; int o_direct = 0; #endif #if defined(_CRAY1) || defined(_CRAYMPP) oflags |= O_RAW; /* We believe that bypassing system cache * enhances performance in most cases. */ #endif /* * Allocate the layer-specific data area. */ cch_info = (struct cch_f *)calloc(1, sizeof(struct cch_f)); if (cch_info == NULL) goto nomem; fio->lyr_info = (char *)cch_info; cch_info->optflags = 0; /* initially, no special options */ /* * Get values from the FFIO spec. */ #ifdef CCH_SDS_SUPPORTED if (spec->fld.recfmt == TR_CCH_SDS) { cch_info->optflags |= CCHOPT_SDS; oflags |= O_SSD; /* request I/O betw disk and SDS */ } #endif bs = _ff_nparm_getv(spec, 1, &isvalid) * BITPBLOCK; if (!isvalid) { #ifdef _UNICOS_MAX if (_MPP_MPPSIM > 0) { /* Running on simulator in user virtual mode. Simulator can */ /* not handle large reads/writes, so restrict the size */ bs = CCH_DEF_SIMBUFSIZ * BITPBLOCK; } else #endif bs = CCH_DEF_BUFSIZ * BITPBLOCK; /* set default bs */ } if (bs <= 0 || bs >= CCH_MAX_BBUFSIZ) { _SETERROR(stat, FDC_ERR_BUFSIZ, 0); goto badret; } nb = _ff_nparm_getv(spec, 2, &isvalid); if (!isvalid) nb = CCH_DEF_NBUF; /* set default nb */ if (nb <= 0) { _SETERROR(stat, FDC_ERR_NBUF0, 0); goto badret; } cch_info->nbufs = nb; cch_info->bufs = NULL; /* * Set flag if -m on is assigned. */ #ifdef __mips if (oflags & O_DIRECT) o_direct = 1; #endif if (oinf->aip != NULL) { if (oinf->aip->m_multup_flg && oinf->aip->m_multup) { cch_info->is_multup = 1; oinf->aip->m_multup_flg |= ATTR_USED; } #ifdef __mips if (oinf->aip->B_direct_flg) { if (oinf->aip->B_direct) o_direct = 1; else o_direct = 0; } #endif } /* * Allocate the buffer control blocks contiguously. */ if ((cch_info->bufs = (struct cch_buf *)calloc(nb, sizeof(struct cch_buf))) == NULL) goto nomem; /* * Get the FFIO spec for the next lower layer. */ nspec = spec; NEXT_SPEC(nspec); /* * Open the layers below this one. */ nextfio = _ffopen(name, oflags, mode, nspec, stat, cbits, cblks, NULL, oinf); if (nextfio == _FFOPEN_ERR) goto badret; nfioptr = (struct fdinfo *)nextfio; /* * Get information about the underlying layer. */ ret = XRCALL(nfioptr,fcntlrtn) nfioptr, FC_STAT, &fstat, stat); if (ret == ERR) goto close_badret; ret = XRCALL(nfioptr,fcntlrtn) nfioptr, FC_GETINFO, &layer_info, stat); if (ret == ERR) goto close_badret; if ( layer_info.ffc_flags & FFC_CANSYLISTIO ) cch_info->do_sylistio = 1; #ifdef __mips /* * Have we been requested to open with O_DIRECT? */ if (o_direct) { int nflag; int64 bsbyt; bsbyt = bs/8; /* convert buffer size to bytes */ /* determine buffer size requirements for O_DIRECT */ ret = XRCALL(nfioptr,fcntlrtn) nfioptr, FC_DIOINFO, &dio, stat); if (ret == ERR) goto close_badret; /* Adjust the size of the buffers for O_DIRECT's requirements.*/ if (bsbyt % dio.d_miniosz != 0){ /* We need to write in these units. */ bsbyt = bsbyt - bsbyt%dio.d_miniosz; } if (bsbyt < dio.d_miniosz) { bsbyt = dio.d_miniosz; } else if (bsbyt > dio.d_maxiosz) { bsbyt = dio.d_maxiosz; } if (bsbyt % dio.d_mem != 0){ /* Each buffer needs to be memaligned */ /* Since this layer expects all buffers */ /* to be contiguous, we're out of luck. */ errno = FDC_ERR_BUFSIZ; goto close_badret; } bs = bsbyt*8; /* convert back to bits */ cch_info->maxiosize = dio.d_maxiosz; cch_info->miniosize = dio.d_miniosz; cch_info->chunksize = dio.d_miniosz; cch_info->diskalign = dio.d_miniosz; cch_info->memalign = dio.d_mem; cch_info->odirect = 1; } else {