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

📄 rwrec.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	}	return error;err_ret:	DEBUG_PRINT(("fmpWriteDataRecord err = %d\n", err));	return err;}/* * Write the link record. */LOCAL ER writeLinkRecord( RCB *rcb, OFCB *ofcb, FM_WRI_REC_PARA *cmdPara ){	FsInfo		*fsinfo = ofcb->fsinfo;	DfLinkIndex	*lidx;	LINK		*lnk;	ID		mid;	ER		err;	/* Parameter check */	if ( (cmdPara->offset != 0)	  || (cmdPara->size < (W)sizeof(LINK)) ) {		return E_PAR;	}	if ( cmdPara->buf == NULL ) {		return E_OK;	}	/* Map the record index. */	lidx = fmpMapDskAdr(rcb->idxadr.ridx, sizeof(DfLinkIndex),						ofcb, &mid, fsinfo);	if ( lidx == NULL ) {		return (ER)mid;	}	/* Check LINK area. */	lnk = (LINK*)cmdPara->buf;	err = CheckSpaceR(lnk, sizeof(LINK));	if ( err < E_OK ) {		goto err_ret;	}	/* Write LINK. (Only attribute) */	lidx->atr[TSD_WLR_VAL_0] = fmpConvEndianH(lnk->atr1, fsinfo);	lidx->atr[TSD_WLR_VAL_1] = fmpConvEndianH(lnk->atr2, fsinfo);	lidx->atr[TSD_WLR_VAL_2] = fmpConvEndianH(lnk->atr3, fsinfo);	lidx->atr[TSD_WLR_VAL_3] = fmpConvEndianH(lnk->atr4, fsinfo);	lidx->atr[TSD_WLR_VAL_4] = fmpConvEndianH(lnk->atr5, fsinfo);	fmpUnmapDisk(mid, MD_WRITE);	return fmpCheckDiskError(ofcb, fsinfo);err_ret:	fmpUnmapDisk(mid, MD_RDONLY);	DEBUG_PRINT(("writeLinkRecord err = %d\n", err));	return err;}/* * Write the record. */EXPORT void fmpWriteRecord( FmCmdPkt *pkt ){	FM_WRI_REC_PARA	*cmdPara = (FM_WRI_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;	}	/* Obtain the current record. */	err = fmpSetRCB(rcb = fd->crcb, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	/* Parameter check */	if ( (cmdPara->offset < TSD_FWR_VAL_M1) || (cmdPara->offset > rcb->rsize)	  || (cmdPara->size < 0) ) {		err = E_PAR;		goto err_ret;	}	/* Check the record lock. */	if ( isLockRecord(fd, rcb) != 0 ) {		err = E_LOCK;		goto err_ret;	}	/* Check the record map. */	if ( isMapRecord(rcb) != 0 ) {		err = E_BUSY;		goto err_ret;	}	/* Check the subtype. */	if ( cmdPara->subtype != NULL ) {		err = CheckSpaceR(cmdPara->subtype, sizeof(UH));		if ( err < E_OK ) {			goto err_ret;		}		/* Change the record subtype. */		err = fmpSetSubtypeRCB(rcb, *cmdPara->subtype, ofcb);		if ( err < E_OK ) {			goto err_ret;		}	}	/* Adjust the offset. */	if ( cmdPara->offset == TSD_FWR_VAL_M1 ) {		cmdPara->offset = rcb->rsize;	}	if ( !(cmdPara->size == 0) ) {		if ( isLinkRecord(rcb->rtype) != 0 ) {			/* Write the link record. */			err = writeLinkRecord(rcb, ofcb, cmdPara);			if ( err < E_OK ) {				goto err_ret;			}		} else {			/* Write the data record. */			err = fmpWriteDataRecord(rcb, ofcb, cmdPara->offset,				cmdPara->buf, cmdPara->size, cmdPara->units);			if ( err < E_OK ) {				if ( err != E_NODSK ) {					goto err_ret;				}				error = err;			}		}	}	/* Return r_size */	if ( cmdPara->r_size != NULL ) {		err = CheckSpaceRW(cmdPara->r_size, sizeof(W));		if ( err < E_OK ) {			goto err_ret;		}		*cmdPara->r_size = rcb->rsize - cmdPara->offset;	}	/* Update the time stamp. */	err = fmpSetTimeStamp(ofcb, F_WRITE);	if ( err < E_OK ) {		goto err_ret;	}	pkt->cmd.ret = error;	setSyncAtExit(SAE_OPENF, ofcb->fsinfo);	return;err_ret:	DEBUG_PRINT(("fmpWriteRecord err = %d\n", err));	pkt->cmd.ret = err;	setSyncAtExit(SAE_OPENF, ofcb->fsinfo);	return;}/* ------------------------------------------------------------------------ *//* * Reduce the record size for internal use. *	The record size is reduced but the file header is not updated. *	(Note) newsize must be smaller than the current record size. *	     (newsize < Current record size) */EXPORT ER fmpITruncateDataRecord( RIdx *ri, W newsize ){	FsInfo		*fsinfo = ri->ofcb->fsinfo;	DfRecordIndex	*ridx;	W		cp;	LogBlk		lblk;	W		end, total, blktp;	W		oldsize;	ER		err;	/* Obtain the location of the first data block and normal index.  */	err = fmpGetDataBlkAdr(ri, &lblk);	if ( err < E_OK ) {		goto err_ret;	}	ridx = fmpGetMapAdr(ri, &cp);	/* Current record size */	oldsize = (W)fmpConvEndianW(ridx->n.size, fsinfo);	/* Update the record size. */	ridx->n.size = fmpConvEndianW((UW)newsize, fsinfo);	fmpSetRIdxMapFlag(ri, MD_WRITE);	blktp = - fmpConvEndianH(ridx->n.offset, fsinfo);	total = blktp + (lblk.cnt * fsinfo->sblk);	/* Find the record end after the reduction. (Location of newsize) */	while ( total <= newsize ) {		/* Obtain the location of data blocks after the first one from the connection index. */		err = fmpGetDataBlkAdr(ri, &lblk);		if ( err < E_OK ) {			goto err_ret;		}		blktp = total;		total += lblk.cnt * fsinfo->sblk;	}	/* Delete after the newsize. */	end = ( total > oldsize )? (oldsize - blktp): (total - blktp);	err = fmpDeleteDataBlk(ri, newsize - blktp, end, (newsize == 0));	if ( err < E_OK ) {		goto err_ret;	}	/* Delete up to the end of remaining record. */	while ( total < oldsize ) {		/* Obtain the location of data blocks after the first one from the connection index.  */		err = fmpGetDataBlkAdr(ri, &lblk);		if ( err < E_OK ) {			goto err_ret;		}		blktp = total;		total += lblk.cnt * fsinfo->sblk;		/* Delete */		end = ( total > oldsize )? (oldsize - blktp): (total - blktp);		err = fmpDeleteDataBlk(ri, 0, end, FALSE);		if ( err < E_OK ) {			goto err_ret;		}	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpITruncateDataRecord err = %d\n", err));	return err;}/* * Reduce the record size. */EXPORT ER fmpTruncateDataRecord( RCB *rcb, OFCB *ofcb, W newsize ){	RIdx		ri;	ER		err;	/* Prepare to obtain the record index. */	err = fmpOpenRIdx(&ri, &rcb->idxadr, ofcb);	if ( err < E_OK ) {		goto err_ret1;	}	/* Reduce the record size. */	err = fmpITruncateDataRecord(&ri, newsize);	if ( err < E_OK ) {		goto err_ret2;	}	err = fmpCloseRIdx(&ri);	if ( err < E_OK ) {		goto err_ret1;	}	/* Update the total byte count of the file of the file header. */	err = changeFileSize(ofcb, newsize - rcb->rsize);	if ( err < E_OK ) {		goto err_ret1;	}	/* Update the record size. */	rcb->rsize = newsize;	return E_OK;err_ret2:	(void)fmpCloseRIdx(&ri);err_ret1:	/* Make RCB invalid for safety. */	setInvalidRCB(rcb);	DEBUG_PRINT(("fmpTruncateDataRecord err = %d\n", err));	return err;}/* * Reduce the record size. */EXPORT void fmpTruncateRecord( FmCmdPkt *pkt ){	FM_TRC_REC_PARA	*cmdPara = (FM_TRC_REC_PARA*)pkt->cmd.para;	FD		*fd;	OFCB		*ofcb;	RCB		*rcb;	ER		err;	/* 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;	}	/* Obtain the current record. */	err = fmpSetRCB(rcb = fd->crcb, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	/* Parameter check */	if ( cmdPara->size < 0 ) {		err = E_PAR;		goto err_ret;	}	/* Check the record type. */	if ( isLinkRecord(rcb->rtype) != 0 ) {		err = E_REC;		goto err_ret;	}	/* Check the record lock. */	if ( isLockRecord(fd, rcb) != 0 ) {		err = E_LOCK;		goto err_ret;	}	/* Check the record map. */	if ( isMapRecord(rcb) != 0 ) {		err = E_BUSY;		goto err_ret;	}	if ( cmdPara->size < rcb->rsize ) {		/* Reduce the record size. */		err = fmpTruncateDataRecord(rcb, ofcb, cmdPara->size);		if ( err < E_OK ) {			goto err_ret;		}		/* Update the time stamp. */		err = fmpSetTimeStamp(ofcb, F_WRITE);		if ( err < E_OK ) {			goto err_ret;		}	}	pkt->cmd.ret = E_OK;	setSyncAtExit(SAE_OPENF, ofcb->fsinfo);	return;err_ret:	DEBUG_PRINT(("fmpTruncateRecord err = %d\n", err));	pkt->cmd.ret = err;	setSyncAtExit(SAE_OPENF, ofcb->fsinfo);	return;}/* ------------------------------------------------------------------------ *//* * Obtain the record block list. *	Fetch the block list of rcb record and store it in blklst. *	blklst stores up to max. (The excess is abandoned) *	Return the start position offset of the record to *offset. *	As a return value, return the number of entries in the whole block list.  */LOCAL WER getRecordBlockList( RCB *rcb, OFCB *ofcb,					PhyBlk blklst[], W *offset, W max ){	LBlks	lb;	LogBlk	*lblk;	W	n, prev;	FsInfo	*fsinfo = ofcb->fsinfo;	W	blkRatio = (W)fsinfo->blkRatio;	ER	err;	if ( rcb->rsize <= 0 ) {		return 0;	}	/* Prepare the block list. */	err = fmNewLBlks(&lb);	if ( err < E_OK ) {		goto err_ret1;	}	/* Create the block list. */	err = fmpMakeLBlks(&lb, rcb, 0, rcb->rsize, ofcb);	if ( err < E_OK ) {		goto err_ret2;	}	if ( offset != NULL ) {		*offset = (W)err;	}	/* Store the block list in blklst. */	lblk = NULL;	prev = TSD_GRB_PRE_M1;	n = 0;	while ( fmNextLBlks(&lb, &lblk) != 0 ) {		if ( lblk->adr == prev ) {			/* It is continued from the previous block. */			if ( n <= max ) {				(blklst - 1)->len += (UW)(lblk->cnt * blkRatio);			}		} else {			if ( ++n <= max ) {				blklst->blk = (UW)((lblk->adr * blkRatio)							+ fsinfo->pbadj);				blklst->len = (UW)(lblk->cnt * blkRatio);				blklst++;			}		}		prev = lblk->adr + lblk->cnt;	}	fmDeleteLBlks(&lb);	return n;err_ret2:	fmDeleteLBlks(&lb);err_ret1:	DEBUG_PRINT(("getRecordBlockList err = %d\n", err));	return err;}/* * Fetch the block configuration of the record. */EXPORT void fmpGetRecordInfo( FmCmdPkt *pkt ){	FM_GETRECINFO_PARA	*cmdPara = (FM_GETRECINFO_PARA*)pkt->cmd.para;	FD			*fd;	OFCB			*ofcb;	RCB			*rcb;	ER			err;	/* Obtain FD and OFCB. */	fd = getFDp(cmdPara->fd);	ofcb = fd->ofcb;	/* Obtain the current record. */	err = fmpSetRCB(rcb = fd->crcb, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	/* Link record is disabled. */	if ( isLinkRecord(rcb->rtype) != 0 ) {		err = E_REC;		goto err_ret;	}	/* Obtain the block configuration. */	err = getRecordBlockList(rcb, ofcb,			cmdPara->block, cmdPara->offset, cmdPara->entry_len);	if ( err < E_OK ) {		goto err_ret;	}	if ( cmdPara->n_entry != NULL ) {		*cmdPara->n_entry = (W)err;	}	/* Return the record size. */	if ( cmdPara->recsize != NULL ) {		*cmdPara->recsize = rcb->rsize;	}	/* Return the disk ID. */	pkt->cmd.ret = ofcb->fsinfo->dskid;	return;err_ret:	DEBUG_PRINT(("fmpGetRecordInfo err = %d\n", err));	pkt->cmd.ret = err;	return;}

⌨️ 快捷键说明

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