📄 dpartcbio.c
字号:
/* dpartCbio.c - generic disk partition manager *//* Copyright 1999-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01s,14jan02,jkf SPR#72533,dpartDevCreate failed with BLK_DEV, & doc edits.01r,12dec01,jkf fixing diab build warnings.01q,09dec01,jkf SPR#71637, fix for SPR#68387 caused ready changed bugs.01p,09nov01,jkf SPR#71633, dont set errno when DevCreate is called w/BLK_DEV01o,20sep01,jkf SPR#69031, common code for both AE & 5.x.01n,01aug01,jyo Fixed SPR#69411: Change in media's readyChanged bit is not being propogated appropriately to the layers above.01m,14jun01,jyo SPR#67729: Updating blkSubDev, cbioSubDev and isDriver in dpartDevCreate().01l,19apr00,dat doc fixup01k,29feb00,jkf T3 changes, cleanup.01j,15sep99,jkf changes for new CBIO API.01i,24aug99,jkf changed docs01h,31jul99,jkf increased max partitions to 24 (c-z) in header, changed docs, defaulted the debug global to 0. SPR#28277.01g,31jul99,jkf T2 merge, tidiness & spelling.01f,07dec98,lrn minor fixes for partition table creation01e,25oct98,lrn fixed re-reading subDev geometry on RESET01d,15sep98,lrn some doc cleanups01c,10sep98,lrn added cbioDevVerify for cache-less configs01b,02jul98,lrn tested, doc review01a,15jun98,lrn written, preliminary*//*DESCRIPTIONThis module implements a generic partition manager using the CBIOAPI (see cbioLib) It supports creating a separate file system device for each of its partitions.This partition manager depends upon an external library to decode aparticular disk partition table format, and report the resultingpartition layout information back to this module. This module isresponsible for maintaining the partition logic during operation.When using this module with the dcacheCbio module, it is recommenedthis module be the master CBIO device. This module should be above the cache CBIO module layer. This is because the cache layer is optimized to fuction efficently atop a single physical disk drive.One should call dcacheDevCreate before dpartDevCreate.An implementation of the de-facto standard partition table formatwhich is created by the MSDOS FDISK program is provided with theusrFdiskPartLib module, which should be used to handle PC-stylepartitioned hard or removable drives.EXAMPLEThe following code will initialize a disk which is expected to have upto 4 partitions:.CS usrPartDiskFsInit( BLK_DEV * blkDevId ) { const char * devNames[] = { "/sd0a", "/sd0b", "/sd0c", "/sd0d" }; CBIO_DEV_ID cbioCache; CBIO_DEV_ID cbioParts; /@ create a disk cache atop the entire BLK_DEV @/ cbioCache = dcacheDevCreate ( blkDevId, NULL, 0, "/sd0" ); if (NULL == cbioCache) { return (ERROR); } /@ create a partition manager with a FDISK style decoder @/ cbioParts = dpartDevCreate( cbioCache, 4, usrFdiskPartRead ); if (NULL == cbioParts) { return (ERROR); } /@ create file systems atop each partition @/ dosFsDevCreate( devNames[0], dpartPartGet(cbioParts,0), 0x10, NONE); dosFsDevCreate( devNames[1], dpartPartGet(cbioParts,1), 0x10, NONE); dosFsDevCreate( devNames[2], dpartPartGet(cbioParts,2), 0x10, NONE); dosFsDevCreate( devNames[3], dpartPartGet(cbioParts,3), 0x10, NONE); }.CEBecause this module complies with the CBIO programming interface on both its upper and lower layers, it is both an optional and a stackable module.SEE ALSO:dcacheLib, dosFsLib, usrFdiskPartLibINTERNAL*//* includes */#include "vxWorks.h"#include "private/dosFsVerP.h"#include "stdlib.h"#include "semLib.h"#include "ioLib.h"#include "string.h"#include "stdio.h"#include "errno.h"#include "assert.h"/* START - CBIO private header */#define CBIO_DEV_EXTRA struct dpartCtrl#include "private/cbioLibP.h"/* END - CBIO private header */#include "dpartCbio.h"/* Implementation dependent data structures */typedef struct dpartCtrl { CBIO_DEV_ID subDev; /* lower level CBIO device handle */ int nPart ; /* Actual # of partitions on the disk */ FUNCPTR pPartDecodeFunc;/* Extern. partition decoder */ PART_TABLE_ENTRY /* partition table */ table [ PART_MAX_ENTRIES ]; CBIO_DEV /* per-partition virtual devices */ vDev [ PART_MAX_ENTRIES ]; CBIO_DEV_ID masterDev; /* master handle CBIO */ } DPART_CTRL ;/* custom use of CBIO fields */#define cbioPartIndx cbioPriv0extern void logMsg( const char *fmt, ... );int dpartDebug = 0;int dpartSemOptions = (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE) ;#define INFO_MSG logMsg#define DEBUG_MSG if(dpartDebug) logMsg/* declarations */LOCAL STATUS dpartBlkRW ( CBIO_DEV_ID dev, block_t startBlock, block_t numBlocks, addr_t buffer, CBIO_RW rw, cookie_t *pCookie );LOCAL STATUS dpartBytesRW ( CBIO_DEV_ID dev, block_t startBlock, off_t offset, addr_t buffer, size_t nBytes, CBIO_RW rw, cookie_t *pCookie );LOCAL STATUS dpartBlkCopy ( CBIO_DEV_ID dev, block_t srcBlock, block_t dstBlock, block_t numBlocks );LOCAL STATUS dpartIoctl ( CBIO_DEV_ID dev, UINT32 command, addr_t arg );/* CBIO_FUNCS, one per cbio driver */LOCAL CBIO_FUNCS cbioFuncs = {(FUNCPTR) dpartBlkRW, (FUNCPTR) dpartBytesRW, (FUNCPTR) dpartBlkCopy, (FUNCPTR) dpartIoctl};/********************************************************************************* dpartPartTableFill - Fill in partition geometry** Call external function to decode partitions, and fill the partition* geometry table accordingly.** RETURNS: OK or ERROR if the partition decode function failed for any reason*/LOCAL STATUS dpartPartTableFill( DPART_CTRL * pDc ) { STATUS ret; int pn ; CBIO_DEV_ID masterDev, subDev ; masterDev = pDc->masterDev; subDev = pDc->subDev; if((OK != cbioDevVerify( masterDev )) || (OK != cbioDevVerify( subDev ))) { return ERROR; } bzero( (char *) &pDc->table, sizeof( pDc->table ) ); /* First, call out the external decode function */ ret = pDc->pPartDecodeFunc( pDc->subDev, &pDc->table, pDc->nPart ) ; if( ret == ERROR ) return ERROR ; /* * re-configure device geometry in case it has been replaced */ masterDev->cbioParams.nBlocks = subDev->cbioParams.nBlocks ; masterDev->cbioParams.bytesPerBlk = subDev->cbioParams.bytesPerBlk ; masterDev->cbioParams.blocksPerTrack= subDev->cbioParams.blocksPerTrack ; masterDev->cbioParams.nHeads = subDev->cbioParams.nHeads ; masterDev->cbioMode = subDev->cbioMode ; /* * check sanity of the resulting partition table: */ for( pn = 0; pn < pDc->nPart; pn ++ ) { if( pDc->table[pn].spare != 0 || (pDc->table[pn].offset + pDc->table[pn].nBlocks) > pDc->subDev->cbioParams.nBlocks ) { DEBUG_MSG("dpartCbio: error: " "partition spills over disk size: %d blocks\n", pDc->table[pn].offset + pDc->table[pn].nBlocks - pDc->subDev->cbioParams.nBlocks ); return ERROR; } } DEBUG_MSG("dpartCbio: partition table decoded:\n"); for( pn = 0; pn < pDc->nPart; pn ++ ) { DEBUG_MSG(" part %d: offset %d nBlocks %d (next free block %d) \n", pn, pDc->table[pn].offset, pDc->table[pn].nBlocks, pDc->table[pn].offset + pDc->table[pn].nBlocks); pDc->vDev[ pn ].cbioParams.nBlocks = pDc->table[pn].nBlocks ; pDc->vDev[ pn ].cbioParams.blockOffset = pDc->table[pn].offset ; pDc->vDev[ pn ].cbioParams.bytesPerBlk = subDev->cbioParams.bytesPerBlk ; pDc->vDev[ pn ].cbioParams.blocksPerTrack = subDev->cbioParams.blocksPerTrack ; pDc->vDev[ pn ].cbioParams.nHeads = subDev->cbioParams.nHeads ; pDc->vDev[ pn ].cbioMode = subDev->cbioMode ; CBIO_READYCHANGED (&(pDc->vDev[ pn ])) = TRUE; } DEBUG_MSG("dpartCbio: end of partitions, total device blocks %d\n", pDc->subDev->cbioParams.nBlocks ); return OK ; }/********************************************************************************* dpartBlkRW - Read/Write blocks** This routine transfers between a user buffer and the lower layer CBIO* It is optimized for block transfers. ** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS dpartBlkRW ( CBIO_DEV_ID dev, /* CBIO handle */ block_t startBlock, /* starting block */ block_t numBlocks, /* nbr of blocks */ addr_t buffer, /* data buffer */ CBIO_RW rw, /* data direction */ cookie_t *pCookie /* passed thru */ ) { CBIO_DEV * pDev = (void *) dev ; STATUS retStat ; if(TRUE == cbioRdyChgdGet (dev)) { errno = S_ioLib_DISK_NOT_PRESENT ; return ERROR; } if( (startBlock) > pDev->cbioParams.nBlocks || (startBlock+numBlocks) > pDev->cbioParams.nBlocks ) return ERROR; startBlock += pDev->cbioParams.blockOffset; if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR ) return ERROR; retStat = pDev->pDc->subDev->pFuncs->cbioDevBlkRW( pDev->pDc->subDev, startBlock, numBlocks, buffer, rw, pCookie ); if( retStat == ERROR ) if( TRUE == cbioRdyChgdGet (dev->pDc->subDev)) CBIO_READYCHANGED (dev) = TRUE; semGive( pDev->cbioMutex ); return (retStat); }/********************************************************************************* dpartBytesRW - Read/Write bytes** This routine transfers between a user buffer and the lower layer CBIO* It is optimized for byte transfers. ** dev - the CBIO handle of the device being accessed (from creation routine)* * startBlock - the starting block of the transfer operation* * offset - offset in bytes from the beginning of the starting block* * buffer - address of the memory buffer used for the transfer* * nBytes - number of bytes to transfer* * rw - indicates the direction of transfer up or down (READ/WRITE)* * *pCookie - pointer to cookie used by upper layer such as dosFsLib(),* it should be preserved.* * RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS dpartBytesRW ( CBIO_DEV_ID dev, block_t startBlock, off_t offset, addr_t buffer, size_t nBytes, CBIO_RW rw, cookie_t *pCookie ) { CBIO_DEV * pDev = dev ; STATUS retStat ; if(TRUE == cbioRdyChgdGet (dev)) { errno = S_ioLib_DISK_NOT_PRESENT ; return ERROR; } if( startBlock >= pDev->cbioParams.nBlocks ) return ERROR; /* verify that all bytes are within one block range */ if (((offset + nBytes) > pDev->cbioParams.bytesPerBlk ) || (offset <0) || (nBytes <=0)) return ERROR; /* apply offset */ startBlock += pDev->cbioParams.blockOffset; if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR ) return ERROR; retStat = pDev->pDc->subDev->pFuncs->cbioDevBytesRW( pDev->pDc->subDev, startBlock, offset, buffer, nBytes, rw, pCookie ); if( retStat == ERROR ) if( TRUE == cbioRdyChgdGet (dev->pDc->subDev)) CBIO_READYCHANGED (dev) = TRUE; semGive( pDev->cbioMutex ); return ( retStat ); }/********************************************************************************* dpartBlkCopy - Copy sectors ** This routine makes copies of one or more blocks on the lower layer CBIO.* It is optimized for block copies on the subordinate layer. * * dev - the CBIO handle of the device being accessed (from creation routine)* * srcBlock - source start block of the copy* * dstBlock - destination start block of the copy* * num_block - number of blocks to copy** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS dpartBlkCopy ( CBIO_DEV_ID dev, block_t srcBlock, block_t dstBlock, block_t numBlocks ) { CBIO_DEV *pDev = (void *) dev ; STATUS retStat ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -