📄 rcb.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 + -