예제 #1
0
_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);
	}
예제 #2
0
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);
	}
예제 #3
0
/*
 * 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);
}
예제 #4
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);
	}
예제 #5
0
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);
	}
예제 #6
0
/*
 * 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
				{
예제 #7
0
파일: sqbseek.c 프로젝트: sharugupta/OpenUH
/*
 *
 * 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);	
}
예제 #8
0
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);
	}
예제 #9
0
int
ffbkspf(int fd, struct ffsw *pstat)
{
	struct fdinfo *fio;
	fio = GETIOB(fd);
	CHECK_FIOPTR(fio, pstat);
	return(XRCALL(fio, backrtn) fio, pstat));
}
예제 #10
0
/*
 * 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);
}
예제 #11
0
/*
 * 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 {
예제 #12
0
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);
}
예제 #13
0
/*
 * 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);
        }
예제 #14
0
/*
 * _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);
}
예제 #15
0
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);
}
예제 #16
0
/*
 * 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);
	}
예제 #17
0
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);
}
예제 #18
0
_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);
}
예제 #19
0
_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);
	}
예제 #20
0
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);
	}
예제 #21
0
/*
 * _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);
}
예제 #22
0
/*
 * 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, &copy[i], nreq);
	}

	ret = XRCALL(llfio, listiortn) cmd, copy, nreq, stat);

	free(copy);

	return(ret);
}
예제 #23
0
/*
 * 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);

}
예제 #24
0
파일: tsync.c 프로젝트: sharugupta/OpenUH
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;
	}
예제 #25
0
파일: endsp.c 프로젝트: sharugupta/OpenUH
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;
	}
예제 #26
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);
}
예제 #27
0
/*
 * 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);
	}
예제 #28
0
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);
	}
예제 #29
0
/*
 * _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);

}
예제 #30
0
/*
 * 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);
}