⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapefslib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	TAPE_DEBUG_MSG ("tapeFsDevInit: numFileMarks < 0\n",0,0,0,0,0,0);	return (NULL);	}    if ((pTapeConfig->rewind != TRUE) && (pTapeConfig->rewind != FALSE))	{	errno = S_tapeFsLib_ILLEGAL_TAPE_CONFIG_PARM;	TAPE_DEBUG_MSG ("tapeFsDevInit: rewind flag wrong\n",0,0,0,0,0,0);	return (NULL);	}    /* Allocate a tape volume descriptor for device */    if ((pTapeVol = (TAPE_VOL_DESC *) calloc 					(sizeof (TAPE_VOL_DESC), 1)) == NULL)	return (NULL);				/* no memory */    TAPE_DEBUG_MSG ("tapeFsDevInit: pTapeVol is %x\n",(int)pTapeVol,0,0,0,0,0);    /* Create volume locking semaphore (initially available) */    pTapeVol->tapevd_semId = semMCreate (tapeFsVolMutexOptions);    if (pTapeVol->tapevd_semId == NULL)	{	free ((char *) pTapeVol);	return (NULL);				/* could not create semaphore */	}    /* Allocate a File Descriptor (FD) for this volume */    pTapeVol->tapevd_pTapeFd = (TAPE_FILE_DESC *) calloc 						  (sizeof (TAPE_FILE_DESC), 1);    if (pTapeVol->tapevd_pTapeFd == NULL) 	{	free ((char *) pTapeVol);	return (NULL);				/* could not allocate FD */	}    /* Add device to system device table */    if (iosDevAdd ((DEV_HDR *) pTapeVol, volName, tapeFsDrvNum) != OK)	{	TAPE_DEBUG_MSG ("tapeFsDevInit: iosDevAdd error\n",0,0,0,0,0,0);	free ((char *) pTapeVol->tapevd_pTapeFd);	free ((char *) pTapeVol);	return (NULL);				/* can't add device */	}    /* Initialize volume descriptor */    pTapeVol->tapevd_pSeqDev      = pSeqDev;    pTapeVol->tapevd_status	  = OK;    pTapeVol->tapevd_state	  = TAPE_VD_READY_CHANGED;    pTapeVol->tapevd_rewind	  = pTapeConfig->rewind;    pTapeVol->tapevd_blkSize	  = pTapeConfig->blkSize;    pTapeVol->tapevd_numFileMarks = pTapeConfig->numFileMarks;    pTapeVol->tapevd_density      = pTapeConfig->density;    pSeqDev->sd_blkSize           = pTapeConfig->blkSize;    /* File descriptor initialization */    pTapeVol->tapevd_pTapeFd->tapefd_inUse = FALSE;    return (pTapeVol);    }/********************************************************************************* tapeFsFdFlush - flush tape volume file descriptor I/O buffer to tape** This routine causes the I/O buffer of a tape volume file descriptor* to be written out to the physical device. It is assumed that the volume* is of fixed block type.** Note: This function should only be called for file descriptors opened with*       the O_WRONLY mode** RETURNS: OK, or ERROR if something could not be written out.*/LOCAL STATUS tapeFsFdFlush    (    FAST TAPE_FILE_DESC  *pTapeFd         /* pointer to file descriptor */    )    {				    FAST int 	   index   = pTapeFd->tapefd_bufIndex;  /* buffer index */    /* ptr to sequential device */    FAST SEQ_DEV * pSeqDev = pTapeFd->tapefd_pTapeVol->tapevd_pSeqDev;    /* seq device block Size */    FAST int	   blkSize = pSeqDev->sd_blkSize;    if (pTapeFd->tapefd_bufIndex != 0)	{	/* Pad partial blocks with zeros */	bzero (pTapeFd->tapefd_buffer + index, blkSize - index); 	/* Write out the current (dirty) block */	if (tapeFsBlkWrt (pTapeFd->tapefd_pTapeVol, 1,		       pTapeFd->tapefd_buffer, TRUE) != OK)	    return (ERROR);			/* write error */	/* Reset the buffer index so as to invalidate the buffer */	pTapeFd->tapefd_bufIndex = 0;	}    return (OK);    }/********************************************************************************* tapeFsInit - initialize the tape volume library** This routine initializes the tape volume library.  It must be called exactly* once, before any other routine in the library. Only one file descriptor* per volume is assumed. ** This routine also installs tape volume library routines in the VxWorks I/O* system driver table.  The driver number assigned to tapeFsLib is placed in* the global variable `tapeFsDrvNum'.  This number is later associated* with system file descriptors opened to tapeFs devices.** To enable this initialization, simply call the routine tapeFsDevInit(), which* automatically calls tapeFsInit() in order to initialize the tape file system.** RETURNS: OK or ERROR.*/STATUS tapeFsInit ()    {    /*     * Install tapeFsLib routines in I/O system driver table     * Note: there is no delete routine, and that the     *       tapeFsOpen routine is also used as the create function.     */    tapeFsDrvNum = iosDrvInstall ((FUNCPTR) tapeFsOpen, (FUNCPTR) NULL,			         (FUNCPTR) tapeFsOpen, tapeFsClose,			         tapeFsRead, tapeFsWrite, tapeFsIoctl);    if (tapeFsDrvNum == ERROR)	return (ERROR);				/* can't install as driver */    return (OK);    }/********************************************************************************* tapeFsIoctl - perform a device-specific control function** This routine performs the following ioctl() functions:** .CS*    MTIOCTOP 	     - Perform all UNIX MTIO operations. Use the MTIO structure*		       to pass the correct operation and operation count.*    FIOSYNC 	     - Write all modified file descriptor buffers to device.*    FIOFLUSH        - Same as FIOSYNC.*    FIOBLKSIZESET   - Set the device block size (0 implies variable blocks)*    FIOBLKSIZEGET   - Get the device block size and compare with tapeFs value* .CE** If the ioctl (`function') is not one of the above, the device driver* ioctl() routine is called to perform the function.** If an ioctl() call fails, the task status (see errnoGet()) indicates* the nature of the error.** RETURNS: OK, or ERROR if function failed or unknown function, or* current byte pointer for FIOWHERE.*/LOCAL STATUS tapeFsIoctl    (    FAST TAPE_FILE_DESC * pTapeFd,      /* file descriptor of file to control */    int                   function,     /* function code                      */    int                   arg           /* some argument                      */    )    {    FAST STATUS		status;		/* return status value 		      */    FAST TAPE_VOL_DESC *pTapeVol = pTapeFd->tapefd_pTapeVol;    FAST SEQ_DEV *    	pSeqDev  = pTapeVol->tapevd_pSeqDev;    FAST MTOP *		pMtOp    = (MTOP *) arg;   /* ptr to operation struct */    switch (function)	{	case MTIOCTOP:	    /* Handle MTIO MTIOCTOP operations */	    status = mtOpHandle (pTapeFd, pMtOp->mt_op, pMtOp->mt_count);            break;                case FIOFLUSH:        case FIOSYNC:            /* Check if the file mode is correct */            if (pTapeFd->tapefd_mode == O_RDONLY)                {                errno = EROFS;		/* posix errno */                status = ERROR;                break;                }            /* Flush any buffered data */            status = tapeFsFdFlush (pTapeFd);  /* errno set by lower layer */            break;        case FIOBLKSIZESET:            	    if (pSeqDev->sd_ioctl == NULL)                {                errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		status = ERROR;                break;		}	    	    if (arg != 0)		/* Variable block size */		{	        /* Call driver's ioctl routine with function and arg */	        status = (*pSeqDev->sd_ioctl) (pSeqDev, function, arg);		}            else		status = OK;	    if (status == ERROR)		break;			/* do not modify any device structs */	    /* Set the block Size in the tapeFs device structures */            pTapeVol->tapevd_blkSize = arg;	    pSeqDev->sd_blkSize      = arg;            break;        case FIOBLKSIZEGET:            if (pSeqDev->sd_ioctl == NULL)                {                errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;                status = ERROR;                break;                }               /* Perform an FIOBLKSIZEGET ioctl on the driver */            status = (*pSeqDev->sd_ioctl) (pSeqDev, function, arg);            /*             * If an ERROR was not returned, then the value returned is a              * valid block size, and this value should be compared with             * that set in the device and volume structures.             */            if ((status != ERROR) && (pSeqDev->sd_blkSize != 0))                {                if  ( (pSeqDev->sd_blkSize != status) ||                       (pTapeVol->tapevd_blkSize != status)                    )                    {                    errno = S_tapeFsLib_BLOCK_SIZE_MISMATCH;                    status = ERROR;                    break;                    }                }            break;	default:	    if (pSeqDev->sd_ioctl == NULL)                {                errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		status = ERROR;                break;		}	    	    /* Call driver's ioctl routine with function and arg */	    status = (*pSeqDev->sd_ioctl) (pSeqDev, function, arg);            break;	} /* switch */        return (status);    }/********************************************************************************* mtOpHandle - Handles MTIOCTOP type ioctl operations** This routine performs the following ioctl() functions:**	MTWEOF		- write an end-of-file record *	MTFSF		- forward space over file mark *	MTBSF		- backward space over file mark *	MTFSR		- forward space to inter-record gap *	MTBSR		- backward space to inter-record gap *	MTREW		- rewind *	MTOFFL		- rewind and put the drive offline*	MTNOP		- no operation, sets status only*	MTRETEN		- retension the tape (use for cartridge tape only)*	MTERASE		- erase the entire tape*	MTEOM		- position to end of media*	MTNBSF		- backward space file to BOF** If the ioctl (`function') is not one of the above, the device driver* ioctl() routine is called to perform the function.** If an ioctl() call fails, the task status (see errnoGet()) indicates* the nature of the error.** RETURNS: OK, or ERROR if function failed or unknown function, or* current byte pointer for FIOWHERE.*/LOCAL STATUS mtOpHandle    (    FAST TAPE_FILE_DESC * pTapeFd,    /* file descriptor of file to control */    int                   op,         /* function code                      */    int                   numOps      /* some argument                      */    )    {    FAST TAPE_VOL_DESC *pTapeVol = pTapeFd->tapefd_pTapeVol;    FAST SEQ_DEV *    	pSeqDev  = pTapeVol->tapevd_pSeqDev;    /* Perform requested function */    switch (op)	{		/* Write an end-of-file record, which means: write a file mark */	case MTWEOF:	    /* Check if the file mode is correct */	    if (pTapeFd->tapefd_mode == O_RDONLY)		{                errno = EROFS;		/* posix errno */		return (ERROR);		}	    /* Flush any buffered data */	    if (tapeFsFdFlush (pTapeFd) == ERROR)		{		return (ERROR);		}			    if (pSeqDev->sd_seqWrtFileMarks == NULL)		{                errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Write "numOps" number of short file marks */            if ((*pSeqDev->sd_seqWrtFileMarks) (pSeqDev, numOps, TRUE)								      == ERROR)                {		return (ERROR);		}	    	    pTapeFd->tapefd_bufIndex = 0;	    return (OK);        /* Forward space over a file mark */	case MTFSF:     	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if (pSeqDev->sd_space == NULL)		{                errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Space forward "numOps" file marks */	    if ((*pSeqDev->sd_space) (pSeqDev, numOps, SPACE_CODE_FILEMARK)								      == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    return (OK);	            /* Backward space over a file mark */	case MTBSF:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if (pSeqDev->sd_space == NULL)		{	        errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Space backward "numOps" file marks */	    if ((*pSeqDev->sd_space) (pSeqDev, -numOps, SPACE_CODE_FILEMARK)								      == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    	    return (OK);	    	/* Forward space to inter-record gap (data blocks) */	case MTFSR:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if (pSeqDev->sd_space == NULL)		{		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Space forward "numOps" data blocks */	    if ((*pSeqDev->sd_space) (pSeqDev, numOps, SPACE_CODE_DATABLK)								      == ERROR)                {		return (ERROR);		}	    	    pTapeFd->tapefd_bufIndex = 0;	    return (OK);	    	/* Backward space to inter-record gap (data blocks) */        case MTBSR:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if (pSeqDev->sd_space == NULL)		{		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Space backward "numOps" data blocks */	    if ((*pSeqDev->sd_space) (pSeqDev, -numOps, SPACE_CODE_DATABLK)								      == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    	    return (OK);	    	/* Rewind the tape device */	case MTREW:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -