_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); }
ffbksp(int fd, ...) #endif { struct fdinfo *fio; int ret, na; struct ffsw locstat, *pstat; #ifdef _CRAY va_list ap; #endif fio = GETIOB(fd); #ifdef _CRAY NUMARG(na); if (na < 2) pstat = &locstat; else { va_start(ap, fd); pstat = va_arg(ap, struct ffsw *); } #else pstat = &locstat; na = 1; #endif CHECK_FIOPTR(fio, pstat); ret = XRCALL(fio, backrtn) fio, pstat); /* set errno only if stat was not passed */ if (na < 2) errno = locstat.sw_error; return (ret); }
/* * Write an EOF to a buffer-layer file. * */ int _sqb_weof(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; if (fio->rwflag == WRITIN) { if (_sqb_flush(fio, stat) < 0) { return(ERR); } } else if (fio->rwflag == READIN || fio->rwflag == POSITIN) { /* synchronize physical position with logical */ if (_sqb_sync(fio, stat, 1) < 0) { return(ERR); } } fio->rwflag = WRITIN; /* * Tell the underlying layer to write an EOF */ llfio = fio->fioptr; if (XRCALL(llfio,weofrtn) llfio, stat) == ERR) return(ERR); SETSTAT(stat, FFEOF, 0); return(0); }
ffweof(int fd, ...) #endif { struct fdinfo *fio; int ret, na; struct ffsw locstat, *pstat; #if !defined(__mips) && !defined(_LITTLE_ENDIAN) va_list ap; #endif fio = GETIOB(fd); #if defined(__mips) || defined(_LITTLE_ENDIAN) na = 1; pstat = &locstat; #else NUMARG(na); if (na < 2) pstat = &locstat; else { va_start(ap, fd); pstat = va_arg(ap, struct ffsw *); } #endif CHECK_FIOPTR(fio, pstat); ret = XRCALL(fio, weofrtn) fio, pstat); #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (na < 2) errno = locstat.sw_error; #endif return (ret); }
ffreada(int fd, char *buf, int nbytes, struct ffsw *stat, ...) { struct fdinfo *fio; int ret, locfulp; bitptr bufptr; int locubc, *pubc, na; /* need a place to put result */ va_list ap; fio = GETIOB(fd); SET_BPTR(bufptr, CPTR2BP(buf)); /* adjust number of bits requested if ubc passed in */ NUMARG(na); locubc = 0; pubc = &locubc; locfulp = FULL; if (na < 4 || na > 6) { errno = FDC_ERR_NOPARM; return(ERR); } va_start(ap, stat); if (na > 4) locfulp = va_arg(ap, int); if (na > 5) pubc = va_arg(ap, int *); CHECK_FIOPTR(fio, stat); ret = XRCALL(fio, readartn) fio, bufptr, nbytes, stat, locfulp, pubc); return (ret); }
/* * buffering layer fcntl requests * * Parameters: * fd - file descriptor (dummy) * cmd - command code * arg - command specific parameter * iostat - pointer to status return word * * Returns: -1 if error occurred * 0 if OK */ _sqb_fcntl(struct fdinfo *fio, int cmd, void *arg, struct ffsw *iostat) { struct fdinfo *llfio; struct ffc_info_s *ffcp, locinfo; struct sqb_f *sqb_info; int ret, llfd; sqb_info = (struct sqb_f *) fio->lyr_info; llfio = fio->fioptr; ret = 0; switch(cmd) { case FC_GETINFO: ffcp = (struct ffc_info_s *)arg; /* * Only do a call to the lower level if it has been opened */ if (llfio != NULL) { ret = XRCALL(llfio,fcntlrtn) llfio, FC_GETINFO, &locinfo, iostat); llfd = locinfo.ffc_fd; /* fd from lower layer */ } else {
/* * * Perform a seek operation on a buffered file. * * Parameters: * fio - fdinfo pointer * pos - requested byte offset * whence - SEEK_SET, SEEK_CUR, or SEEK_END * stat - status return word * * Return value: * * The new byte postion in the file. * If an error occurs, -1 is returned, and the stat->sw_error field is * set. */ _ffseek_t _sqb_seek(struct fdinfo *fio, off_t pos, int whence, struct ffsw *stat) { _ffseek_t ret; struct sqb_f *sqb_info; int sync = 0; struct fdinfo *llfio; sqb_info = (struct sqb_f *)fio->lyr_info; llfio = fio->fioptr; /* We could probably do more record keeping, and */ /* determine whether the desired position was already */ /* in our buffers. */ /* Wait for outstanding I/O */ if (fio->rwflag == READIN || fio->rwflag == POSITIN) { if (whence == SEEK_CUR) sync = 1; /* synchronize physical and logical */ /* positions */ if (_sqb_sync(fio, stat, sync) < 0) { return(ERR); } } else if (fio->rwflag == WRITIN) { if (_sqb_flush(fio, stat) < 0) { return(ERR); } } fio->rwflag = POSITIN; ret = XRCALL(llfio, seekrtn) llfio, pos, whence, stat); return(ret); }
off_t #else int #endif ffpos( int fd, int cmd, #if defined(__mips) || defined(_LITTLE_ENDIAN) void *arg, #else long *arg, #endif int len, struct ffsw *stat ) { struct fdinfo *fio; _ffseek_t ret; fio = GETIOB(fd); CHECK_FIOPTR(fio, stat); #if defined(__mips) || defined(_LITTLE_ENDIAN) if (cmd == FP_BSEEK) ERETURN(stat, FDC_ERR_NOSUP, 0); #endif ret = XRCALL(fio, posrtn) fio, cmd, arg, len, stat); return (ret); }
int ffbkspf(int fd, struct ffsw *pstat) { struct fdinfo *fio; fio = GETIOB(fd); CHECK_FIOPTR(fio, pstat); return(XRCALL(fio, backrtn) fio, pstat)); }
/* * This routine is like ffweof, except it expects 2 parameters */ ffweoff(int fd, struct ffsw *pstat) { struct fdinfo *fio; int ret; fio = GETIOB(fd); CHECK_FIOPTR(fio, pstat); ret = XRCALL(fio, weofrtn) fio, pstat); return (ret); }
/* * cache layer fcntl requests * * Returns: -1 if error occurred * 0 if OK */ _cca_fcntl( struct fdinfo *fio, /* file descriptor */ int cmd, /* command code */ void *arg, /* command-specific parameter */ struct ffsw *iostat) /* pointer to status return word */ { struct fdinfo *llfio; struct ffc_info_s *ffcp, locinfo; struct cca_f *cca_info; int ret, llfd; struct ffsw *check_ffsw; struct cca_async_tracker *this_tracker; cca_info = (struct cca_f *) fio->lyr_info; llfio = fio->fioptr; if(CCA_SOFT_BYPASS) { int ret; ret = XRCALL(llfio,fcntlrtn) llfio, cmd, arg, iostat); if (cmd == FC_GETINFO) { ffcp = (struct ffc_info_s *)arg; ffcp->ffc_flags &= ~(FFC_CANLISTIO); } return(ret); } ret = 0; switch(cmd) { case FC_GETINFO: ffcp = (struct ffc_info_s *)arg; /* * Only do a call to the lower level if it has been opened */ if (llfio != NULL) { ret = XRCALL(llfio,fcntlrtn) llfio, FC_GETINFO, &locinfo, iostat); llfd = locinfo.ffc_fd; /* fd from lower layer */ } else {
int _lock_flush(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; int ret; llfio = fio->fioptr; LYR_LOCK(fio); ret = XRCALL(llfio, flushrtn) llfio, stat); LYR_UNLOCK(fio); return(ret); }
/* * Close an f77 file. */ int _f77_close(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; int ret; struct f77_xf *xfinfo; ret = 0; /* * If the file has been writing, flush and truncate after the last * record written. */ xfinfo = (struct f77_xf *)fio->lyr_info; if (fio->rwflag == WRITIN) { ret = XRCALL(fio, flushrtn) fio, stat); if (ret != 0) return(ERR); ret = XRCALL(fio, weodrtn) fio, stat); if (ret != 0) return(ERR); }
/* * _evnt_weod * * Log an EOD write operation * * Input: * fio - ffio file descriptor * stat - pointer to status return word * * Output: * ret - return value from weodrtn * */ int _evnt_weod(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; struct evnt_f *evnt_info; int status; rtc_t start_rtc, finish_rtc; struct ffsw log_stat; int log_ubc = 0; int ret; evnt_info = (struct evnt_f *) fio->lyr_info; llfio = fio->fioptr; start_rtc = RTC(); ret = XRCALL(llfio, weodrtn) llfio, stat); finish_rtc = RTC(); #ifdef __mips if (!(evnt_info->odirect) || (evnt_info->cur_pos % evnt_info->diskalign != 0)) #else if (evnt_info->cur_pos & evnt_info->sector_mask) #endif evnt_info->ill_formed_weod++; #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace) { int record[4]; EVNT_LOCK_ON; record[0] = _evnt_WEOD | evnt_info->fd; record[1] = start_rtc; record[2] = finish_rtc; record[3] = ret; status = EVNT_XR_WRITE(record, sizeof(int), 4); INC_GLOBAL_LOG_COUNT(weod); EVNT_LOCK_OFF; } #endif _GL_evnt_trc_file[evnt_info->trc_file_number].cur_usage -= (evnt_info->cur_size - evnt_info->cur_pos); evnt_info->cur_size = evnt_info->cur_pos; EVNT_TRACE_SIZE; evnt_info->counts.weod++; evnt_info->counts.total++; return (ret); }
ssize_t _lock_writea(struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat, int fulp, int *ubc) { struct fdinfo *llfio; ssize_t ret; llfio = fio->fioptr; LYR_LOCK(fio); ret = XRCALL(llfio, writeartn) llfio, bufptr, nbytes, stat, fulp, ubc); LYR_UNLOCK(fio); return(ret); }
/* * lock listio requests * The lock layer will be called only if the lower layer can handle listio * requests. */ _lock_listio( int cmd, /* LC_WAIT or LC_START */ struct fflistreq *list, /* list of requests (see fflistio) */ int nreq, /* number of requests */ struct ffsw *stat) /* status structure */ { int i; struct fdinfo *llfio; struct fdinfo *first_fio; struct fdinfo *fio; struct fflistreq *copy; /* copy of the list of requests */ int numdone; int curent; int pos; bitptr buf; int nb; int zero; int ret; int nstr; struct ffsw locstat; struct ffsw *istat; if (nreq == 0) return(0); first_fio = GETIOB(list[0].li_fildes); for (i = 0; i < nreq; i++) { fio = GETIOB(list[i].li_fildes); if (fio != first_fio) { _SETERROR(stat, FDC_ERR_LSTIO, 0); return (-1); } } llfio = first_fio->fioptr; if (llfio->can_listio) { copy = malloc(nreq * sizeof(*list)); if (copy == NULL) ERETURN(stat, FDC_ERR_NOMEM, 0); for (i = 0; i < nreq; i++) { copy[i] = list[i]; /* copy the entry */ copy[i].li_fildes = (int)llfio; } LYR_LOCK(fio); numdone = XRCALL(llfio, listiortn) cmd, copy, nreq, stat); LYR_UNLOCK(fio); free(copy); return(numdone); }
ssize_t _lock_readc(struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat, int fulp) { struct fdinfo *llfio; ssize_t ret; llfio = fio->fioptr; LYR_LOCK(fio); ret = XRCALL(llfio, readcrtn)llfio, bufptr, nbytes, stat, fulp); LYR_UNLOCK(fio); return(ret); }
_ffseek_t _lock_seek(struct fdinfo *fio, off_t pos, int whence, struct ffsw *stat) { struct fdinfo *llfio; _ffseek_t ret; llfio = fio->fioptr; LYR_LOCK(fio); ret = XRCALL(llfio, seekrtn) llfio, pos, whence, stat); LYR_UNLOCK(fio); return(ret); }
_gen_xbksp(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; ssize_t rret; int ret, whence, rdwlen, flag; ff_offt pos, cwpos; long ii; union nosve_rdw_u rdw; union w_205_u wcw; struct gen_xf *xf_info; xf_info = (struct gen_xf *)fio->lyr_info; /* * If the file's been writing, flush previously written data to disk and * truncate. */ if (fio->rwflag == WRITIN) { ret = XRCALL(fio, flushrtn) fio, stat); if (ret < 0) return(ERR); ret = XRCALL(fio, weodrtn) fio, stat); if (ret < 0) return(ERR); }
int ffread(int fd, char *buf, int nbytes, ...) #endif { struct fdinfo *fio; ssize_t ret; int locfulp; bitptr bufptr; int locubc, *pubc, na; /* need a place to put result */ struct ffsw locstat, *pstat; /* need a place to put result */ #if !defined(__mips) && !defined(_LITTLE_ENDIAN) va_list ap; #endif fio = GETIOB(fd); SET_BPTR(bufptr, CPTR2BP(buf)); /* adjust number of bits requested if ubc passed in */ #ifdef _CRAY NUMARG(na); #elif defined(__mips) || defined(_LITTLE_ENDIAN) na = 3; #endif locubc = 0; pubc = &locubc; locfulp = FULL; pstat = &locstat; #if !defined(__mips) && !defined(_LITTLE_ENDIAN) va_start(ap, nbytes); if (na < 3 || na > 6) { errno = FDC_ERR_NOPARM; return(ERR); } if (na > 3) pstat = va_arg(ap, struct ffsw *); if (na > 4) locfulp = va_arg(ap, int); if (na > 5) pubc = va_arg(ap, int *); #endif CHECK_FIOPTR(fio, pstat); ret = XRCALL(fio, readrtn) fio, bufptr, nbytes, pstat, locfulp, pubc); if (na < 4) errno = locstat.sw_error; return (ret); }
/* * _evnt_write * * Log a write request * * Input: * fio - ffio file descriptor * bufptr - bit pointer to where data is to go * nbytes - number of bytes to be written * stat - pointer to status return word * fulp - full or partial write mode flag * ubcp - pointer to unused bit count. On return, * *ubcp is updated to contain the unused bit * count in the data returned. * * Output: * The number of bytes transferred is returned upon successful completion. * if an error occurs, -1 is returned. * * The stat->sw_stat field is set to FFCNT upon normal return. * */ ssize_t _evnt_write(struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat, int fulp, int *ubcp) { struct fdinfo *llfio; struct evnt_f *evnt_info; int status; rtc_t start_rtc, finish_rtc; ssize_t ret; struct ffsw log_stat; int log_ubc = 0; evnt_info = (struct evnt_f *) fio->lyr_info; llfio = fio->fioptr; EVNT_UPDATE(write); start_rtc = RTC(); ret = XRCALL(llfio, writertn) llfio, bufptr, nbytes, stat, fulp, ubcp); finish_rtc = RTC(); evnt_info->cur_pos += nbytes; EVNT_CHECK_SIZE; #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace) { int record[4]; EVNT_LOCK_ON; record[0] = (_evnt_WRITE | evnt_info->fd) | nbytes; record[1] = start_rtc; record[2] = finish_rtc; record[3] = ret; status = EVNT_XR_WRITE(record, sizeof(int), 4); INC_GLOBAL_LOG_COUNT(write); EVNT_LOCK_OFF; } #endif evnt_info->counts.total++; evnt_info->counts.write++; evnt_info->write.delivered += ret; evnt_info->write.time += (finish_rtc - start_rtc); return (ret); }
/* * trace listio requests * The trace layer indicates that it can handle listio requests iff * the lower layer can. */ _trc_listio( int cmd, /* LC_WAIT or LC_START */ struct fflistreq *list, /* list of requests (see fflistio) */ int nreq, /* number of requests */ struct ffsw *stat) /* status structure */ { int ret; int i; struct fdinfo *llfio; struct fdinfo *first_llfio; struct fdinfo *fio; struct fflistreq *copy; /* copy of the list of requests */ if (nreq == 0) return(0); copy = malloc(nreq * sizeof(*list)); if (copy == NULL) ERETURN(stat, FDC_ERR_NOMEM, 0); for (i = 0; i < nreq; i++) { fio = GETIOB(list[i].li_fildes); llfio = fio->fioptr; if (i == 0) first_llfio = llfio; else if (llfio != first_llfio) { _SETERROR(list[i].li_status, FDC_ERR_LSTIO, 0); continue; } copy[i] = list[i]; /* copy the entry */ copy[i].li_fildes = (int)llfio; /* pass it on to lower layer */ _trace_listio(fio, i, cmd, ©[i], nreq); } ret = XRCALL(llfio, listiortn) cmd, copy, nreq, stat); free(copy); return(ret); }
/* * Write an EOD. * Truncate the file. This is the 'real' end of the data. * We cannot do this if we were reading or if we just positioned. */ int _tmf_weod(struct fdinfo *fio, struct ffsw *stat) { register int ret; struct tmfio *xfinfo; xfinfo = (struct tmfio *)fio->lyr_info; if (xfinfo->rwflag != WRITIN) { ERETURN(stat, FENOENDF, 0); } ret = XRCALL(fio, flushrtn) fio, stat); if (ret < 0) return(ret); SETSTAT(stat, FFEOD, 0); return(0); }
void TSYNC(_f_int *unump, _f_int *istat) { register int ret; unit *cup; /* Unit table pointer */ FIOSPTR css; /* I/O statement state */ GET_FIOS_PTR(css); STMT_BEGIN(*unump, 0, T_TAPE, NULL, css, cup); if (cup == NULL) _ferr(css, FENOTOPN); *istat = 0; if (cup->ufs == FS_FDC) { ret = XRCALL(cup->ufp.fdc, fcntlrtn) cup->ufp.fdc, FC_TSYNC, 0, &cup->uffsw); if (ret < 0) *istat = cup->uffsw.sw_error; }
void ENDSP(_f_int *unump, _f_int *istat) { register int ret; unit *cup; FIOSPTR css; GET_FIOS_PTR(css); STMT_BEGIN(*unump, 0, T_TAPE, NULL, css, cup); if (cup == NULL) _ferr(css, FENOTOPN); *istat = 0; if (cup->ufs == FS_FDC) { ret = XRCALL(cup->ufp.fdc, fcntlrtn) cup->ufp.fdc, FC_ENDSP, 0, &cup->uffsw); if (ret < 0) *istat = cup->uffsw.sw_error; else cup->uspcproc = 0; }
/* * _evnt_bksp * * Time backspace request * * Input: * fio - ffio file descriptor * stat - pointer to status return word * * Output: * ret - return value from backrtn * */ int _evnt_bksp(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; struct evnt_f *evnt_info; int status; rtc_t start_rtc, finish_rtc; struct ffsw log_stat; int log_ubc = 0; int ret; evnt_info = (struct evnt_f *) fio->lyr_info; llfio = fio->fioptr; start_rtc = RTC(); ret = XRCALL(llfio, backrtn) llfio, stat); finish_rtc = RTC(); #if !defined(__mips) && !defined(_LITTLE_ENDIAN) if (evnt_info->optflags.trace) { int record[4]; EVNT_LOCK_ON; record[0] = (_evnt_BKSP | evnt_info->fd); record[1] = start_rtc; record[2] = finish_rtc; record[3] = ret; status = EVNT_XR_WRITE(record, sizeof(int), 4); INC_GLOBAL_LOG_COUNT(bksp); EVNT_LOCK_OFF; } #endif evnt_info->counts.bksp++; evnt_info->counts.total++; return (ret); }
/* * This routine is like ffread, except it expects all parameters . * If ubc == NULL, then do not return ubc information to user. */ ssize_t ffreadf(int fd, void *buf, size_t nbytes, struct ffsw *pstat, int locfulp, int *ubc) { struct fdinfo *fio; ssize_t ret; bitptr bufptr; int locubc, *pubc; if (ubc == NULL) { pubc = &locubc; locubc = 0; } else { pubc = ubc; } fio = GETIOB(fd); SET_BPTR(bufptr, CPTR2BP(buf)); CHECK_FIOPTR(fio, pstat); ret = XRCALL(fio, readrtn) fio, bufptr, nbytes, pstat, locfulp, pubc); return (ret); }
ffsetsp(int fd, ...) { struct fdinfo *fio; struct ffsw locstat, *pstat; int ret, na; va_list ap; fio = GETIOB(fd); NUMARG(na); if (na < 2) pstat = &locstat; else { va_start(ap, fd); pstat = va_arg(ap, struct ffsw *); } CHECK_FIOPTR(fio, pstat); _eov_load(1); /* Call a routine that provides hard references */ /* to eov routines. */ ret = XRCALL(fio, fcntlrtn) fio, FC_SETSP, 1, pstat); if (na < 2) errno = locstat.sw_error; return (ret); }
/* * _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); }
/* * Write an EOD to a cache file. * * Truncate this layer at the current position. */ int _cch_weod( struct fdinfo *fio, struct ffsw *stat) { int nbu, i; off_t fsize; int bs; struct cch_buf *cbufs; struct cch_f *cch_info; struct fdinfo *llfio; cch_info = (struct cch_f *)fio->lyr_info; if ((fio->opn_flags & O_ACCMODE) == O_RDONLY) ERETURN(stat, EBADF, 0); if (cch_info->is_blkspec) ERETURN(stat, FDC_ERR_NOSUP, 0); cch_info->fsize = cch_info->cpos; fio->rwflag = WRITIN; fio->ateof = 0; fio->ateod = 1; fio->recbits = 0; /* * Fix up any cache page buffers for file pages which lie past the new EOD. */ nbu = cch_info->nbufs; bs = cch_info->bsize; cbufs = cch_info->bufs; fsize = cch_info->fsize; for (i=0; i<nbu; i++) { off_t filead = cbufs[i].filead; if (filead >= 0) { /* If page is past EOD then mark it free */ if (filead >= fsize) cbufs[i].filead = -1; /* If page straddles EOD then zero out part of it */ else if (filead < fsize && filead + bs > fsize) { int valid_bytes = BITS2BYTES(fsize - filead); #ifdef CCH_SDS_SUPPORTED if (cch_info->optflags & CCHOPT_SDS) { int sds_offset; int res; sds_offset = BPTR2CP(cbufs[i].buf) - (char *)NULL; res = _sdsset( sds_offset + valid_bytes, 0, BITS2BYTES(bs) - valid_bytes); if (res == -1) ERETURN(stat, errno, 0); } else #endif { (void)memset( BPTR2CP(cbufs[i].buf) + valid_bytes, 0, BITS2BYTES(bs) - valid_bytes); } } } } /* * Truncate the underlying layer at the same location. For most layers, * this ensures that data past this EOD becomes zero if the underlying file * is later extended such that a hole is left between the this EOD * and the data written later. */ llfio = fio->fioptr; if (fsize < cch_info->feof) { if (XRCALL(llfio,seekrtn) llfio, BITS2BYTES(fsize), SEEK_SET, stat) == ERR) return(ERR); if (XRCALL(llfio,weodrtn) llfio, stat) == ERR) return(ERR); cch_info->feof = fsize; } SETSTAT(stat, FFEOD, 0); return(0); }