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

📄 tapefslib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    if (pSeqDev->sd_rewind == NULL)		{		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Rewind the tape device */	    if ((*pSeqDev->sd_rewind) (pSeqDev) == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    	    return (OK);	            /* Rewind and take the device offline */	case MTOFFL:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if ((pSeqDev->sd_rewind == NULL) || (pSeqDev->sd_load == NULL))		{		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Rewind the tape device */	    if ((*pSeqDev->sd_rewind) (pSeqDev) == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    	    /* Take it offline by unloading the device */	    if ((*pSeqDev->sd_load) (pSeqDev, UNLOAD, FALSE, FALSE) == ERROR)                {		return (ERROR);		}	    	    return (OK);        /* No operation on device, simply sets the status */	case MTNOP:	    if (pSeqDev->sd_statusChk == NULL)		{		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}            /* Check device status (driver sets the status in SEQ_DEV) */	    if ((*pSeqDev->sd_statusChk) (pSeqDev) == ERROR)                {		return (ERROR);		}	    	    return (OK);	    	/* Retension the tape */	case MTRETEN:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if (pSeqDev->sd_load == NULL)                {		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}	    	    /* Take it offline by unloading the device */	    if ((*pSeqDev->sd_load) (pSeqDev, UNLOAD, RETEN, FALSE) == ERROR)                {		return (ERROR);		}	    	    pTapeFd->tapefd_bufIndex = 0;	    return (OK);        /* Erase the entire tape and rewind */	case MTERASE:	    if (pSeqDev->sd_erase == NULL)                {		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}	    	    /* Take it offline by unloading the device */	    if ((*pSeqDev->sd_erase) (pSeqDev, LONG) == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    	    return (OK);        /* Position the tape at the end-of-medium before unloading */	case MTEOM:	    if (pTapeFd->tapefd_mode != O_RDONLY)		{	        /* Flush any buffered data */	        if (tapeFsFdFlush (pTapeFd) == ERROR)	    	    {		    return (ERROR);		    }		}	    if (pSeqDev->sd_load == NULL)                {		errno = S_tapeFsLib_SERVICE_NOT_AVAILABLE;		return (ERROR);		}	    	    /* Take it offline by unloading the device */	    if ((*pSeqDev->sd_load) (pSeqDev, UNLOAD, FALSE, EOT) == ERROR)                {		return (ERROR);		}	    pTapeFd->tapefd_bufIndex = 0;	    	    return (OK);        /* Backward space file to beginning of file */        /* XXX Not sure how this is different that MTBSF 1 */        case MTNBSF:	    return (ERROR);        /* Any other operation is an error */        default:	    return (ERROR);        } /* switch */    }/********************************************************************************* tapeFsOpen - open a tape volume** This routine opens the volume with the specified mode* (O_RDONLY or O_WRONLY).** The specified `name' must be a null string, indicating that the* caller specified only the device name during open(). This is because* there is no file structure on the tape device.** If the device driver supplies a status-check routine, it will be* called before the volume state is examined.** RETURNS: Pointer to tape volume file descriptor, or ERROR.*/LOCAL TAPE_FILE_DESC *tapeFsOpen    (    FAST TAPE_VOL_DESC * pTapeVol,      /* pointer to volume descriptor      */    FAST char *          name,     	/* "file" name - should be empty str */    FAST int             flags,         /* open flags                        */    FAST int		 mode		/* not used                          */    )    {                                        /* file descriptor pointer */    FAST TAPE_FILE_DESC	*pTapeFd = pTapeVol->tapevd_pTapeFd;						/* pointer to block device info */    FAST SEQ_DEV	*pSeqDev = pTapeVol->tapevd_pSeqDev;    UINT16          unused;    /* Check for open of other than tape volume (non-null filename) */    if (name [0] != EOS)	{	errno = S_tapeFsLib_ILLEGAL_FILE_SYSTEM_NAME; 	return ((TAPE_FILE_DESC *) ERROR);	/* cannot specify filename */	}    /* check the open flags for read only or write only */    if ((flags != O_RDONLY) && (flags != O_WRONLY))	{	errno = S_tapeFsLib_ILLEGAL_FLAGS; 	TAPE_DEBUG_MSG ("tapeFsOpen: Wrong Tape Mode\n", 0,0,0,0,0,0);	return ((TAPE_FILE_DESC *) ERROR);	/* cannot specify filename */	}    /* Get ownership of volume. If taken, return ERROR */    if (semTake (pTapeVol->tapevd_semId, NO_WAIT) == ERROR)		{	errno = EBUSY;			 	/* posix errno */	TAPE_DEBUG_MSG ("tapeFsOpen: Could not get Semaphore\n", 0,0,0,0,0,0);        return ((TAPE_FILE_DESC *) ERROR);	}    /* Check if file descriptor is in use */    if (pTapeFd->tapefd_inUse == TRUE)	{        errno = S_tapeFsLib_FILE_DESCRIPTOR_BUSY;	semGive (pTapeVol->tapevd_semId);	/* release volume         */	return ((TAPE_FILE_DESC *) ERROR);	/* file descriptor in use */	}    /* Call driver check-status routine, if any */    if (pSeqDev->sd_statusChk != NULL)	{	if ((* pSeqDev->sd_statusChk) (pSeqDev) != OK)	    {	    semGive (pTapeVol->tapevd_semId);	    TAPE_DEBUG_MSG ("tapeFsOpen: statusChk failed\n", 0,0,0,0,0, 0);	    return ((TAPE_FILE_DESC *) ERROR);	/* driver returned error */	    }	}    /* Check for read-only volume opened for write/update */    if ((pSeqDev->sd_mode == O_RDONLY)  && (flags == O_WRONLY ))	{	errno = S_ioLib_WRITE_PROTECTED;	semGive (pTapeVol->tapevd_semId);	TAPE_DEBUG_MSG ("tapeFsOpen: write protected. sd_mode is %x\n", 				    pSeqDev->sd_mode,0,0,0,0, 0);	return ((TAPE_FILE_DESC *) ERROR);	/* volume not writable */	}    /* fill in the rest of the tape volume fields */    pTapeFd->tapefd_mode	   = flags;    pTapeFd->tapefd_pTapeVol	   = pTapeVol;    /* Check that volume is available */    if (tapeFsVolCheck (pTapeVol) != OK)	{	semGive (pTapeVol->tapevd_semId);	errno = S_tapeFsLib_VOLUME_NOT_AVAILABLE;	TAPE_DEBUG_MSG ("tapeFsOpen: volume not available\n", 0,0,0,0,0, 0);	return ((TAPE_FILE_DESC *) ERROR);	/* cannot access volume */	}    /*      * Reserve the tape device for exclusive use unitl the file is closed.     * When the file is closed, the device should be released. Reserving the     * device disallows any other host from accessing the tape device.     */    if ((*pSeqDev->sd_reserve) (pSeqDev) != OK)	{	semGive (pTapeVol->tapevd_semId);	TAPE_DEBUG_MSG ("tapeFsOpen: reserve unit failed\n", 0,0,0,0,0, 0);	return ((TAPE_FILE_DESC *) ERROR);  /* driver returned error */	}    /* mount a tape device if not already mounted */        if (pTapeVol->tapevd_state != TAPE_VD_MOUNTED)	{	if ((*pSeqDev->sd_load) (pSeqDev, LOAD, FALSE, FALSE) != OK)	    {	    semGive (pTapeVol->tapevd_semId);	    TAPE_DEBUG_MSG ("tapeFsOpen: mount failed\n", 0,0,0,0,0, 0);	    return ((TAPE_FILE_DESC *) ERROR);  /* driver returned error */	    }        }    /* rewind if it is a rewind device */    if (pTapeVol->tapevd_rewind)	{	if ((*pSeqDev->sd_rewind) (pSeqDev) != OK)	    {	    semGive (pTapeVol->tapevd_semId);	    TAPE_DEBUG_MSG ("tapeFsOpen: rewind failed\n", 0,0,0,0,0, 0);	    return ((TAPE_FILE_DESC *) ERROR);  /* driver returned error */	    }	}    /* Read block limits */    if (pSeqDev->sd_readBlkLim != NULL)	{	if ((*pSeqDev->sd_readBlkLim) (pSeqDev, &pSeqDev->sd_maxVarBlockLimit,				       &unused) != OK)	    {	    semGive (pTapeVol->tapevd_semId);	    TAPE_DEBUG_MSG ("tapeFsOpen: readBlkLim failed\n", 0,0,0,0,0, 0);	    return ((TAPE_FILE_DESC *) ERROR);  /* driver returned error */	    }	}    /* Allocate a 1 block buffer for short reads/writes if fixed block */    if (pSeqDev->sd_blkSize != 0)	{        pTapeFd->tapefd_buffer = (char *) calloc 					((unsigned) pSeqDev->sd_blkSize, 1);        if (pTapeFd->tapefd_buffer == NULL)    	    {            semGive (pTapeVol->tapevd_semId);		/* release volume */	    TAPE_DEBUG_MSG ("tapeFsOpen: calloc failed\n", 0,0,0,0,0, 0);	    return ((TAPE_FILE_DESC *) ERROR);	/* mem alloc error */	    }        pTapeFd->tapefd_bufSize = pSeqDev->sd_blkSize;        }    pTapeFd->tapefd_inUse = TRUE;		/* fd in use      */    semGive (pTapeVol->tapevd_semId);		/* release volume */    return (pTapeFd);    }/********************************************************************************* tapeFsRead - read from a tape volume** This routine reads from the volume specified by the file descriptor* (returned by tapeFsOpen()) into the specified buffer.* `maxbytes' bytes will be read, if there is that much data in the file.** RETURNS: Number of bytes actually read, 0 if end of file, or ERROR.*/LOCAL int tapeFsRead    (    FAST TAPE_FILE_DESC * pTapeFd,      /* file descriptor pointer          */    char                * pBuf,         /* addr of input buffer             */    UINT                  maxBytes      /* count of data units to read      */    )    {    int		bytesLeft;	/* count of remaining bytes to read */    int		dataCount;	/* count of remaining bytes to read */    int		bytesRead;	/* count of bytes read              */    int		blocksRead;	/* count of bytes read              */    int		nBytes;		/* byte count from individual read  */    int		numBytes;	/* byte count from individual read  */    int		numBlks;	/* number of blocks to read         */        /* pointer to vol descriptor        */    TAPE_VOL_DESC	*pTapeVol = pTapeFd->tapefd_pTapeVol;        /* pointer to sequential device     */    SEQ_DEV	*pSeqDev = pTapeFd->tapefd_pTapeVol->tapevd_pSeqDev;        /* take control of volume */    semTake (pTapeVol->tapevd_semId, WAIT_FOREVER);         TAPE_DEBUG_MSG ("tapeFsRead: Device block size is: %d\n",		    pSeqDev->sd_blkSize, 0,0,0,0,0);        /* Check for valid length of read */        if (maxBytes <= 0)	{	semGive (pTapeVol->tapevd_semId);	errno =  S_tapeFsLib_INVALID_NUMBER_OF_BYTES;	return (ERROR);	}        /* Check that device was opened for reading */        if (pTapeFd->tapefd_mode == O_WRONLY)        {    	semGive (pTapeVol->tapevd_semId);   	/* errnoSet (S_tapeFsLib_READ_ONLY); */    	return (ERROR);    	}        /* Do successive reads until requested byte count or EOF */        bytesLeft  = maxBytes;	/* init number bytes remaining     */    dataCount  = maxBytes;        /* Variable block read */        if (pSeqDev->sd_blkSize == VARIABLE_BLOCK_SIZE)	{	while (dataCount > 0)	    {	    /* Read a variable block upto a maximum size */	    	    nBytes = (bytesLeft > pSeqDev->sd_maxVarBlockLimit) ?		     pSeqDev->sd_maxVarBlockLimit  : bytesLeft;	                if ((bytesRead = tapeFsDevRd (pTapeVol, nBytes, pBuf, 					  VARIABLE_BLK)) == ERROR)		break; 			/* do nothing, may not be an error */	                dataCount -= nBytes;            bytesLeft -= bytesRead;	    pBuf      += bytesRead;	    }	        semGive (pTapeVol->tapevd_semId);           /* release volume */        return (maxBytes - bytesLeft);              /* number of bytes read */    	}        /* Fixed block read */        while (dataCount > 0)	{	nBytes = 0;	/* init individual read count */	    	/* 	 * Do direct whole-block read, if the data is more than a blocks worth	 * and the FD buffer is empty.	 */	    	if ((dataCount >= pSeqDev->sd_blkSize) &&	    (pTapeFd->tapefd_bufIndex == 0))	    {            /* calculate number of blocks to read */	    	    numBlks = dataCount / pSeqDev->sd_blkSize;	    	    /* Read as many blocks as possible */	    	    if ((blocksRead = tapeFsDevRd (pTapeVol, numBlks, pBuf, FIXED_BLK))		== ERROR)    	    	break;		    	    numBytes = numBlks * pSeqDev->sd_blkSize;	    	    /* calculate the number of bytes read */	    	    nBytes = blocksRead * pSeqDev->sd_blkSize;	    }	        /* Handle partially read blocks (buffered) */	    	else	/* if not whole-block transfer */	    {	    if (pTapeFd->tapefd_bufIndex != 0)	        numBytes =  pSeqDev->sd_blkSize - pTapeFd->tapefd_bufIndex;	    else 	        numBytes = dataCount;	    	    if ((nBytes = tapeFsPartRd (pTapeFd, pBuf, dataCount)) == ERROR)		break;	    }		/* Adjust count remaining, buffer pointer, and file pointer */		dataCount -= numBytes;	bytesLeft -= nBytes;	pBuf      += nBytes;	}        semGive (pTapeVol->tapevd_semId);		/* release volume */    return (maxBytes - bytesLeft);  		/* number of bytes read */    }/********************************************************************************* tapeFsPartRd - read a partial tape block** This routine reads from a tape volume specified by the file descriptor,* to the specified buffer. When a partial block needs to be read, the entire* block is first read into the file descriptor buffer and then the desired* portion is copied into the specified buffer. If the number of bytes to be* read is more than that in the buffer then only the number of bytes left* in the buffer are read.** This routine calls the device driver block-reading routine directly* to read (possibly) a whole block.** RETURNS: Number of bytes read (error if != maxBytes), or* ERROR if maxBytes < 0, or can't read block.*/LOCAL int tapeFsPartRd    (    TAPE_FILE_DESC * pTapeFd,   /* pointer to a tape file descriptor      */    char *           pBuf,      /* pointer to data buffer                 */    UINT             nBytes     /* number of partial bytes to read        */

⌨️ 快捷键说明

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