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

📄 diskio.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	diskio.c (file) * *	File management *	Disk I/O related */#include "diskio.h"LOCAL void fmpDiskErrorHandler( DiskErrInfo *info );LOCAL VP fmpMapPhyBlks( PhyBlk padr[], MapClass mapc, MapModeClr clear, ID_ERR *mid, FsInfo *fsinfo );LOCAL VP fmcMapPhyBlks( PhyBlk padr[], DiskMapInfo *dmInfo, ID_ERR *mid );LOCAL VP fmcMapLogBlk( UW lblk, W sblk, DiskMapInfo *dmInfo, ID_ERR *mid );LOCAL ER fmcScanFileSystemHeader( DiskMapInfo *dmInfo, PhyBlk pblk[2] );#define TSD_DIO_BLK_2	2#define TSD_FMB_VAL_M1	(-1)#define TSD_FCD_SFT_MC1	((UW)BIGENDIAN << 16)#define TSD_FCD_SFT_MC2	(((UW)BIGENDIAN ^ 1) << 16)/* * Disk exception handler */LOCAL void fmpDiskErrorHandler( DiskErrInfo *info ){	MapClass	mapc;	FsInfo		*fsinfo;	mapc = (MapClass)info->mode.info;	fsinfo = GetFsInfo(info->taskid);	if ( (mapc == MAP_SYNC) || (mapc == MAP_ASYN) ) {		/* Error occurred in common section */		if ( fsinfo != NULL ) {			fsinfo->dskErr = info->err;		}	} else if ( mapc == MAP_FSTSK ) {		/* Error occurred in individual mapping section */		if ( fsinfo != NULL ) {			fsinfo->dskErr = info->err;		}	} else {		/* Error occurred in file individual section */		((OFCB*)mapc)->dskErr = info->err;	}}/* * Register/Deregister the disk exception handler. *	init =	TRUE	Register *		FALSE	Deregister */EXPORT ER fmpDefineDiskErrorHandler( BOOL init ){	ER	err;	FP	errhdr = ( init != 0 )? fmpDiskErrorHandler: NULL;	err = NotifyDiskErr(errhdr);	if ( err < E_OK ) {		DEBUG_PRINT(("fmpDefineDiskErrorHandler err = %d\n", err));		return err;	}	return E_OK;}/* * Check an exception occurrence. *	ofcb == NULL	Check only the error occurred in common section. *	ofcb != NULL	Check also the error occurred in individual section (File of ofcb). */EXPORT ER fmpCheckDiskError( OFCB *ofcb, FsInfo *fsinfo ){	UW	psw;	ER	err, error = E_OK;	/*** Take note that it must work exclusively with the exception handler. ***/	if ( ofcb != NULL ) {		DI(psw);		err = ofcb->dskErr;		ofcb->dskErr = E_OK;		EI(psw);		if ( err < E_OK ) {			error = err;		}	}	DI(psw);	err = fsinfo->dskErr;	fsinfo->dskErr = E_OK;	EI(psw);	if ( err < E_OK ) {		error = err;	}	return error;}/* * Error reset *	 Clear when the recorded error is the same as err. */EXPORT void fmpResetDiskError( ER err, MapClass mapc, FsInfo *fsinfo ){	UW	psw;	/*** Take note that it must work exclusively with the exception handler. ***/	if ( (mapc == MAP_SYNC) || (mapc == MAP_ASYN) || (mapc == MAP_FSTSK) ) {		DI(psw);		if ( fsinfo->dskErr == err ) {			fsinfo->dskErr = E_OK;		}		EI(psw);	} else {		DI(psw);		if ( ((OFCB*)mapc)->dskErr == err ) {			((OFCB*)mapc)->dskErr = E_OK;		}		EI(psw);	}}/* ----------------------------------------------------------------------- *//* * Disk mapping *	Map the non-contiguous physical block (PkyBlk[]) of the disk *	to a contiguous address space, and return the first address. */LOCAL VP fmpMapPhyBlks( PhyBlk padr[], MapClass mapc, MapModeClr clear,						ID_ERR *mid, FsInfo *fsinfo ){	MapMode		mode = DefaultMapMode;	ER		err;	mode.info = (VW)mapc;	mode.clear = clear;	*mid = err = MapDisk(fsinfo->dskid, padr, &mode);	if ( err < E_OK ) {		fmpResetDiskError(err, mapc, fsinfo);		if ( err == E_TMOUT ) {			*mid = E_SYSMEM;		}		DEBUG_PRINT(("fmpMapPhyBlks err = %d\n", err));		return NULL;	}	return mode.addr;}/* * Disk mapping *	Map the size bytes from the byte address (DskAdrS) of the disk, *	and return the first address. */EXPORT VP fmpMapDskAdrS( DskAdrS dadr, W size, MapClass mapc, ID_ERR *mid,							FsInfo *fsinfo ){	PhyBlk		blks[TSD_DIO_BLK_2];	UW		start, end;	/* Physical block number */	UW		offset;		/* Offset in the block */	VB		*adr;	start  = (UW)dadr / (UW)fsinfo->dskInfo.blocksize;	offset = (UW)dadr % (UW)fsinfo->dskInfo.blocksize;	end    = ((UW)dadr + (UW)size - 1U) / (UW)fsinfo->dskInfo.blocksize;	blks[0].blk = start + (UW)fsinfo->pbadj;	blks[0].len = end - start + 1U;	blks[1].len = 0;	adr = fmpMapPhyBlks(blks, mapc, MapNoClr, mid, fsinfo);	if ( adr == NULL ) {		return NULL;	}	return (VP)(adr + offset);}/* * Disk mapping *	Map the size bytes from the disk address (DskAdr), *	and return the first address. */EXPORT VP fmpMapDskAdr( DskAdr dadr, W size, MapClass mapc, ID_ERR *mid,							FsInfo *fsinfo ){	PhyBlk		blks[TSD_DIO_BLK_2];	UW		start, end;	/* Physical block number */	UW		offset;		/* Offset in the block */	VB		*adr;	start = end = dadr.lblk * fsinfo->blkRatio;	start  += (UW)dadr.offset / (UW)fsinfo->dskInfo.blocksize;	offset  = (UW)dadr.offset % (UW)fsinfo->dskInfo.blocksize;	end    += ((UW)dadr.offset + (UW)size - 1U) / (UW)fsinfo->dskInfo.blocksize;	blks[0].blk = start + (UW)fsinfo->pbadj;	blks[0].len = end - start + 1U;	blks[1].len = 0;	adr = fmpMapPhyBlks(blks, mapc, MapNoClr, mid, fsinfo);	if ( adr == NULL ) {		return NULL;	}	return (VP)(adr + offset);}/* * Disk mapping *	Map the one logical block of the disk, and return the first address. */EXPORT VP fmpMapLogBlk( UW lblk, MapClass mapc, ID_ERR *mid, FsInfo *fsinfo ){	PhyBlk		blks[TSD_DIO_BLK_2];	blks[0].blk = (lblk * fsinfo->blkRatio) + (UW)fsinfo->pbadj;	blks[0].len = fsinfo->blkRatio;	blks[1].len = 0;	return fmpMapPhyBlks(blks, mapc, MapNoClr, mid, fsinfo);}/* * Disk mapping with clear specification. *	Map the one logical block of the disk, and return the first address. */EXPORT VP fmpMapLogBlkC( UW lblk, MapClass mapc, MapModeClr clear,					ID_ERR *mid, FsInfo *fsinfo ){	PhyBlk		blks[TSD_DIO_BLK_2];	blks[0].blk = (lblk * fsinfo->blkRatio) + (UW)fsinfo->pbadj;	blks[0].len = fsinfo->blkRatio;	blks[1].len = 0;	return fmpMapPhyBlks(blks, mapc, clear, mid, fsinfo);}/* * Disk mapping *	Map the disk block according to the logical block list (LBlks), *	and return the first address. */EXPORT VP fmpMapLogBlks( LBlks *lb, MapClass mapc, MapModeClr clear,					ID_ERR *mid, FsInfo *fsinfo ){	PhyBlk		*blks, *p;	LogBlk		*lblk;	W		nlblk;	W		prev;	VP		mapadr;	W		blkRatio = (W)fsinfo->blkRatio;	ER		err;	/* The number of entries of the logical block. */	nlblk = fmpNLBlks(lb);	if ( nlblk <= 0 ) {		err = E_SYS;		goto err_ret;	}	/* Reserve the storing area of the physical block list. */	blks = (PhyBlk*)Kmalloc(((UW)nlblk + 1U) * sizeof(PhyBlk));	if ( blks == NULL ) {		err = E_SYSMEM;		goto err_ret;	}	/* Convert the logical block list into physical block list. */	p = blks;	lblk = NULL;	prev = TSD_FMB_VAL_M1;	while ( fmNextLBlks(lb, &lblk) != 0 ) {		if ( lblk->adr == prev ) {			/* It is continued from the previous block. */			(p - 1)->len += (UW)lblk->cnt * (UW)blkRatio;		} else {			p->blk = (UW)((lblk->adr * blkRatio) + fsinfo->pbadj);			p->len = (UW)lblk->cnt * (UW)blkRatio;			p++;		}		prev = lblk->adr + lblk->cnt;	}	p->len = 0;	/* Mapping */	mapadr = fmpMapPhyBlks(blks, mapc, clear, mid, fsinfo);	Kfree((VB*)blks);	return mapadr;err_ret:	DEBUG_PRINT(("fmpMapLogBlks err = %d\n", err));	*mid = err;	return NULL;}/* * Synchronize the cache in file. *	Write the unwritten data of the map class specified in mapc to the disk. */EXPORT ER fmpSyncFile( MapClass mapc, FsInfo *fsinfo ){	OFCB	*ofcb;	(void)SyncFS(fsinfo->dskid, (VW)mapc);	if ( (mapc == MAP_SYNC) || (mapc == MAP_ASYN) || (mapc == MAP_FSTSK) ) {		ofcb = NULL;	} else {		ofcb = (OFCB*)mapc;	}	return fmpCheckDiskError(ofcb, fsinfo);}/* ----------------------------------------------------------------------- *//* * Map the specified elements of the file ID table. */EXPORT DfFileID* fmpMapFileID( FID fid, ID_ERR *mid, FsInfo *fsinfo ){	DfFileID	*fidt = (DfFileID*)fsinfo->fidt;	VP		mapadr;	if ( fid >= fsinfo->nfmax ) {		/* Abnormal file ID */		*mid = E_NOEXS;		return NULL;	}	mapadr = fmpMapDskAdrS(&fidt[fid], sizeof(DfFileID),					MAP_SYS(fsinfo), mid, fsinfo);	return (DfFileID*)mapadr;}/* * Map the file header. */EXPORT DfFileHeaderBlock* fmpMapFileHeader( FID fid, DskAdr *da, ID_ERR *mid,							FsInfo *fsinfo ){	DfFileID	*fidt, f;	DskAdr		fhd;	VP		mapadr;	/* Map the file ID. */	fidt = fmpMapFileID(fid, mid, fsinfo);	if ( fidt == NULL ) {		goto err_ret;	}	if ( fidt->w == 0U ) {		/* Unused entry (No file) */		fmpUnmapDisk(*mid, MD_RDONLY);		*mid = E_NOEXS;		goto err_ret;	}	/* Location of the file header */	f = fmpConvEndianFileID(*fidt, fsinfo);	fhd = fmpLBlkToDAdr(f.s.blkadr, fsinfo);	if ( da != NULL ) {		*da = fhd;	}	fmpUnmapDisk(*mid, MD_RDONLY);	*mid = fmpCheckDiskError(NULL, fsinfo);	if ( *mid < E_OK ) {		goto err_ret;	}	/* Map the file header. */	mapadr = fmpMapDskAdr(fhd, sizeof(DfFileHeaderBlock),

⌨️ 快捷键说明

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