📄 rwrec.c
字号:
} } 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 + -