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

📄 rcb.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. * *---------------------------------------------------------------------- *//* *	rcb.c (file) * *	File management *	Record control block */#include "fsinfo.h"#include "diskio.h"LOCAL ER setRCB( RCB *fst, RCB *end, OFCB *ofcb );#define TSD_SRC_TYP_0X80	(UB)0x80#define TSD_SRC_MSK_0X1F	(UB)0x1f#define TSD_FAB_VAL_255		255#define TSD_FAB_VAL_3		3/* * Create new RCB and insert it just before currcb. */EXPORT ER fmpNewRCB( RCB *currcb ){	RCB	*rcb;	/* Create new one */	rcb = (RCB*)Vmalloc(sizeof(RCB));	if ( rcb == NULL ) {		return E_SYSMEM;	}	/* Initialization */	memset(rcb, 0, (size_t)sizeof(RCB));	rcb->rtype  = RCB_Invalid;	QueInit(&rcb->lkwait);	QueInit(&rcb->mcbq);	/* Connect to the queue. */	QueInsert(&rcb->q, &currcb->q);	return E_OK;}/* * Delete rcb and decrease the record numbers of RCBs after rcb by1. *	rcb must not be the end record. *	It must not be referred to as the current value. */EXPORT void fmpDeleteRCB( RCB *rcb, OFCB *ofcb ){	RCB	*p;#ifdef DEBUG	if ( rcb->ref > 0 ) {		DEBUG_PRINT(("fmpDeleteRCB ref = %d\n", rcb->ref));	}#endif	/* Decrease the record number by 1. */	for ( p = nextRCB(rcb); p != EndRCB(ofcb); p = nextRCB(p) ) {		p->recnum--;	}	/* Delete rcb. */	QueRemove(&rcb->q);	Vfree((VB*)rcb);}/* * Delete all RCBs connected to OFCB. */EXPORT void fmpDeleteAllRCB( OFCB *ofcb ){	RCB	*rcb;	while ( (rcb = (RCB*)QueRemoveNext(&ofcb->rcb)) != NULL ) {		Vfree((VB*)rcb);	}}/* * Set to the current record. */EXPORT RCB* fmpSetCurRCB( RCB *rcb, OFCB *ofcb ){	if ( !isEndRCB(rcb, ofcb) ) {		rcb->ref++;	}	return rcb;}/* * Release the current record. */EXPORT void fmpClearCurRCB( RCB *rcb, OFCB *ofcb ){	if ( !isEndRCB(rcb, ofcb) ) {		rcb->ref--;	}}/* ------------------------------------------------------------------------ *//* * Set the RCBs of from fst to end to the record information. *	The RCB just before fst must properly be set to the record information *	except in cases where fst is the first record. */LOCAL ER setRCB( RCB *fst, RCB *end, OFCB *ofcb ){	FsInfo		*fsinfo = ofcb->fsinfo;	RCB		*rcb;	RIdx		ri;	IdxAdr		*idxadr;	DfRecordIndex	*ridx;	W		recnum;	ER		err;	if ( isFirstRCB(fst, ofcb) != 0 ) {		rcb = fst;		recnum = 0;		idxadr = FIRST_RIdx;	} else {		rcb = prevRCB(fst);		recnum = rcb->recnum;		idxadr = &rcb->idxadr;	}	err = fmpOpenRIdx(&ri, idxadr, ofcb);	if ( err < E_OK ) {		return err;	}	for ( ;; ) {		/* Fetch the normal or link index. */		ridx = fmpGetRecordRIdx(&ri);		if ( ridx == NULL ) {			break;		}		if ( isInvalidRCB(rcb) != 0 ) {			/* Set RCB. */			if ( ridx->type[1] == TSD_SRC_TYP_0X80 ) {				/* Link index */				rcb->rtype = 0;				rcb->stype =					fmpConvEndianH(ridx->l.stype, fsinfo);				rcb->rsize = sizeof(LINK);			} else {				/* Normal index */				rcb->rtype = ridx->n.rtype & TSD_SRC_MSK_0X1F;				rcb->stype =					fmpConvEndianH(ridx->n.stype, fsinfo);				rcb->rsize =					(W)fmpConvEndianW(ridx->n.size, fsinfo);			}			rcb->recnum = recnum;			rcb->idxadr = fmpGetIdxAdr(&ri);		}		if ( rcb == end ) {			break;		}		rcb = nextRCB(rcb);		recnum++;	}	err = fmpCloseRIdx(&ri);	if ( err < E_OK ) {		DEBUG_PRINT(("setRCB RIdx I/O err = %d\n", err));		return err;	}	return E_OK;}/* * Set RCB to the record information. */EXPORT ER fmpSetRCB( RCB *rcb, OFCB *ofcb ){	RCB	*p;	ER	err;	if ( isEndRCB(rcb, ofcb) != 0 ) {		return E_ENDR;	}	/* Find the RCB that is set to the record information. */	for ( p = rcb; p != RCBQue(ofcb) ; p = prevRCB(p) ) {		if ( !isInvalidRCB(p) ) {			break;		}	}	if ( p == rcb ) {	/* Already set */		return E_OK;	}	/* Set the RCBs of up to rcb to the record information. */	err = setRCB(nextRCB(p), rcb, ofcb);	if ( err < E_OK ) {		return err;	}	return E_OK;}/* * Make invalid all RCBs of ofcb. */EXPORT void fmpSetInvalidAllRCB( OFCB *ofcb ){	RCB	*p;	for ( p = (RCB*)ofcb->rcb.next; p != EndRCB(ofcb); p = nextRCB(p) ) {		p->rtype = RCB_Invalid;	}}/* * Make invalid the specified range of rcb. *	Make invalid the RCBs of from top to end in relative position from rcb. */EXPORT void fmpSetInvalidRCB( RCB *rcb, W top, W end ){	RCB	*p;	W	i;	if ( rcb == NULL ) {		return;	}	/* Part before rcb */	p = rcb;	for ( i = 0; i >= top; --i, p = prevRCB(p) ) {		if ( i > end ) {			continue;		}		p->rtype = RCB_Invalid;	}	/* Part after rcb */	p = nextRCB(rcb);	for ( i = 1; i <= end; ++i, p = nextRCB(p) ) {		if ( i < top ) {			continue;		}		p->rtype = RCB_Invalid;	}}/* * Shift the idxadr of rcb. *	Shift the RCBs of from top to end in relative position from rcb. *	Specify the amount of shift with shift. *	The target of the shift is specified with lv. *	lv <  0   rcb->idxadr.ridx *	lv >= 0   rcb->idxadr.iidx[lv] */EXPORT void fmpShiftIdxAdrRCB( RCB *rcb, W lv, W top, W end, W shift ){	RCB	*p;	W	i;	if ( rcb == NULL ) {		return;	}	/* Part before rcb */	p = rcb;	for ( i = 0; i >= top; --i, p = prevRCB(p) ) {		if ( i > end ) {			continue;		}		if ( lv < 0 ) {			p->idxadr.ridx.offset = (VP)((DfRecordIndex*)p->idxadr.ridx.offset + shift);		} else {			p->idxadr.iidx[lv].offset = (VP)((DfIndirectIndex*)p->idxadr.iidx[lv].offset + shift);		}	}	/* Part after rcb */	p = nextRCB(rcb);	for ( i = 1; i <= end; ++i, p = nextRCB(p) ) {		if ( i < top ) {			continue;		}		if ( lv < 0 ) {			p->idxadr.ridx.offset = (VP)((DfRecordIndex*)p->idxadr.ridx.offset + shift);		} else {			p->idxadr.iidx[lv].offset = (VP)((DfIndirectIndex*)p->idxadr.iidx[lv].offset + shift);		}	}}/* * Extend the index level of RCB. */EXPORT void fmpExpandIndexLevelRCB( OFCB *ofcb ){	RCB	*p;	DskAdr	newroot;		newroot = FHeadIdxDAdr(ofcb);	for ( p = (RCB*)ofcb->rcb.next; p != EndRCB(ofcb); p = nextRCB(p) ) {		fmpExpandIdxAdr(&p->idxadr, newroot);	}}/* * Increase the record numbers of RCBs after rcb by 1. */EXPORT void fmpIncRNoRCB( RCB *rcb, OFCB *ofcb ){	RCB	*p;	for ( p = rcb; p != EndRCB(ofcb); p = nextRCB(p) ) {		p->recnum++;	}}/* ------------------------------------------------------------------------ *//* * Register new block in the record index. *	Additionally register new logical block at the end of the record of rcb. *	The current location of ri must indicates the location of the record index *	corresponding to the record end. *	After new is added, the location of the record index that has newly become *	the end is the current location of ri. */EXPORT ER fmpAppendBlockRCB( RCB *rcb, RIdx *ri, LogBlk new ){	OFCB		*ofcb = ri->ofcb;	FsInfo		*fsinfo = ofcb->fsinfo;	DfRecordIndex	*ridx;	W		cp;	LogBlk		lastblk;	ER		err;	/* Obtain the current end logical block. */	ridx = fmpGetMapAdr(ri, &cp);	lastblk = fmpConvEndianLogBlk(ridx->c.blk[cp], fsinfo);	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	if ( ((lastblk.adr + lastblk.cnt) == new.adr)	  && (((W)lastblk.cnt + (W)new.cnt) <= TSD_FAB_VAL_255) ) {		/* Because the new block follows just after the current end block,	increase the number of current blocks. */		lastblk.cnt += new.cnt;		ridx->c.blk[cp] = fmpConvEndianLogBlk(lastblk, fsinfo);	} else {		if ( (cp < TSD_FAB_VAL_3) || (lastblk.cnt == 0) ) {			/* Since the current record index has space,			   add it there. */			if ( lastblk.cnt != 0 ) {				ri->cp++;			}			ridx->c.blk[ri->cp - 1] =				fmpConvEndianLogBlk(new, fsinfo);		} else {			/* Add the record index. */			ridx = fmpAppendRIdx(ri, rcb);			if ( ridx == NULL ) {				err = fmpGetRIdxError(ri);				goto err_ret;			}			/* Register in the new record index. */			ridx->c.blk[0] = fmpConvEndianLogBlk(new, fsinfo);			ri->cp = 1;		}	}	fmpSetRIdxMapFlag(ri, MD_WRITE);	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpAppendBlockRCB err = %d\n", err));	return err;}/* * Update the record size. *	Add addsize bytes to the current size of the record of rcb. *	The logical block has to have been added already. */EXPORT ER fmpAddRSizeRCB( RCB *rcb, W addsize, OFCB *ofcb ){	FsInfo		*fsinfo = ofcb->fsinfo;	DfNormalIndex	*ridx;	ID		mid;	/* Map the record index. */	ridx = fmpMapDskAdr(rcb->idxadr.ridx, sizeof(DfNormalIndex),						ofcb, &mid, fsinfo);	if ( ridx == NULL ) {		return (ER)mid;	}	/* Update the record size. */	rcb->rsize += addsize;	ridx->size = fmpConvEndianW((UW)rcb->rsize, fsinfo);	fmpUnmapDisk(mid, MD_WRITE);	return fmpCheckDiskError(ofcb, fsinfo);}/* * Set the record subtype. *	Change the record subtype of rcb into subtype. */EXPORT ER fmpSetSubtypeRCB( RCB *rcb, UH subtype, OFCB *ofcb ){	FsInfo		*fsinfo = ofcb->fsinfo;	DfNormalIndex	*ridx;	ID		mid;	/* Map the record index. */	ridx = fmpMapDskAdr(rcb->idxadr.ridx, sizeof(DfNormalIndex),						ofcb, &mid, fsinfo);	if ( ridx == NULL ) {		return (ER)mid;	}	/* Change the record index. */	rcb->stype = subtype;	ridx->stype = fmpConvEndianH(subtype, fsinfo);	fmpUnmapDisk(mid, MD_WRITE);	return fmpCheckDiskError(ofcb, fsinfo);}

⌨️ 快捷键说明

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