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

📄 rawfslib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
/* rawFsLib.c - raw block device file system library *//* Copyright 1984-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01p,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).01o,29sep98,lrn  merged mod 01n for T2.x, fixed copyright01n,30oct97,wil  SPR# 9418: added check for new position past end of device to                  rawFsRead().01m,27jan93,jdi  documentation cleanup for 5.1; added 3rd param to ioctl()		 examples.01l,02oct92,srh  added ioctl(FIOGETFL) to return file's open mode01k,22jul92,kdl  changed from 4.0.2-style semaphores to mutexes.01j,18jul92,smb  Changed errno.h to errnoLib.h.01i,04jul92,jcf  scalable/ANSI/cleanup effort.01h,26may92,rrr  the tree shuffle01g,16dec91,gae  added includes for ANSI.01f,19nov91,rrr  shut up some ansi warnings.01e,04oct91,rrr  passed through the ansification filter                  -changed functions to ansi style		  -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY and ...		  -changed VOID to void		  -changed copyright notice01d,05apr91,jdi	 documentation -- removed header parens and x-ref numbers;		 doc review by kdl.01c,21feb91,jaa	 documentation cleanup.01b,08oct90,kdl  lint.01a,02oct90,kdl  written*//*This library provides basic services for disk devices that do notuse a standard file or directory structure.  The disk volume is treatedmuch like a large file.  Portions of it may be read, written, or thecurrent position within the disk may be changed.  However, thereis no high-level organization of the disk into files or directories.USING THIS LIBRARYThe various routines provided by the VxWorks raw "file system" (rawFs) maybe separated into three broad groups: general initialization,device initialization, and file system operation.The rawFsInit() routine is the principal initialization function;it need only be called once, regardless of how many rawFs deviceswill be used.A separate rawFs routine is used for device initialization.  Foreach rawFs device, rawFsDevInit() must be called to install the device.Several routines are provided to inform the file system ofchanges in the system environment.  The rawFsModeChange() routine may beused to modify the readability or writability of a particular device.The rawFsReadyChange() routine is used to inform the file system that adisk may have been swapped and that the next disk operation should firstremount the disk.  The rawFsVolUnmount() routine informs thefile system that a particular device should be synchronized and unmounted,generally in preparation for a disk change.INITIALIZATIONBefore any other routines in rawFsLib can be used, rawFsInit() must be called to initialize the library.  This call specifies themaximum number of raw device file descriptors that can be opensimultaneously and allocates memory for that many raw file descriptors.Any attempt to open more raw device file descriptors than the specifiedmaximum will result in errors from open() or creat().During the rawFsInit() call, the raw device library is installed as a driverin the I/O system driver table.  The driver number associated with it isthen placed in a global variable, `rawFsDrvNum'.This initialization is enabled when the configuration macro INCLUDE_RAWFSis defined; rawFsInit() is then called from the root task, usrRoot(), inusrConfig.c.DEFINING A RAW DEVICETo use this library for a particular device, the device structureused by the device driver must contain, as the very first item, ablock device description structure (BLK_DEV).  This must be initializedbefore calling rawFsDevInit().  In the BLK_DEV structure, the driver includesthe addresses of five routines it must supply:  one that reads oneor more blocks, one that writes one or more blocks, one that performsI/O control (ioctl()) on the device, one that checks the status of thethe device, and one that resets the device.  The BLK_DEV structure alsocontains fields that describe the physical configuration of the device.  Formore information about defining block devices, see the .I "VxWorks Programmer's Guide: I/O System."The rawFsDevInit() routine is used to associate a device with the rawFsLibfunctions.  The <volName> parameter expected by rawFsDevInit() is a pointer toa name string, to be used to identify the device.  This will serve asthe pathname for I/O operations which operate on the device.  Thisname will appear in the I/O system device table, which may be displayedusing iosDevShow().The <pBlkDev> parameter that rawFsDevInit() expects is a pointerto the BLK_DEV structure describing the device and contains theaddresses of the required driver functions.  The syntax of the rawFsDevInit()routine is as follows:.CS    rawFsDevInit	(	char     *volName,  /@ name to be used for volume   @/	BLK_DEV  *pBlkDev   /@ pointer to device descriptor @/	).CEUnlike the VxWorks DOS and RT-11 file systems, raw volumes do notrequire an \%FIODISKINIT ioctl() function to initialize volume structures.(Such an ioctl() call can be made for a raw volume, but it has no effect.)As a result, there is no "make file system" routine for raw volumes(for comparison, see the manual entries for dosFsMkfs() and rt11Mkfs()).When rawFsLib receives a request from the I/O system, after rawFsDevInit()has been called, it calls the device driver routines (whose addresses werepassed in the BLK_DEV structure) to access the device.MULTIPLE LOGICAL DEVICESThe block number passed to the block read and write routines is an absolutenumber, starting from block 0 at the beginning of the device.  If desired,the driver may add an offset from the beginning of the physical devicebefore the start of the logical device.  This would normally be done bykeeping an offset parameter in the driver's device-specific structure,and adding the proper number of blocks to the block number passed to the readand write routines.  See the ramDrv manual entry for an example.UNMOUNTING VOLUMES (CHANGING DISKS)A disk should be unmounted before it is removed.  When unmounted,any modified data that has not been written to the disk will be writtenout.  A disk may be unmounted by either calling rawFsVolUnmount() directlyor calling ioctl() with a FIODISKCHANGE function code.There may be open file descriptors to a raw device volume when it isunmounted.  If this is the case, those file descriptors will be markedas obsolete.  Any attempts to use them for further I/O operations willreturn an S_rawFsLib_FD_OBSOLETE error.  To free such file descriptors, use theclose() call, as usual.  This will successfully free the descriptor,but will still return S_rawFsLib_FD_OBSOLETE.SYNCHRONIZING VOLUMESA disk should be "synchronized" before it is unmounted.  To synchronize adisk means to write out all buffered data (the write buffers associatedwith open file descriptors), so that the disk is updated.  It mayor may not be necessary to explicitly synchronize a disk, depending onhow (or if) the driver issues the rawFsVolUnmount() call.When rawFsVolUnmount() is called, an attempt will be made to synchronize thedevice before unmounting.  However, if the rawFsVolUnmount() call is made bya driver in response to a disk being removed, it is obviously too late tosynchronize.  Therefore, a separate ioctl() call specifying the FIOSYNCfunction should be made before the disk is removed.  (This could be done inresponse to an operator command.)If the disk will still be present and writable when rawFsVolUnmount() iscalled, it is not necessary to first synchronize the disk.  Inall other circumstances, failure to synchronize the volume beforeunmounting may result in lost data.IOCTL FUNCTIONSThe VxWorks raw block device file system supports the following ioctl()functions.  The functions listed are defined in the header ioLib.h..iP "FIODISKFORMAT" 16 3Formats the entire disk with appropriate hardware track and sector marks.No file system is initialized on the disk by this request.Note that this is a driver-provided function:.CS    fd = open ("DEV1:", O_WRONLY);    status = ioctl (fd, FIODISKFORMAT, 0);.CE.iP "FIODISKINIT"Initializes a raw file system on the disk volume.Since there are no file system structures, this functions performs no action.It is provided only for compatibility with other VxWorks file systems..iP "FIODISKCHANGE"Announces a media change.  It performs the same function as rawFsReadyChange().This function may be called from interrupt level:.CS    status = ioctl (fd, FIODISKCHANGE, 0);.CE.iP "FIOUNMOUNT"Unmounts a disk volume.  It performs the same function as rawFsVolUnmount().This function must not be called from interrupt level:.CS    status = ioctl (fd, FIOUNMOUNT, 0);.CE.iP "FIOGETNAME"Gets the file name of the file descriptor and copies it to the buffer <nameBuf>:.CS    status = ioctl (fd, FIOGETNAME, &nameBuf);.CE.iP "FIOSEEK"Sets the current byte offset on the disk to the position specifiedby <newOffset>:.CS    status = ioctl (fd, FIOSEEK, newOffset);.CE.iP "FIOWHERE"Returns the current byte position from the start of the devicefor the specified file descriptor.This is the byte offset of the next byte to be read or written.It takes no additional argument:.CS    position = ioctl (fd, FIOWHERE, 0);.CE.iP "FIOFLUSH"Writes all modified file descriptor buffers to the physical device..CS    status = ioctl (fd, FIOFLUSH, 0);.CE.iP "FIOSYNC"Performs the same function as FIOFLUSH..iP "FIONREAD"Copies to <unreadCount> the number of bytes from the current file positionto the end of the device:.CS    status = ioctl (fd, FIONREAD, &unreadCount);.CE.LPINCLUDE FILES: rawFsLib.hSEE ALSO: ioLib, iosLib, dosFsLib, rt11FsLib, ramDrv,.pG "I/O System, Local File Systems"*//* LINTLIBRARY */#include "vxWorks.h"#include "ctype.h"#include "ioLib.h"#include "lstLib.h"#include "stdlib.h"#include "string.h"#include "semLib.h"#include "errnoLib.h"#include "rawFsLib.h"/* Raw device file descriptor */typedef struct		/* RAW_FILE_DESC */    {    NODE	rawfd_node;		/* linked list node info */    SEM_ID	rawfd_semId;		/* semaphore for this file descriptor */    int		rawfd_status;		/* (OK | NOT_IN_USE) */    RAW_VOL_DESC *rawfd_vdptr;		/* ptr to volume descriptor */    int		rawfd_mode;		/* mode: O_RDONLY, O_WRONLY, O_RDWR */    UINT	rawfd_curptr;		/* file byte ptr of I/O buffer byte 0 */    UINT	rawfd_newptr;		/* file byte ptr for new read/writes */    UINT	rawfd_endptr;		/* file byte ptr to end of file */    BOOL	rawfd_modified;		/* TRUE = buffer has been modified */    char	*rawfd_buffer;		/* pointer to read/write buffer area */    int		rawfd_bufBlk;		/* number of block in I/O buffer */    } RAW_FILE_DESC;/* File descriptor status values */#define RAWFD_AVAILABLE		-1	/* file descriptor available */#define RAWFD_IN_USE		0	/* file descriptor in-use */#define RAWFD_OBSOLETE		1	/* file descriptor obsolete *//* GLOBALS */int 	rawFsDrvNum   = ERROR;	   /* I/O system driver number for rawFsLib */					/* default mutex options */int	rawFsVolMutexOptions    = (SEM_Q_PRIORITY | SEM_DELETE_SAFE);int	rawFsFdListMutexOptions = (SEM_Q_PRIORITY | SEM_DELETE_SAFE);int	rawFsFdMutexOptions     = (SEM_Q_PRIORITY | SEM_DELETE_SAFE);/* LOCALS */LOCAL LIST		rawFsFdActiveList;	/* linked list of in-use Fd's */LOCAL LIST		rawFsFdFreeList;	/* linked list of avail. Fd's */LOCAL SEM_ID 		rawFsFdListSemId;	/* file descr list semaphore  */LOCAL int 		rawFsMaxFiles;		/* max files open at once     *//* forward static functions */static int	rawFsBlkNew (RAW_FILE_DESC *pRawFd);static STATUS	rawFsBlkRd (RAW_VOL_DESC *vdptr, int startBlk, int numBlks,			    char *pBuf);static STATUS	rawFsBlkWrt (RAW_VOL_DESC *vdptr, int startBlk, int numBlks,			     char *pBuf);static STATUS	rawFsClose (RAW_FILE_DESC *pRawFd);static STATUS	rawFsFdFlush (RAW_FILE_DESC *pRawFd);static void	rawFsFdFree (RAW_FILE_DESC *pRawFd);static RAW_FILE_DESC *rawFsFdGet (void);static STATUS	rawFsFlush (RAW_VOL_DESC *vdptr);static STATUS	rawFsIoctl (RAW_FILE_DESC *pRawFd, int function, int arg);static RAW_FILE_DESC *rawFsOpen (RAW_VOL_DESC *vdptr, char *name, int flags);static int	rawFsRead (RAW_FILE_DESC *pRawFd, char *pBuf, int maxBytes);static STATUS	rawFsReset (RAW_VOL_DESC *vdptr);static STATUS	rawFsSeek (RAW_FILE_DESC *pRawFd, int position);static STATUS	rawFsVolCheck (RAW_VOL_DESC *vdptr);static STATUS	rawFsVolFlush (RAW_VOL_DESC *vdptr);static STATUS	rawFsVolMount (RAW_VOL_DESC *vdptr);static int	rawFsWhere (RAW_FILE_DESC *pRawFd);static int	rawFsWrite (RAW_FILE_DESC *pRawFd, char *pBuf, int maxBytes);/********************************************************************************* rawFsBlkNew - make file descriptor buffer contain new block** This routine does whatever is necessary to make the block buffer* of the specified file descriptor contain the byte addressed by* the current pointer in the descriptor.  In particular, if on entry* the buffer already contains the desired byte, then no action is taken.* Otherwise if the buffer is modified (contains data written by user* but not yet on disk) then the block is written.  Then the correct* block is read if the mode is O_RDONLY or O_RDWR.** RETURNS:* Number of bytes in buffer if successful, or* 0 if end of file, or* ERROR if unable to read/write block.*/LOCAL int rawFsBlkNew    (    FAST RAW_FILE_DESC  *pRawFd         /* file descriptor pointer */    )    {    FAST int		curBlkNum;	/* current block in buffer */    FAST int		newBlkNum;	/* new block number */    FAST RAW_VOL_DESC	*vdptr = pRawFd->rawfd_vdptr;					/* pointer to volume descriptor */    FAST BLK_DEV	*pBlkDev = pRawFd->rawfd_vdptr->rawvd_pBlkDev;					/* pointer to block device info */    /* Calculate num of desired new block and of current block */    newBlkNum = pRawFd->rawfd_newptr / pBlkDev->bd_bytesPerBlk;    curBlkNum = pRawFd->rawfd_curptr / pBlkDev->bd_bytesPerBlk;    /* Check if new block already in current buffer */    if ((newBlkNum == curBlkNum) && (pRawFd->rawfd_bufBlk != NONE))	return (pBlkDev->bd_bytesPerBlk);	/* ready to go as is */    /* Flush current block buffer */    if (rawFsFdFlush (pRawFd) != OK)	return (ERROR);    /* Check for new position past end of device */    if (newBlkNum >= pBlkDev->bd_nBlocks)	{	errnoSet (S_rawFsLib_END_OF_DEVICE);	return (ERROR);	}    /* Read in new block, unless opened for write only */    if (pRawFd->rawfd_mode != O_WRONLY)	{	if (rawFsBlkRd (vdptr, newBlkNum, 1, pRawFd->rawfd_buffer) != OK)	    return (ERROR);	}    /* Update file descriptor */    pRawFd->rawfd_curptr = newBlkNum * pBlkDev->bd_bytesPerBlk;						/* set pointer to buf start */    pRawFd->rawfd_bufBlk = newBlkNum;    return (pBlkDev->bd_bytesPerBlk);		/* return size of buffer */    }/********************************************************************************* rawFsBlkRd - read block(s) from a raw volume** This routine reads the specified block from the specified volume.* A limited number of retries is allowed.  If the block still cannot* be read, an error is returned.** RETURNS:* OK, or* ERROR, if read error and reset/retry failed.*/LOCAL STATUS rawFsBlkRd    (    FAST RAW_VOL_DESC   *vdptr,         /* pointer to volume descriptor */    int                 startBlk,       /* starting block for read */    int                 numBlks,        /* how many blocks to read */    FAST char           *pBuf           /* buffer to receive block */    )    {    FAST BLK_DEV	*pBlkDev = vdptr->rawvd_pBlkDev;					/* pointer to block device struct */    vdptr->rawvd_retry = 0;    while (((* pBlkDev->bd_blkRd) (pBlkDev, startBlk, numBlks,				       pBuf)) != OK)        {        /* read error: reset volume and retry, up to device's retry limit */        if (rawFsReset (vdptr) != OK)    	    return (ERROR);			/* drive won't reset! */        if (++(vdptr->rawvd_retry) > pBlkDev->bd_retry)    	    return (ERROR);			/* retry limit reached */        }    return (OK);    }/********************************************************************************* rawFsBlkWrt - write block(s) to a raw volume** This routine writes the specified blocks to the specified volume.* A limited number of retries is allowed.  If the blocks still cannot* be written, an error is returned.** RETURNS:

⌨️ 快捷键说明

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