📄 rawfslib.c
字号:
/********************************************************************************* rawFsReadyChange - notify rawFsLib of a change in ready status** This routine sets the volume descriptor state to RAW_VD_READY_CHANGED.* It should be called whenever a driver senses that a device has come on-line* or gone off-line, (e.g., a disk has been inserted or removed).** After this routine has been called, the next attempt to use the volume* will result in an attempted remount.** RETURNS: N/A*/void rawFsReadyChange ( RAW_VOL_DESC *pVd /* pointer to volume descriptor */ ) { pVd->rawVdState = RAW_VD_READY_CHANGED; }/********************************************************************************* rawFsReset - reset a volume** This routine calls the specified volume's reset routine, if any.* If the reset fails, rawVdState is set to (RAW_VD_CANT_RESET)* to indicate that disk won't reset.** RETURNS: OK, or ERROR if driver returned error.*/LOCAL STATUS rawFsReset ( FAST RAW_VOL_DESC *pVd /* pointer to volume descriptor */ ) { if ( cbioIoctl (pVd->rawVdCbio, CBIO_RESET, NULL) != OK) { pVd->rawVdState = RAW_VD_CANT_RESET; return (ERROR); } pVd->rawVdState = RAW_VD_RESET; return (OK); }/********************************************************************************* rawFsSeek - change file descriptor's current character position** This routine sets the specified file descriptor's current character* position to the specified position. This only changes the pointer, it* doesn't affect the hardware at all.** Attempts to set the character pointer to a negative offset (i.e. before* the start of the disk) or to a point beyond the end of the device* will return ERROR.** RETURNS: OK, or ERROR if invalid character offset.*/LOCAL STATUS rawFsSeek ( FAST RAW_FILE_DESC *pRawFd, /* file descriptor pointer */ fsize_t position /* desired character position in file */ ) { /* * Check for valid new offset. Accept any positive offset. * volume end overgoing is checked within read/write */ if (position < 0) { errnoSet (S_rawFsLib_BAD_SEEK); return (ERROR); } /* Update new file byte pointer */ pRawFd->rawFdNewPtr = 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 *pVd /* pointer to volume descriptor */ ) { FAST int status; /* return status value */ status = OK; /* init return value */ /* Check if device driver announced ready-change */ if ( cbioIoctl ( pVd->rawVdCbio, CBIO_STATUS_CHK, NULL) != OK || TRUE == cbioRdyChgdGet (pVd->rawVdCbio)) { pVd->rawVdState = RAW_VD_READY_CHANGED; } /* Check volume status */ switch (pVd->rawVdState) { case RAW_VD_MOUNTED: break; /* ready to go as is */ case RAW_VD_CANT_RESET: /* This state means we tried to reset and failed. * try again */ case RAW_VD_CANT_MOUNT: /* This state means we tried to mount and failed. * try again */ case RAW_VD_RESET: /* Volume reset but not mounted; mount */ case RAW_VD_READY_CHANGED: /* Ready change occurred; remount volume */ if (rawFsVolMount (pVd) != OK) { pVd->rawVdState = RAW_VD_CANT_MOUNT; /* can't mount */ status = ERROR; /* don't try again */ break; } pVd->rawVdState = RAW_VD_MOUNTED; /* note vol mounted */ break; } 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* Possession 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 *pVd /* pointer to volume descriptor */ ) { FAST RAW_FILE_DESC *pRawFd; /* pointer to file descriptor */ if (pVd->rawVdState != RAW_VD_MOUNTED) { return (ERROR); } /* 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->pRawFdVd == pVd) /* if correct volume */ { if (rawFsFdFlush (pRawFd) != OK) /* write Fd buffer to disk */ return (ERROR); /* error flushing buffer */ } pRawFd = (RAW_FILE_DESC *) lstNext (&pRawFd->rawFdNode); /* get next in-use Fd */ } semGive (rawFsFdListSemId); /* release Fd lists */ 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 *pVd /* pointer to volume descriptor */ ) { semTake (pVd->rawVdSemId, WAIT_FOREVER); /* get ownership of volume */ /* unmount volume prior mounting */ if (pVd->rawVdStatus == OK) { rawFsVolUnmount (pVd); } /* update new volume parameters */ if (rawFsReset (pVd) == OK) { pVd->rawVdStatus = OK; pVd->rawVdState = RAW_VD_MOUNTED; } semGive (pVd->rawVdSemId); /* release volume */ return (pVd->rawVdStatus); }/********************************************************************************* 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 *pVd /* pointer to volume descriptor */ ) { FAST RAW_FILE_DESC *pRawFd; /* pointer to file descriptor */ /* Check that volume is available */ semTake (pVd->rawVdSemId, WAIT_FOREVER); /* get ownership of volume */ /* nothing to be done, if volume was not mounted since last unmount */ if (pVd->rawVdStatus != OK) { semGive (pVd->rawVdSemId); /* release volume */ return (OK); /* cannot access volume */ } /* do not check device state before flush, let flush just fail */ /* Flush volume structures, if possible */ (void) rawFsVolFlush (pVd); /* 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->pRawFdVd == pVd) { pRawFd->rawFdStatus = RAWFD_OBSOLETE; } pRawFd = (RAW_FILE_DESC *) lstNext (&pRawFd->rawFdNode); /* get next in-use Fd */ } semGive (rawFsFdListSemId); /* release Fd lists */ /* Mark volume as no longer mounted */ rawFsReadyChange (pVd); pVd->rawVdStatus = ERROR; semGive (pVd->rawVdSemId); /* 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 specified file descriptor;* other file descriptor to the save raw device may have different character* pointer values.** RETURNS: Current character position of file descriptor.*/LOCAL fsize_t rawFsWhere ( FAST RAW_FILE_DESC *pRawFd /* file descriptor pointer */ ) { return (pRawFd->rawFdNewPtr); }/********************************************************************************* rawFsRead - read from a raw volume** This routine reads from the volume specified by the file descriptor* (returned by rawFsOpen()) into the specified buffer.* <maxbytes> bytes will be read, if there is that much data in the file.** RETURNS: Number of bytes actually read, or 0 if end of file, or ERROR.*/LOCAL int rawFsRead ( FAST RAW_FILE_DESC *pRawFd, /* file descriptor pointer */ char *pBuf, /* addr of input buffer */ int maxBytes /* maximum bytes to read into buffer */ ) { return rawFdRdWr (pRawFd, pBuf, maxBytes, CBIO_READ); } /********************************************************************************* 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 */ ) { return rawFdRdWr (pRawFd, pBuf, maxBytes, CBIO_WRITE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -