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

📄 rawfslib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
    )    {    FAST BLK_DEV	*pBlkDev;	/* ptr to blkock dev structure */    /* Check for valid new offset */    pBlkDev = pRawFd->rawfd_vdptr->rawvd_pBlkDev;    if (position < 0  ||	(position / pBlkDev->bd_bytesPerBlk) >= pBlkDev->bd_nBlocks)	{	errnoSet (S_rawFsLib_BAD_SEEK);	return (ERROR);	}    /* Update new file byte pointer */    pRawFd->rawfd_newptr = position;    return (OK);    }/********************************************************************************* rawFsVolCheck - verify that volume descriptor is current** This routine is called at the beginning of most operations on* the device.  The status field in the volume descriptor is examined,* and the appropriate action is taken.  In particular, the disk is* mounted if it is currently unmounted or a ready-change has occurred.** If the disk is already mounted or is successfully mounted as a* result of this routine calling rawFsVolMount, this routine returns* OK.  If the disk cannot be mounted, ERROR is returned.** RETURNS: OK, or ERROR.*/LOCAL STATUS rawFsVolCheck    (    FAST RAW_VOL_DESC   *vdptr          /* pointer to volume descriptor   */    )    {    FAST int		status;		/* return status value */    status = OK;				/* init return value */    /* Check if device driver announced ready-change */    if (vdptr->rawvd_pBlkDev->bd_readyChanged)	{	vdptr->rawvd_state = RAW_VD_READY_CHANGED;	vdptr->rawvd_pBlkDev->bd_readyChanged = FALSE;	}    /* Check volume status */    switch (vdptr->rawvd_state)	{	case RAW_VD_CANT_RESET:	    /* This state means we tried to reset and failed so we	     * don't try again until a ready change occurs	     */	    status = ERROR;			/* can't reset */	    break;	case RAW_VD_CANT_MOUNT:	    /* This state means we tried to mount and failed so we	     * don't try again until a ready change occurs	     */	    status = ERROR;			/* can't mount */	    break;	case RAW_VD_READY_CHANGED:	    /* Ready change occurred; try to reset volume */	    if (rawFsReset (vdptr) != OK)		{		status = ERROR;			/* can't reset */		break;		}	    vdptr->rawvd_state = RAW_VD_RESET;	/* note volume reset */	    /* Fall-through to try to mount */	case RAW_VD_RESET:	    /* Volume reset but not mounted; try mount */	    if (rawFsVolMount (vdptr) != OK)		{		vdptr->rawvd_state = RAW_VD_CANT_MOUNT; /* can't mount */		status = ERROR;			 	/* don't try again */		break;		}	    vdptr->rawvd_state = RAW_VD_MOUNTED;	/* note vol mounted */	    break;	case RAW_VD_MOUNTED:	    break;				/* ready to go as is */	}    return (status);				/* return status value */    }/********************************************************************************* rawFsVolFlush - flush raw volume to disk** This routine guarantees that any changes to the volume are actually* written to disk.  Since there are no data structures kept on disk,* the only possible changes are the file descriptor read/write buffers.** INTERNAL* Posession of the volume descriptor's semaphore must have been secured* before this routine is called.** RETURNS: OK, or ERROR.*/LOCAL STATUS rawFsVolFlush    (    FAST RAW_VOL_DESC   *vdptr          /* pointer to volume descriptor */    )    {    FAST RAW_FILE_DESC	*pRawFd;	/* pointer to file descriptor */    /* Flush all modified file descriptor I/O buffers to disk */    semTake (rawFsFdListSemId, WAIT_FOREVER);	/* take control of Fd lists */    pRawFd = (RAW_FILE_DESC *) lstFirst (&rawFsFdActiveList);						/* get first in-use Fd */    while (pRawFd != NULL)	{	if (pRawFd->rawfd_vdptr == vdptr)	/* if correct volume */	    {	    if (rawFsFdFlush (pRawFd) != OK)	/* write Fd buffer to disk */	    	return (ERROR);			/* error flushing buffer */	    }	pRawFd = (RAW_FILE_DESC *) lstNext (&pRawFd->rawfd_node);						/* get next in-use Fd */	}    semGive (rawFsFdListSemId);			/* release Fd lists */    vdptr->rawvd_status = OK;    return (OK);    }/********************************************************************************* rawFsVolMount - prepare to use raw volume** This routine prepares the library to use the raw volume on the device* specified.** This routine should be called every time a disk is changed (i.e. a floppy* is swapped, or whatever), or before every open and create, if the driver* can't tell when disks are changed.** RETURNS: OK or ERROR.*/LOCAL STATUS rawFsVolMount    (    FAST RAW_VOL_DESC   *vdptr          /* pointer to volume descriptor */    )    {    vdptr->rawvd_status = OK;    return (OK);    }/********************************************************************************* rawFsVolUnmount - disable a raw device volume** This routine is called when I/O operations on a volume are to be* discontinued.  This is commonly done before changing removable disks.* All buffered data for the volume is written to the device (if possible),* any open file descriptors are marked as obsolete, and the volume is* marked as not mounted.** Because this routine will flush data from memory to the physical* device, it should not be used in situations where the disk-change is* not recognized until after a new disk has been inserted.  In these* circumstances, use the ready-change mechanism.  (See the manual entry for * rawFsReadyChange().)** This routine may also be called by issuing an ioctl() call using the* \%FIOUNMOUNT function code.** RETURNS: OK, or ERROR if the routine cannot access the volume.** SEE ALSO: rawFsReadyChange()*/STATUS rawFsVolUnmount    (    FAST RAW_VOL_DESC   *vdptr          /* pointer to volume descriptor */    )    {    FAST RAW_FILE_DESC	*pRawFd;	/* pointer to file descriptor */    /* Check that volume is available */    semTake (vdptr->rawvd_semId, WAIT_FOREVER);	/* get ownership of volume */    if ((rawFsVolCheck (vdptr) != OK) || (vdptr->rawvd_status != OK))        {        semGive (vdptr->rawvd_semId);		/* release volume */        errnoSet (S_rawFsLib_VOLUME_NOT_AVAILABLE);        return (ERROR);				/* cannot access volume */        }    /* Flush volume structures, if possible */    (void) rawFsVolFlush (vdptr);			/* flush volume */    /* Mark any open file descriptors as obsolete */    semTake (rawFsFdListSemId, WAIT_FOREVER);	/* take control of Fd lists */    pRawFd = (RAW_FILE_DESC *) lstFirst (&rawFsFdActiveList);						/* get first in-use Fd */    while (pRawFd != NULL)	{	if (pRawFd->rawfd_vdptr == vdptr)	    {	    pRawFd->rawfd_status = RAWFD_OBSOLETE;	    }	pRawFd = (RAW_FILE_DESC *) lstNext (&pRawFd->rawfd_node);						/* get next in-use Fd */	}    semGive (rawFsFdListSemId);			/* release Fd lists */    /* Mark volume as no longer mounted */    rawFsReadyChange (vdptr);    semGive (vdptr->rawvd_semId);		/* release volume */    return (OK);    }/********************************************************************************* rawFsWhere - return current character position on raw device** This routine tells you where the character pointer is for a raw device.* This character position applies only to the specifed file descriptor;* other file descriptor to the save raw device may have different character* pointer values.** RETURNS: Current character position of file descriptor.*/LOCAL int rawFsWhere    (    FAST RAW_FILE_DESC *pRawFd  /* file descriptor pointer */    )    {    return (pRawFd->rawfd_newptr);    }/********************************************************************************* rawFsWrite - write to a raw volume** This routine writes to the raw volume specified by the file descriptor* from the specified buffer.  If the block containing the disk locations* to be written is already in the file descriptor's read/write buffer,* the buffer won't be flushed.  If another in-memory block is needed,* any block already in memory will be flushed.** This routine calls the device driver block-writing routine directly* to write (possibly multiple) whole blocks.** RETURNS: Number of bytes written (error if != maxBytes), or* ERROR if maxBytes < 0, or no more space for the file,* or can't write block.*/LOCAL int rawFsWrite    (    FAST RAW_FILE_DESC  *pRawFd,        /* file descriptor pointer */    char                *pBuf,          /* data to be written */    int                 maxBytes        /* number of bytes to write */    )    {    FAST int		nBytes;		/* byte count for individual write */    FAST int		bufIndex;	/* position it file I/O buffer */    FAST int		blkNum;		/* starting block for write */    FAST int		numBlks;	/* number of blocks to write */    FAST RAW_VOL_DESC	*vdptr = pRawFd->rawfd_vdptr;					/* pointer to vol descriptor */    FAST BLK_DEV	*pBlkDev = pRawFd->rawfd_vdptr->rawvd_pBlkDev;					/* pointer to block device info */    FAST int		bytesLeft;	/* remaining bytes to write */    semTake (pRawFd->rawfd_semId, WAIT_FOREVER); /* take control of fd */    /* Check that file descriptor is current */    if (pRawFd->rawfd_status == RAWFD_OBSOLETE)	{	semGive (pRawFd->rawfd_semId);	errnoSet (S_rawFsLib_FD_OBSOLETE);	return (ERROR);	}    /* Check that device was opened for writing */    if (pRawFd->rawfd_mode == O_RDONLY)	{	semGive (pRawFd->rawfd_semId);        errnoSet (S_rawFsLib_READ_ONLY);	return (ERROR);	}    /* Check for valid length of write */    if (maxBytes < 0)	{	semGive (pRawFd->rawfd_semId);	errnoSet (S_rawFsLib_INVALID_NUMBER_OF_BYTES);	return (ERROR);	}    /* Write into successive blocks until all of caller's buffer written */    semTake (vdptr->rawvd_semId, WAIT_FOREVER);	/* take control of volume */    bytesLeft = maxBytes;    while (bytesLeft > 0)	{	nBytes = 0;				/* init individual write count*/	/* Do direct whole-block write if possible */	if ((bytesLeft >= pBlkDev->bd_bytesPerBlk) &&	    (pRawFd->rawfd_newptr % pBlkDev->bd_bytesPerBlk == 0))	    {	    /* Calculate starting block and number to write */	    blkNum = pRawFd->rawfd_newptr / pBlkDev->bd_bytesPerBlk;	    numBlks = bytesLeft / pBlkDev->bd_bytesPerBlk;	    /* Adjust if write would extend past end of device */	    numBlks = min (numBlks, (pBlkDev->bd_nBlocks - blkNum));	    if (numBlks == 0)		{		errnoSet (S_rawFsLib_END_OF_DEVICE);		break;		}	    /* Write blocks */	    if (rawFsBlkWrt (vdptr, blkNum, numBlks, pBuf) != OK)		break;	    /* If write included buffered block, invalidate buffer */	    if ((pRawFd->rawfd_bufBlk >= blkNum)  &&	    	(pRawFd->rawfd_bufBlk < (blkNum + numBlks)))		{		pRawFd->rawfd_bufBlk = NONE;    		pRawFd->rawfd_modified = FALSE;		}	    nBytes = (numBlks * pBlkDev->bd_bytesPerBlk);	    }	else	    {	    /* Get block containing new pointer into buffer */	    if (rawFsBlkNew (pRawFd) <= 0)		break;					/* disk full */	    /* Copy length = rest of caller's buffer or rest of file I/O buffer,	     *   whichever is less.	     */	    bufIndex = pRawFd->rawfd_newptr % pBlkDev->bd_bytesPerBlk;	    nBytes = min (bytesLeft, pBlkDev->bd_bytesPerBlk - bufIndex);	    bcopy (pBuf, &pRawFd->rawfd_buffer [bufIndex], nBytes);	    pRawFd->rawfd_modified = TRUE;	    }	/* Update pointers and bytes remaining */	pRawFd->rawfd_newptr += nBytes;	pBuf += nBytes;	bytesLeft -= nBytes;	}    semGive (vdptr->rawvd_semId);		/* release volume */    semGive (pRawFd->rawfd_semId);		/* release fd */    return (maxBytes - bytesLeft);		/* return actual copy count */    }/******************************************************************************/

⌨️ 快捷键说明

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