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

📄 maprec.c

📁 T-kernel 的extension源代码
💻 C
字号:
/* *---------------------------------------------------------------------- *    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. * *---------------------------------------------------------------------- *//* *	maprec.c (file) * *	File management *	Record map */#include "fileio.h"#include "mcb.h"#include "diskio.h"LOCAL MCB* fmpNewMCB( FD *fd, RCB *rcb );LOCAL void fmpDeleteMCB( MCB *mcb );LOCAL VP mapLBlks( LBlks *lb, W mode, PINFO *pinfo, OFCB *ofcb, ID_ERR *mid );LOCAL WER mapRecord( FD *fd, RCB *rcb, OFCB *ofcb, FM_MAP_REC_PARA *cmdPara );#define TSD_MLB_VAL_M1	(-1)/* * Newly generate MCB. *	Generate MCB to map the record of rcb that is opened with fd. */LOCAL MCB* fmpNewMCB( FD *fd, RCB *rcb ){	MCB	*mcb;	/* Reserve a memory. */	mcb = Vmalloc(sizeof(MCB));	if ( mcb == NULL ) {		return NULL;	}	/* Link to fd and rcb. */	QueInsert(&mcb->fdq, &fd->mcbq);	QueInsert(&mcb->rcbq, &rcb->mcbq);	return mcb;}/* * Delete MCB */LOCAL void fmpDeleteMCB( MCB *mcb ){	/* Delete the links from fd and rcb. */	QueRemove(&mcb->fdq);	QueRemove(&mcb->rcbq);	/* Release the memory. */	Vfree(mcb);}/* ------------------------------------------------------------------------ *//* * Perform mapping according to the block list. */LOCAL VP mapLBlks( LBlks *lb, W mode, PINFO *pinfo, OFCB *ofcb, ID_ERR *mid ){	PhyBlk		*blks, *p;	LogBlk		*lblk;	W		nlblk;	W		prev;	MapMode		mapmode;	FsInfo		*fsinfo = ofcb->fsinfo;	W		blkRatio = (W)fsinfo->blkRatio;	ER		err;#ifdef CanNotMapRecord	/* When the record map can not be performed at all. */	err = E_NOSPT;	goto err_ret1;#endif#ifdef MappableBlockSize	/* When the logical block size that can be mapped is restricted. */	if ( (fsinfo->sblk % MappableBlockSize) != 0 ) {		err = E_NOSPT;		goto err_ret1;	}#endif	/* The number of entries of the logical block list */	nlblk = fmpNLBlks(lb);	if ( nlblk <= 0 ) {		err = E_SYS;		goto err_ret1;	}	/* Reserve the storing area of the physical block list. */	blks = (PhyBlk*)Kmalloc((UW)(nlblk + 1) * sizeof(PhyBlk));	if ( blks == NULL ) {		err = E_SYSMEM;		goto err_ret1;	}	/* Convert from the logical block list into physical block list. */	p = blks;	lblk = NULL;	prev = TSD_MLB_VAL_M1;	while ( fmNextLBlks(lb, &lblk) != 0 ) {		if ( lblk->adr == prev ) {			/* It is continued from the previous block. */			(p - 1)->len += (UW)(lblk->cnt * blkRatio);		} else {			p->blk = (UW)((lblk->adr * blkRatio) + fsinfo->pbadj);			p->len = (UW)(lblk->cnt * blkRatio);			p++;		}		prev = lblk->adr + lblk->cnt;	}	p->len = 0;	/* Map mode */	mapmode.resv	= 0;	mapmode.rank	= MapRankFM3;	mapmode.real	= 0;	mapmode.clear	= MapNoClr;	mapmode.addr	= INVADR;	mapmode.info	= (VW)ofcb;	switch ( (UW)mode & (UW)F_SYSTEM ) {	  case F_SYSTEM:	/* System space */		mapmode.level = MapSystem;		mapmode.space = 0;		break;	  case F_COMMON:	/* Shared space */		mapmode.level = MapUser;		mapmode.space = 0;		break;	  default:		/* Local space */		mapmode.level = MapUser;		mapmode.space = GetLSID(pinfo);		break;	}	if ( ((UW)mode & F_READ  ) != 0U ) {		mapmode.level |= MapRead;	}	if ( ((UW)mode & F_WRITE ) != 0U ) {		mapmode.level |= MapWrite;	}	if ( ((UW)mode & F_EXCUTE) != 0U ) {		mapmode.level |= MapExecute;	}	/* Mapping  */	err = MapDisk(fsinfo->dskid, blks, &mapmode);	if ( err < E_OK ) {		goto err_ret2;	}	*mid = (ID)err;	Kfree(blks);	return mapmode.addr;err_ret2:	fmpResetDiskError(err, ofcb, fsinfo);	if ( err == E_TMOUT ) {		err = E_SYSMEM;	}	Kfree(blks);err_ret1:	DEBUG_PRINT(("mapLBlks err = %d\n", err));	*mid = err;	return NULL;}/* * Map the data record. */LOCAL WER mapRecord( FD *fd, RCB *rcb, OFCB *ofcb, FM_MAP_REC_PARA *cmdPara ){	MCB	*mcb;	LBlks	lb;	W	offset;	VB	*mp;	ID	mid;	ER	err;	/* Obtain MCB. */	mcb = fmpNewMCB(fd, rcb);	if ( mcb == NULL ) {		err = E_SYSMEM;		goto err_ret1;	}	/* Prepare the block list. */	err = fmNewLBlks(&lb);	if ( err < E_OK ) {		goto err_ret2;	}	/* Create the block list of record. */	offset = fmpMakeLBlks(&lb, rcb, cmdPara->offset, cmdPara->size, ofcb);	if ( offset < 0 ) {		err = (ER)offset;		goto err_ret2;	}	/* Map the record */	mp = mapLBlks(&lb, cmdPara->mode, fd->pinfo, ofcb, &mid);	if ( mp == NULL ) {		err = (ER)mid;		goto err_ret3;	}	mp += offset;	/* Release the block list. */	fmDeleteLBlks(&lb);	/* Set MCB. */	mcb->mid  = mid;	mcb->mode = cmdPara->mode;	*cmdPara->addr = mp;	return mid;err_ret3:	fmDeleteLBlks(&lb);err_ret2:	fmpDeleteMCB(mcb);err_ret1:	DEBUG_PRINT(("mapRecord err = %d\n", err));	return err;}/* * Record map */EXPORT void fmpMapRecord( FmCmdPkt *pkt ){	FM_MAP_REC_PARA	*cmdPara = (FM_MAP_REC_PARA*)pkt->cmd.para;	FD		*fd;	OFCB		*ofcb;	RCB		*rcb;	UW		chkmode;	ER		err;	/* Obtain FD and OFCB. */	fd = getFDp(cmdPara->fd);	ofcb = fd->ofcb;	/* Parameter check */	if ( (((UW)cmdPara->mode & ~(UW)(F_READ|F_WRITE|F_EXCUTE|F_SYSTEM)) != 0)	  || (((UW)cmdPara->mode & (F_READ|F_WRITE|F_EXCUTE)) == 0U)	  || (cmdPara->offset < 0) || (cmdPara->size <= 0) ) {		err = E_PAR;		goto err_ret;	}	err = CheckSpaceRW(cmdPara->addr, sizeof(B*));	if ( err < E_OK ) {		goto err_ret;	}	/* Removal disks can not be mapped.	   Mapping can not be performed in the disk recovery mode. */	if ( ofcb->fsinfo->dskInfo.removable || _isFsrcvMode() ) {		err = E_NOSPT;		goto err_ret;	}	/* Check the open mode. */	chkmode = 0;	if ( ((UW)cmdPara->mode & F_WRITE) != 0U ) {		chkmode |= F_WRITE;	}	if ( ((UW)cmdPara->mode & (F_READ|F_EXCUTE)) != 0U ) {		chkmode |= F_READ;	}	err = fmpCheckFileOpenMode(fd, chkmode);	if ( err < E_OK ) {		goto err_ret;	}	/* Obtain the current record. */	err = fmpSetRCB(rcb = fd->crcb, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	/* Link record can not be mapped. */	if ( isLinkRecord(rcb->rtype) != 0 ) {		err = E_REC;		goto err_ret;	}	/* The current record size must not be exceeded. */	if ( ((UW)cmdPara->offset + (UW)cmdPara->size) > (UW)rcb->rsize ) {		err = E_PAR;		goto err_ret;	}	/* Record map */	err = mapRecord(fd, rcb, ofcb, cmdPara);	if ( err < E_OK ) {		goto err_ret;	}	pkt->cmd.ret = err; /* Map ID */	return;err_ret:	DEBUG_PRINT(("fmpMapRecord err = %d\n", err));	pkt->cmd.ret = err;	return;}/* * Release the record map. */EXPORT void fmpUnmapRecord( FmCmdPkt *pkt ){	FM_UMP_REC_PARA	*cmdPara = (FM_UMP_REC_PARA*)pkt->cmd.para;	FD	*fd;	MCB	*mcb;	OFCB	*ofcb;	ER	err, error = E_OK;	/* Obtain FD and OFCB. */	fd = getFDp(cmdPara->fd);	ofcb = fd->ofcb;	/* Retrieve MCB. */	mcb = (MCB*)QueSearch(&fd->mcbq, &fd->mcbq,				cmdPara->mapid, (W)offsetof(MCB, mid));	if ( mcb == (MCB*)&fd->mcbq ) {		error = E_NOEXS;		goto err_ret;	}	/* Release the map. */	fmpUnmapDisk(mcb->mid,			(((UW)mcb->mode & F_WRITE) != 0U )? MD_WRITE: MD_RDONLY);	err = fmpCheckDiskError(ofcb, ofcb->fsinfo);	if ( err < E_OK ) {		error = err;	}	/* Update the time stamp. */	err = fmpSetTimeStamp(ofcb, (UW)mcb->mode);	if ( err < E_OK ) {		error = err;	}	/* Delete MCB. */	fmpDeleteMCB(mcb);err_ret:DO_DEBUG(	if ( error < E_OK ) {		DEBUG_PRINT(("fmpUnmapRecord err = %d\n", error));	})	pkt->cmd.ret = error;	setSyncAtExit(SAE_OPENF, ofcb->fsinfo);	return;}/* * Release the map of all records of fd. */EXPORT ER fmpUnmapAllRecord( FD *fd, OFCB *ofcb ){	MCB	*mcb;	UW	mode = 0;	ER	err, error = E_OK;	while ( !isQueEmpty(&fd->mcbq) ) {		mcb = (MCB*)fd->mcbq.next;		/* Release the map. */		fmpUnmapDisk(mcb->mid,			(((UW)mcb->mode & F_WRITE) != 0U )? MD_WRITE: MD_RDONLY);		mode |= (UW)mcb->mode;		/* Delete MCB. */		fmpDeleteMCB(mcb);	}	err = fmpCheckDiskError(ofcb, ofcb->fsinfo);	if ( err < E_OK ) {		error = err;	}	/* Update the time stamp. */	err = fmpSetTimeStamp(ofcb, mode);	if ( err < E_OK ) {		error = err;	}DO_DEBUG(	if ( error < E_OK ) {		DEBUG_PRINT(("fmpUnmapAllRecord err = %d\n", error));	})	return error;}

⌨️ 快捷键说明

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