📄 rawfslib.c
字号:
/* rawFsLib.c - raw block device file system library *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------03j,30apr02,jkf SPR#75255, corrected unneeded api change to rawFsDevInit() SPR#72300, 4GB drive failed with rawFsOpen() SPR#25017, corrected FIODISKFORMAT docs to reflect reality.03i,09nov01,jkf SPR#71633, dont set errno when DevCreate is called w/BLK_DEV03h,20sep01,jkf SPR#69031, common code for both AE & 5.x.03g,31jul00,jkf removal of RT-11 (rt11) file system, SPR#32821/3122303f,29feb00,jkf T3 changes, cleanup.03e,31aug99,jkf changes for new CBIO API.03d,31jul99,jkf T2 merge, tidiness & spelling, jdi's 01p SPR#(SPR 25663).03c,23jul98,vld fixed SPR#8309 : rawFsDevInit() calls rawFsInit() with default parameters; fixed SPR#21875/9418 : don't validate seeked position for volume end overgoing.03b,23jul98,vld discontinued actual support for different volume states except RAW_VD_MOUNTED and RAW_VD_READY_CHANGED;03a,23jul98,vld driver interface changed to support CBIO_DEV; fixed SPR#22606 : CBIO on-byte base access functions are used instead of per file descriptor buffers02b,23jul98,vld added support for 64-bit ioctl requests; 32-bit restricted old ioctl functions improved to check and to return ERROR for 32-bit overloading results; added new routine rawFsIsValHuge().02a,23jul98,vld - added support for 64-bit arithmetic to serve huge volumes: type of rawFdCurPtr, rawFdNewPtr and rawFdEndPtr fields of RAW_FILE_DESC changed to fsize_t; - new type defined for block number (block_t); - "empty buffer" value constant defined as BUF_EMPTY (block_t)(-1)01p,14mar99,jdi doc: removed refs to config.h and/or configAll.h (SPR 25663).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, a CBIOdevice description structure (CBIO_DEV) or block device descriptionstructure (BLK_DEV) . This must be initializedbefore calling rawFsDevInit().The rawFsDevInit() routine is used to associate a device with the rawFsLibfunctions. The <pVolName> 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 syntax of the rawFsDevInit()routine is as follows:.CS rawFsDevInit ( char *pVolName, /@ name to be used for volume - iosDevAdd @/ BLK_DEV *pDevice /@ a pointer to BLK_DEV device or a CBIO_DEV_ID @/ ).CEUnlike the VxWorks DOS file system, 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 entry for rawFsMkfs()).When rawFsLib receives a request from the I/O system, after rawFsDevInit()has been called, it calls the appropriate device driver routinesto 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 3No file system is initialized on the disk by this request.This ioctl is passed directly down to the 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, rawFsLib, ramDrv,.pG "I/O System, Local File Systems"*//* LINTLIBRARY */#include "vxWorks.h"#include "private/dosFsVerP.h"#include "ctype.h"#include "ioLib.h"#include "lstLib.h"#include "stdlib.h"#include "string.h"#include "semLib.h"#include "errnoLib.h"#include "assert.h"#include "cbioLib.h"#include "rawFsLib.h"#define SIZE64#ifdef SIZE64typedef long long fsize_t;#define RAWFS_IS_VAL_HUGE( val ) ( ( (fsize_t)(val) >> 32 ) != 0 )#elsetypedef size_t fsize_t;#define RAWFS_IS_VAL_HUGE( val ) FALSE#endif /* SIZE64 *//* Raw device file descriptor */typedef struct /* RAW_FILE_DESC */ { NODE rawFdNode; /* linked list node info */ SEM_ID rawFdSemId; /* semaphore for this file descriptor */ int rawFdStatus; /* (OK | NOT_IN_USE) */ RAW_VOL_DESC * pRawFdVd; /* ptr to volume descriptor */ int rawFdMode; /* mode: O_RDONLY, O_WRONLY, O_RDWR */ fsize_t rawFdNewPtr; /* file byte ptr for new read/writes */ fsize_t rawFdEndPtr; /* file byte ptr to end of file */ cookie_t rawFdCookie; /* CBIO cookie of recently accessed sector */ } 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 */#define BUF_EMPTY (block_t)(-1) /* buffer not initialized *//* type definitions *//* 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 STATUS rawFsBlkRdWr (RAW_VOL_DESC *pVd, block_t startBlk, int numBlks, FAST char *pBuf, CBIO_RW rw);static STATUS rawFsBtRdWr (RAW_VOL_DESC *pVd, block_t blk, off_t offset, char * pBuf, size_t nBytes, CBIO_RW rw, cookie_t * pCookie);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 *pVd);static STATUS rawFsIoctl (RAW_FILE_DESC *pRawFd, int function, int arg);static RAW_FILE_DESC *rawFsOpen (RAW_VOL_DESC *pVd, char *name, int flags);static int rawFsRead (RAW_FILE_DESC *pRawFd, char *pBuf, int maxBytes);static STATUS rawFsReset (RAW_VOL_DESC *pVd);static STATUS rawFsSeek (RAW_FILE_DESC *pRawFd, fsize_t position);static STATUS rawFsVolCheck (RAW_VOL_DESC *pVd);static STATUS rawFsVolFlush (RAW_VOL_DESC *pVd);static STATUS rawFsVolMount (RAW_VOL_DESC *pVd);static fsize_t rawFsWhere (RAW_FILE_DESC *pRawFd);static int rawFsWrite (RAW_FILE_DESC *pRawFd, char *pBuf, int maxBytes);/********************************************************************************* rawFsIsValHuge - - check if value is greater, than 4GB (max 32 bit).** * RETURNS: TRUE if is greater, else return FALSE.*/LOCAL BOOL rawFsIsValHuge ( fsize_t val ) { return RAWFS_IS_VAL_HUGE( val ); } /* rawFsIsValHuge() *//********************************************************************************* rawFsBlkRdWr - read/write block(s) from/to a raw volume** This routine reads/writes the specified block from/to the* specified volume.** RETURNS:* OK, or* ERROR, if read/write error.*/LOCAL STATUS rawFsBlkRdWr ( FAST RAW_VOL_DESC *pVd, /* pointer to volume descriptor */ block_t startBlk, /* starting block for read */ int numBlks, /* how many blocks to read */ FAST char *pBuf, /* buffer to receive block */ CBIO_RW rw /* read / write */ ) { return (cbioBlkRW (pVd->rawVdCbio, startBlk, numBlks, pBuf, rw , NULL)); }/********************************************************************************* rawFsBtRdWr - read/write some bytes from/to block.** This routine reads/writes the specified number of bytes* from/to specified block starting at specified offset.** RETURNS:* OK, or* ERROR, if volume access error.*/LOCAL STATUS rawFsBtRdWr ( FAST RAW_VOL_DESC *pVd, /* pointer to volume descriptor */ block_t blkNum, /* block number */ off_t offset, /* offset in block */ char *pBuf, /* data buffer */ size_t numBytes, /* how many bytes to process */ CBIO_RW rw, /* read / write */ cookie_t *pCookie ) { return ( cbioBytesRW ( pVd->rawVdCbio, blkNum, offset, pBuf, numBytes, rw, pCookie)); }/********************************************************************************* rawFsClose - close raw volume
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -