📄 ofcb.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. * *---------------------------------------------------------------------- *//* * ofcb.c (file) * * File management * Open file control block */#include "fsinfo.h"#include "diskio.h"LOCAL OFCB* fmpFindOFCB( FID fid, FsInfo *fsinfo );/* * Retrieve OFCB. */LOCAL OFCB* fmpFindOFCB( FID fid, FsInfo *fsinfo ){ QUEUE *que; OFCB *ofcb; W OffsetFid = (W)offsetof(OFCB, fid); /* Queue in which OFCB of fid should be registered */ que = &fsinfo->ofcb[fid & OFCB_QMSK]; /* Find an entry that matches in fid */ ofcb = (OFCB*)QueSearchH(que, que, (H)fid, OffsetFid); return ( ofcb == (OFCB*)que )? NULL: ofcb;}/* * Obtain OFCB. */EXPORT OFCB* fmpGetOFCB( OpenPara *opara, FsInfo *fsinfo, ER *err ){ OFCB *ofcb; DfFileHeader *fhd = &opara->fhd->head; *err = E_OK; /* Retrieve to check whether the file is already opened. */ ofcb = fmpFindOFCB(opara->fid, fsinfo); if ( ofcb != NULL ) { return ofcb; } /* Newly create OFCB. */ ofcb = (OFCB*)Kmalloc(sizeof(OFCB)); if ( ofcb == NULL ) { *err = E_SYSMEM; goto err_ret1; } /* Initialization */ memset(ofcb, 0, (size_t)sizeof(OFCB)); ofcb->fsinfo = fsinfo; ofcb->fid = opara->fid; ofcb->fhead = opara->dadr; ofcb->idxlv = (H)fmpConvEndianH((UH)fhd->idxlv, fsinfo); ofcb->ridxofs = ( fsinfo->diskform < DiskForm_C )? (UH)offsetof(DfFileHeaderBlock, idx): fmpConvEndianH(fhd->ridxofs, fsinfo); ofcb->nrec = (W)fmpConvEndianW((UW)fhd->nrec, fsinfo); QueInit(&ofcb->rcb); *err = fmpCheckDiskError(NULL, fsinfo); if ( *err < E_OK ) { goto err_ret2; } /* Check whether the index level is supported or not. */ if ( ofcb->idxlv > MaxIndexLevel ) { *err = E_NOSPT; goto err_ret2; } /* Connect OFCB. */ QueInsert(&ofcb->q, &fsinfo->ofcb[opara->fid & OFCB_QMSK]); return ofcb;err_ret2: Kfree((VB*)ofcb);err_ret1: DEBUG_PRINT(("fmpGetOFCB err = %d\n", *err)); return NULL;}/* * Delete OFCB. * When force == TRUE, delete it even if FD refereeing to ofcb remains. */EXPORT void fmpRemoveOFCB( OFCB *ofcb, BOOL force ){ if ( (ofcb->ref > 0) && !force ) { /* References still remain. */ return; } /* Delete RCB. */ fmpDeleteAllRCB(ofcb); /* Disconnect/Delete OFCB. */ QueRemove(&ofcb->q); Kfree((VB*)ofcb);}/* * Forcefully delete all OFCBs (including RCB). */EXPORT ER fmpDeleteAllOFCB( FsInfo *fsinfo ){ QUEUE *que; OFCB *ofcb; W i; ER err, error = E_OK; for ( i = 0; i < OFCB_QSZ; ++i ) { que = &fsinfo->ofcb[i]; while ( (ofcb = (OFCB*)QueRemoveNext(que)) != NULL ) { /* Check whether some disk error are recorded. */ err = fmpCheckDiskError(ofcb, fsinfo); if ( err < E_OK ) { error = err; } /* Delete RCB. */ fmpDeleteAllRCB(ofcb); /* Delete OFCB. */ Kfree((VB*)ofcb); } }#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("fmpDeleteAllOFCB err = %d\n", error)); }#endif return error;}/* * Check the exclusive open. */EXPORT ER fmpCheckExclusiveOpen( OFCB *ofcb, UW omode ){ /* Check the exclusive mode. */ if ( (ofcb->omode.excl > (UH)0) || ((ofcb->ref > 0) && ((omode & F_EXCL) != 0U)) ) { return E_BUSY; } /* Check the exclusive write mode. */ if ( ((ofcb->omode.wexcl > (UH)0) && ((omode & F_WRITE) != 0U)) || (((omode & F_WEXCL) != 0U) && (ofcb->omode.write > (UH)0) ) ) { return E_BUSY; } return E_OK;}/* * OFCB open * Register the reference from the file descriptor. * Make sure that it can be opened in omode. */EXPORT ER fmpOpenOFCB( OFCB *ofcb, UW omode ){ ER err; if ( ofcb->ref == 0 ) { W i; /* Initialize RCB. */ for ( i = 0; i < ofcb->nrec; ++i ) { err = fmpNewRCB(EndRCB(ofcb)); if ( err < E_OK ) { goto err_ret; } } } ofcb->ref++; if ( (omode & F_EXCL) != 0U ) { ofcb->omode.excl++; } if ( (omode & F_WEXCL) != 0U ) { ofcb->omode.wexcl++; } if ( (omode & F_READ) != 0U ) { ofcb->omode.read++; } if ( (omode & F_WRITE) != 0U ) { ofcb->omode.write++; } return E_OK;err_ret: fmpDeleteAllRCB(ofcb); DEBUG_PRINT(("fmpOpenOFCB err = %d\n", err)); return err;}/* * OFCB close * Deregister the reference from the file descriptor. * Set omode to the mode when opened. */EXPORT void fmpCloseOFCB( OFCB *ofcb, UW omode ){ ofcb->ref--; if ( (omode & F_EXCL) != 0 ) { ofcb->omode.excl--; } if ( (omode & F_WEXCL) != 0 ) { ofcb->omode.wexcl--; } if ( (omode & F_READ) != 0 ) { ofcb->omode.read--; } if ( (omode & F_WRITE) != 0 ) { ofcb->omode.write--; } if ( ofcb->ref == 0 ) { /* Delete RCB */ fmpDeleteAllRCB(ofcb); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -