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

📄 dosfslib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
** RETURNS: STATUS as result of semGive.*/LOCAL STATUS dosFsFSemGive    (    DOS_FILE_DESC_ID	pFd    )    {    STATUS retStat;     assert( pFd - pFd->pVolDesc->pFdList < pFd->pVolDesc->maxFiles );    assert( pFd->pFileHdl - pFd->pVolDesc->pFhdlList <            pFd->pVolDesc->maxFiles );     retStat =  semGive( *(pFd->pVolDesc->pFsemList +     		       (pFd->pFileHdl - pFd->pVolDesc->pFhdlList)));    assert( retStat == OK );    return retStat;    } /* dosFsFSemGive() */    /********************************************************************************* dosFsVolUnmount - unmount a dosFs volume** This routine is called when I/O operations on a volume are to be* discontinued.  This is the preferred action prior to changing a* removable disk.** All buffered data for the volume is written to the device* (if possible, with no error returned if data cannot be written),* any open file descriptors are marked as obsolete,* and the volume is marked as not currently mounted.** When a subsequent open() operation is initiated on the device,* new volume will be mounted automatically.** Once file descriptors have been marked as obsolete, any attempt to* use them for file operations will return an error.  (An obsolete file* descriptor may be freed by using close().  The call to close() will* return an error, but the descriptor will in fact be freed).** This routine may also be invoked by calling ioctl() with the* FIOUNMOUNT function code.** This routine must not be called from interrupt level.** RETURNS: OK, or ERROR if the volume was not mounted.** NOMANUAL*/STATUS dosFsVolUnmount    (    void *	pDevNameOrPVolDesc	/* device name or ptr to */    					/* volume descriptor */    )    {    DOS_VOLUME_DESC_ID	pVolDesc;	/* pointer to volume descriptor */    int i;        /* get volume descriptor */        pVolDesc = dosFsVolDescGet( pDevNameOrPVolDesc, NULL );    if( pVolDesc == NULL )    	return ERROR;        if( ! pVolDesc->mounted )    	return ERROR;        /* acquire semaphore */        if( semTake( pVolDesc->devSem, WAIT_FOREVER ) == ERROR )    	return ERROR;        /* mark all opened file descriptors as obsolete */    /* also synchronize the FAT and do not hold the */    /* file semaphore, in certain operations like   */    /* rename-file the file semaphore is locked     */    /* before devSem. Trying to hold file semaphore */    /* , after holding devSem, will cause dead-lock */     for( i = 0; i < pVolDesc->maxFiles; i ++ )    	{   	if( pVolDesc->pFdList[ i ].busy )	    {	    /* Synchronize the FAT */	    pVolDesc->pFatDesc->flush(&pVolDesc->pFdList[i]);    	    pVolDesc->pFdList[ i ].pFileHdl->obsolet = 1;	    }    	}    pVolDesc->nBusyFd = 0;        /* flush buffers */        cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_FLUSH, (void*)(-1) );    cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_INVAL, 0 );        pVolDesc->mounted = FALSE;	/* volume unmounted */        semGive( pVolDesc->devSem );    return OK;    } /* dosFsVolUnmount() */    /********************************************************************************* dosFsChkDsk - make volume integrity checking.** This library does not makes integrity check process itself, but* instead uses routine provided by dosChkLib. * This routine prepares parameters and invokes checking routine* via preinitialized function pointer. If dosChkLib does not configured* into vxWorks, this routine returns ERROR.** Ownership on device should be taken by an upper level routine.** RETURNS: STATUS as returned by volume checking routine or*  ERROR, if such routine does not installed.** ERRNO:* S_dosFsLib_UNSUPPORTED.*/STATUS dosFsChkDsk    (    FAST DOS_FILE_DESC_ID	pFd, /* file descriptor of root dir */    u_int	params		     /* check level and verbosity */    )    {    DOS_VOLUME_DESC_ID	pVolDesc = pFd->pVolDesc;    CBIO_DEV_ID	cbio =  pFd->pVolDesc->pCbio;    STATUS	retVal = ERROR;        if( dosFsChkRtn == NULL )        {    	errnoSet( S_dosFsLib_UNSUPPORTED );	ERR_MSG(1,"Check disk utility not installed\n", 0,0,0,0,0,0 );    	return ERROR;        }    /* prepare check disk parameters */        if( (params & 0xff) == 0 )    	params |= DOS_CHK_ONLY;        /* prevent attempts to write on read only volume */        cbioIoctl(cbio, CBIO_STATUS_CHK, 0 );    if( cbioModeGet(cbio) == O_RDONLY )        {	/* avoid writing to O_RDONLY devices */        params = (params & ~0xff) | DOS_CHK_ONLY;        }    pVolDesc->chkLevel = min( params & 0xff, DOS_CHK_REPAIR );    pVolDesc->chkVerbLevel =     	    ( (params & 0xff00) == DOS_CHK_VERB_0 )? 0 : params >> 8;        /* run disk check */        retVal = dosFsChkRtn( pFd );        if(params == ((params & ~0xff) | DOS_CHK_ONLY))        {        cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_FLUSH, (void *)(-1) );        cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_INVAL, 0 );        }    	        pVolDesc->chkLevel = 0;    pVolDesc->chkVerbLevel = 0;    	        /* reset dcache driver to recount boot block checksum */    if( TRUE == cbioRdyChgdGet (pVolDesc->pCbio) )    	{    	retVal = ERROR; /* volume was changed during check disk */    	}    else	    	{     	cbioIoctl( pVolDesc->pCbio, CBIO_RESET, NULL );    	}    	    	    return retVal;    } /* dosFsChkDsk() *//********************************************************************************* dosFsBadBootMsg - print error message while boot sector parsing.** RETURNS: N/A.*/LOCAL void dosFsBadBootMsg    (    u_int	dbgLevel, 	/* message level */    u_int	offset,		/* offset of invalid field */    u_int	val,		/* invalid value */    char *	pExtraMsg,	/* extra message */    u_int	line		/* line number of error detecting code */    )    {#ifdef DEBUG    printErr( "%s : %u. Malformed boot sector. Offset %u, value %u. %s\n",    	      __FILE__, __LINE__, offset, val,	      ( (pExtraMsg == NULL)? " " : pExtraMsg ) );#else /* not DEBUG */    ERR_MSG( dbgLevel, "Malformed boot sector. Offset %u, value %u. %s\n",	     offset, val, ( (pExtraMsg == NULL)? " " : pExtraMsg ), 0,0,0 ); #endif /* DEBUG */    }    /********************************************************************************* dosFsBootSecGet - extract boot sector parameters.** This routine reads boot sector from the disk and extracts* current volume parameters from of it.** This routine also performs sanity check of those volume parameters,* that are mutually dependent or alternative.* * This routine also determines the FAT type: FAT32, FAT12, or FAT16.** If read or damaged boot sector is encountered, this routine* searches for backup copy of boot sector and accepts volume* volume configuration from this copy.,** RETURNS: OK or ERROR if disk read error or inconsistent* boot sector data or failure to obtain cbio parameters.** ERRNO:* S_dosFsLib_UNKNOWN_VOLUME_FORMAT*/LOCAL STATUS dosFsBootSecGet    (    DOS_VOLUME_DESC_ID	pVolDesc	/* pointer to volume descriptor */    )    {    CBIO_PARAMS cbioParams;    u_int	work;    u_char	bootSec[ 512 ] = { 0 }; /* buffer for boot sector data */    u_char	pass = 0;    u_char      tmpType [ DOS_BOOT_FSTYPE_LEN + 1] = { 0 };    pVolDesc->bootSecNum = DOS_BOOT_SEC_NUM;  /* zero, per FAT standard */boot_get:        /* reset the CBIO device in order to synchronize the boot sector */    if( cbioIoctl(pVolDesc->pCbio, CBIO_RESET, 0 ) == ERROR )    	{    	return ERROR;    	}    /* request the underlying CBIO device parameters */    if (ERROR == cbioParamsGet (pVolDesc->pCbio, &cbioParams))	{	return (ERROR);	}    /* ensure bytesPerBlk is non-zero */    if (0 == cbioParams.bytesPerBlk)	{    	ERR_MSG( 1, "cbioParams.bytesPerBlk cannot be zero.\n", 		0,0,0,0,0,0 );    	if( TRUE == cbioRdyChgdGet (pVolDesc->pCbio) )            {	    return (ERROR);            }    	goto error;	}    /* read relevant boot sector data into bootSec[] */    work = min( cbioParams.bytesPerBlk, (int) sizeof(bootSec) );    if( cbioBytesRW(pVolDesc->pCbio, pVolDesc->bootSecNum, 0 /* offset */,    	    	     (addr_t)bootSec, work, CBIO_READ, NULL ) == ERROR )     	{    	ERR_MSG( 1, "ERROR reading the device boot sector\n", 0,0,0,0,0,0 );    	ERR_MSG( 1, "media not formatted or not present\n", 0,0,0,0,0,0 );    	if( TRUE == cbioRdyChgdGet (pVolDesc->pCbio) )            {	    return (ERROR);            }    	goto error;    	}    /* check for both acceptable Intel 80x86 `jmp' opcodes */    if( bootSec[ DOS_BOOT_JMP ] != 0xe9 && bootSec[ DOS_BOOT_JMP ] != 0xeb )    	{    	dosFsBadBootMsg( 1, DOS_BOOT_JMP, (u_int)bootSec[ DOS_BOOT_JMP ],			 NULL , __LINE__);        goto error;        }    /*      * Many FAT documents mistakenly state that the 0x55aa signature word     * "occupies the last two bytes of the boot sector".  That is only true      * when the bytes-per-sector value is 512 bytes.  Microsoft defines the      * signature at offsets 510 and 511 (zero-based) regardless of the sector      * size.  It is acceptable, however to have the signature at the end of the      * sector.  We shall accept either location. SPR#62415.     */    /* read the ending 2 bytes of the sector to check signature */    if( cbioBytesRW(pVolDesc->pCbio, pVolDesc->bootSecNum,            cbioParams.bytesPerBlk - 2 /* off */,            (addr_t)&work, 2, CBIO_READ, NULL ) == ERROR )         {    	ERR_MSG( 1, "ERROR reading boot sector\n", 0,0,0,0,0,0 );    	if( TRUE == cbioRdyChgdGet (pVolDesc->pCbio) )            {	    return (ERROR);            }    	goto error;    	}    work = DISK_TO_VX_16( &work );    if (0xaa55 != work) /* why have a back door? "&& (work != 0xface)") */        {	/* 	 * We did not find the signature word at the end of the sector,	 * so we will check at the 510/511 offset per the Microsoft FAT spec. 	 * If we cannot find it there, then assume the boot sector is bad.	 */        if ((bootSec[510] != 0x55) || (bootSec[511] != 0xaa))	    {	    dosFsBadBootMsg( 1, cbioParams.bytesPerBlk - 2,			     work, "At the end of boot sector", __LINE__ );            goto error;	    }        }    /*      * Start filling out and verifying the volume descriptor fields      * using the data from the boot parameter block.  Evaluate the validity     * of the data, so that dosFsVolIsFat12() may be safely called.     */    /* evaluate bytes per sector */        work = DISK_TO_VX_16( bootSec + DOS_BOOT_BYTES_PER_SEC );    pVolDesc->bytesPerSec = work;    if( work == 0 )

⌨️ 快捷键说明

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