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

📄 insrec.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. * *---------------------------------------------------------------------- *//* *	insrec.c (file) * *	File management *	Insert/Add/Delete records. */#include "fileio.h"#include "diskio.h"LOCAL ER changeRecordCount( OFCB *ofcb, W rtype, W diff );LOCAL WER changeFileReferenceCount( FID fid, W diff, FsInfo *fsinfo );LOCAL ER checkLINK( LINK *lnk, FsInfo *fsinfo );LOCAL ER appendRecord( RCB **rcb, OFCB *ofcb, W type, UH subtype, LINK *lnk );LOCAL ER insertRecord( RCB **rcb, OFCB *ofcb, W type, UH subtype, LINK *lnk );LOCAL WER deleteRecord( FD *fd, RCB *rcb, OFCB *ofcb );#define TSD_FRC_VAL_255	255#define TSD_FPR_VAL_32	32#define TSD_FRC_VAL_M1	(-1)#define TSD_DRD_VAL_M1	(-1)/* * Update the total number of records. *	Increase/Decrease the total number of records of the file header by diff. *	In the case of the link record, increase/decrease the number of included links as well. */LOCAL ER changeRecordCount( OFCB *ofcb, W rtype, W diff ){	FsInfo		*fsinfo = ofcb->fsinfo;	DfFileHeader	*fh;	H		nlnk;	ID		mid;	ER		err;	/* Map the file header. */	fh = fmpMapDskAdr(ofcb->fhead, sizeof(DfFileHeader),					ofcb, &mid, fsinfo);	if ( fh == NULL ) {		err = (ER)mid;		goto err_ret;	}	/* Update the total number of records. */	ofcb->nrec += diff;	fh->nrec = (W)fmpConvEndianW((UW)ofcb->nrec, fsinfo);	if ( isLinkRecord(rtype) != 0 ) {		/* Update the number of included links. */		nlnk = (H)fmpConvEndianH((UH)fh->nlnk, fsinfo) + (H)diff;		fh->nlnk = (H)fmpConvEndianH((UH)nlnk, fsinfo);	}	fmpUnmapDisk(mid, MD_WRITE);	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("changeRecordCount err = %d\n", err));	return err;}/* * Update the file reference count. *	Increase/Decrease the reference count of the file ID table by diff. *	Return the updated reference count. */LOCAL WER changeFileReferenceCount( FID fid, W diff, FsInfo *fsinfo ){	W		refcnt;	DfFileID	*fidt, f;	DfFileHeader	*fh = NULL;	ID		mid, mid2;	ER		err;	/* Map the file ID table. */	fidt = fmpMapFileID(fid, &mid, fsinfo);	if ( fidt == NULL ) {		err = (ER)mid;		goto err_ret1;	}	if ( fidt->w == 0U ) {		/* File does not exist. */		err = E_NOEXS;		goto err_ret2;	}	f = fmpConvEndianFileID(*fidt, fsinfo);	refcnt = (W)f.s.refcnt;	if ( ((refcnt == TSD_FRC_VAL_255) || ((refcnt + diff) >= TSD_FRC_VAL_255))	  && (fsinfo->diskform >= DiskForm_B) ) {		/* Map the file header. */		fh = fmpMapDskAdr(fmpLBlkToDAdr(f.s.blkadr, fsinfo),			sizeof(DfFileHeader), MAP_FSTSK, &mid2, fsinfo);		if ( fh == NULL ) {			err = (ER)mid2;			goto err_ret2;		}		if ( refcnt == TSD_FRC_VAL_255 ) {			/* File reference count in STDFS extended format (>=255) */			refcnt = (W)fmpConvEndianW((UW)fh->refcnt, fsinfo);		}	}	refcnt += diff;	if ( (refcnt < 0)	  || ((refcnt > TSD_FRC_VAL_255) && (fsinfo->diskform == DiskForm_A)) ) {		/* The reference count overflowed. */		err = E_LIMIT;		goto err_ret3;	}	if ( fh != NULL ) {		/* File the reference count in STDFS extended format (>=255) */		fh->refcnt = (W)fmpConvEndianW(( refcnt >= TSD_FRC_VAL_255 )? (UW)refcnt: 0,								fsinfo);		fmpUnmapDisk(mid2, MD_WRITE);	}	/* Update the file reference count */	f.s.refcnt = (UB)(( refcnt >= TSD_FRC_VAL_255 )? TSD_FRC_VAL_255: refcnt);	*fidt = fmpConvEndianFileID(f, fsinfo);	fmpUnmapDisk(mid, MD_WRITE);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	return refcnt;err_ret3:	fmpUnmapDisk(mid2, MD_RDONLY);err_ret2:	fmpUnmapDisk(mid, MD_RDONLY);err_ret1:	DEBUG_PRINT(("changeFileReferenceCount err = %d\n", err));	return err;}/* * Check the contents of LINK. * If correct, up the reference count. */LOCAL ER checkLINK( LINK *lnk, FsInfo *fsinfo ){	ER		err;	/* Check the file system. */	if ( tc_strncmp(lnk->fs_name, fsinfo->fsName, FsNameLen) != 0 ) {		/* The file system is different. */		err = E_REC;		goto err_ret;	}	/* Up the file reference count. */	err = changeFileReferenceCount(lnk->f_id, +1, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("checkLINK err = %d\n", err));	return err;}/* * Add the record. *	Add new record just before the end record. *	Return the RCB of the added new record to *rcb. */LOCAL ER appendRecord( RCB **rcb, OFCB *ofcb, W type, UH subtype, LINK *lnk ){	RIdx		ri;	RCB		*newrcb;	DfRecordIndex	*ridx;	ER		err;	/* Locate ri at the last record index. */	err = fmpOpenRIdx(&ri, LAST_RIdx, ofcb);	if ( err < E_OK ) {		goto err_ret1;	}	ridx = fmpGetRIdx(&ri);	if ( ridx == NULL ) {		goto err_ret3;	}	/* Whether the current location is an unused record index. */	if ( !((ridx->type[0] == 0) && (ridx->type[1] == 0)) ) {		/* It is used. */		RCB *currcb = prevRCB(EndRCB(ofcb));		err = fmpSetRCB(currcb, ofcb);		if ( err < E_OK ) {			goto err_ret2;		}		/* Add the record index. */		ridx = fmpAppendRIdx(&ri, currcb);		if ( ridx == NULL ) {			goto err_ret3;		}	}	/* Add the new RCB just before the end record. */	err = fmpNewRCB(EndRCB(ofcb));	if ( err < E_OK ) {		goto err_ret2;	}	/* Initialize the record index. */	err = fmpSetRIdx(&ri, type, subtype, lnk);	if ( err < E_OK ) {		goto err_ret2;	}	err = fmpCloseRIdx(&ri);	if ( err < E_OK ) {		goto err_ret1;	}	/* Update the total number of records of the file header. */	err = changeRecordCount(ofcb, type, +1);	if ( err < E_OK ) {		goto err_ret1;	}	/* Initialize the added RCB. */	newrcb = prevRCB(EndRCB(ofcb));	err = fmpSetRCB(newrcb, ofcb);	if ( err < E_OK ) {		goto err_ret1;	}	*rcb = newrcb;	return E_OK;err_ret3:	err = fmpGetRIdxError(&ri);err_ret2:	(void)fmpCloseRIdx(&ri);err_ret1:	DEBUG_PRINT(("appendRecord err = %d\n", err));	return err;}/* * Insert the record. *	Insert the new record just before *rcb. *	*rcb must not be the end record. *	Return the RCB of the inserted new record to *rcb. */LOCAL ER insertRecord( RCB **rcb, OFCB *ofcb, W type, UH subtype, LINK *lnk ){	RIdx		ri;	RCB		*currcb = *rcb;	RCB		*newrcb;	DfRecordIndex	*ridx;	ER		err;	/* Locate ri at the first record index of currcb. */	err = fmpOpenRIdx(&ri, &currcb->idxadr, ofcb);	if ( err < E_OK ) {		goto err_ret1;	}	ridx = fmpGetRIdx(&ri);	if ( ridx == NULL ) {		goto err_ret3;	}	/* Insert the record index. */	ridx = fmpInsertRIdx(&ri, currcb);	if ( ridx == NULL ) {		goto err_ret3;	}	/* Insert the new RCB just before currcb. */	err = fmpNewRCB(currcb);	if ( err < E_OK ) {		goto err_ret2;	}	/* Increase the record numbers after currcb by 1. */	fmpIncRNoRCB(currcb, ofcb);	/* Initialize the record index. */	err = fmpSetRIdx(&ri, type, subtype, lnk);	if ( err < E_OK ) {		goto err_ret2;	}	err = fmpCloseRIdx(&ri);	if ( err < E_OK ) {		goto err_ret1;	}	/* Update the total number of records of the file header. */	err = changeRecordCount(ofcb, type, +1);	if ( err < E_OK ) {		goto err_ret1;	}	/* Initialize the inserted RCB. */	newrcb = prevRCB(currcb);	err = fmpSetRCB(newrcb, ofcb);	if ( err < E_OK ) {		goto err_ret1;	}	*rcb = newrcb;	return E_OK;err_ret3:	err = fmpGetRIdxError(&ri);err_ret2:	(void)fmpCloseRIdx(&ri);err_ret1:	DEBUG_PRINT(("insertRecord err = %d\n", err));	return err;}/* * Insert the record. */EXPORT void fmpInsertRecord( FmCmdPkt *pkt ){	FM_INS_REC_PARA	*cmdPara = (FM_INS_REC_PARA*)pkt->cmd.para;	FD		*fd;	OFCB		*ofcb;	RCB		*rcb;	ER		err, error = E_OK;	/* Obtain FD and OFCB. */	fd = getFDp(cmdPara->fd);	ofcb = fd->ofcb;	/* Check the open mode. */	err = fmpCheckFileOpenMode(fd, F_WRITE);	if ( err < E_OK ) {		goto err_ret;	}	/* Parameter check */	if ( !((cmdPara->type >= 0) && (cmdPara->type < TSD_FPR_VAL_32))	   || (cmdPara->size < 0) ) {		err = E_PAR;		goto err_ret;	}	if ( isLinkRecord(cmdPara->type) != 0 ) {		/* Check when the link record is inserted. */		if ( ((UW)cmdPara->size != sizeof(LINK))		  || (cmdPara->buf == NULL) ) {			err = E_PAR;			goto err_ret;		}		err = CheckSpaceR(cmdPara->buf, sizeof(LINK));		if ( err < E_OK ) {			goto err_ret;		}		/* Check the contents of LINK. */		err = checkLINK((LINK*)cmdPara->buf, ofcb->fsinfo);		if ( err < E_OK ) {			goto err_ret;		}	}	/* Obtain the current record. */	rcb = fd->crcb;	if ( !isEndRCB(rcb, ofcb) ) {		err = fmpSetRCB(rcb, ofcb);		if ( err < E_OK ) {			goto err_ret;		}		/* Insert the record. */		err = insertRecord(&rcb, ofcb,			cmdPara->type, cmdPara->subtype, (LINK*)cmdPara->buf);		if ( err < E_OK ) {			goto err_ret;		}	} else {		/* Add the record. */		err = appendRecord(&rcb, ofcb,			cmdPara->type, cmdPara->subtype, (LINK*)cmdPara->buf);		if ( err < E_OK ) {			goto err_ret;		}	}	if ( isDataRecord(cmdPara->type) && (cmdPara->size > 0) ) {		/* Write the data record. */		err = fmpWriteDataRecord(rcb, ofcb,			0, cmdPara->buf, cmdPara->size, cmdPara->units);		if ( err < E_OK ) {			if ( err != E_NODSK ) {				goto err_ret;			}			error = err;		}	}	/* Update the time stamp. */	err = fmpSetTimeStamp(ofcb, F_WRITE);

⌨️ 快捷键说明

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