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

📄 open.c

📁 T-kernel 的extension源代码
💻 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. * *---------------------------------------------------------------------- *//* *	open.c (file) * *	File management *	File open/close *	Replace the file contents. */#include "fileio.h"#include "diskio.h"LOCAL ER exchangeFileHeader( OFCB *ofcb1, OFCB *ofcb2 );LOCAL void exchangeOFCB( OFCB *ofcb1, OFCB *ofcb2 );LOCAL ER exchangeFileContent( OFCB *ofcb1, OFCB *ofcb2 );/* * Obtain the open parameter. *	Map the file header and return the map ID. */EXPORT ID_ERR fmpGetOpenPara( OpenPara *opara, FID fid, FsInfo *fsinfo ){	ID	mid;	opara->fid = fid;	opara->fhd = fmpMapFileHeader(fid, &opara->dadr, &mid, fsinfo);	return mid;}/* * File open for internal use *	RCB and FD are not used. */EXPORT OFCB* fmpIOpenFile( OpenPara *opara, W omode,				PINFO *pinfo, FsInfo *fsinfo, ER *errp ){	FileAccMode	amode;	OFCB		*ofcb;	ER		err;	/* Fetch the file access mode. */	err = fmpGetFileAccMode(&amode, &opara->fhd->head, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Access right check */	err = fmpCheckFileAccMode(pinfo, &amode, (UW)omode, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Obtain OFCB. */	ofcb = fmpGetOFCB(opara, fsinfo, &err);	if ( ofcb == NULL ) {		goto err_ret1;	}	/* The exclusive access check is not preformed when doing only search access. */	if ( (UW)omode != F_EXCUTE ) {		/* Check the exclusive access mode. */		err = fmpCheckExclusiveOpen(ofcb, (UW)omode);		if ( err < E_OK ) {			goto err_ret2;		}	}	*errp = E_OK;	return ofcb;err_ret2:	fmpRemoveOFCB(ofcb, FALSE);err_ret1:	DEBUG_PRINT(("fmpIOpenFile err = %d\n", err));	*errp = err;	return NULL;}/* * Open the newly generated file. */EXPORT FD* fmpOpenNewFile( FID fid, W omode, PINFO *pinfo, FsInfo *fsinfo,								ER *err ){	OFCB		*ofcb;	FD		*fd;	OpenPara	opara;	ID		mid;	/* Obtain the open parameter. */	mid = fmpGetOpenPara(&opara, fid, fsinfo);	if ( mid < E_OK ) {		*err = (ER)mid;		goto err_ret1;	}	/* Obtain OFCB. */	ofcb = fmpGetOFCB(&opara, fsinfo, err);	if ( ofcb == NULL ) {		goto err_ret2;	}	/* Obtain FD. */	fd = fmpOpenFD(pinfo, (UW)omode, ofcb, err);	if ( fd == NULL ) {		goto err_ret3;	}	fmpUnmapDisk(mid, MD_RDONLY);	return fd;err_ret3:	fmpRemoveOFCB(ofcb, FALSE);err_ret2:	fmpUnmapDisk(mid, MD_RDONLY);err_ret1:	DEBUG_PRINT(("fmpOpenNewFile err = %d\n", *err));	return NULL;}/* * File open *	When writing into opara->fhd, return MD_WRITE. *	Otherwise, return MD_RDONLY. */EXPORT UW fmpOpenFile( FmCmdPkt *pkt, OpenPara *opara, FsInfo *fsinfo ){	FM_OPN_FIL_PARA	*cmdPara = (FM_OPN_FIL_PARA*)pkt->cmd.para;	FileAccMode	amode;	OFCB		*ofcb;	FD		*fd;	ER		err;	/* Parameter check */	if ( (((UW)cmdPara->o_mode & ~(UW)(F_UPDATE|F_EXCL|F_WEXCL)) != 0U)	  || (((UW)cmdPara->o_mode & (F_EXCL|F_WEXCL)) == (F_EXCL|F_WEXCL))	  || (((UW)cmdPara->o_mode & F_UPDATE) == 0U) ) {		err = E_PAR;		goto err_ret1;	}	/* Fetch the file access mode. */	err = fmpGetFileAccMode(&amode, &opara->fhd->head, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Access right check */	err = fmpCheckFileAccMode(pkt->wrk.pinfo, &amode, (UW)cmdPara->o_mode,								fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Password check */	err = fmpCheckPassWord(&opara->fhd->head, cmdPara->pwd, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Obtain OFCB. */	ofcb = fmpGetOFCB(opara, fsinfo, &err);	if ( ofcb == NULL ) {		goto err_ret1;	}	/* Check the exclusive access mode. */	err = fmpCheckExclusiveOpen(ofcb, (UW)cmdPara->o_mode);	if ( err < E_OK ) {		goto err_ret2;	}	/* Obtain FD. */	fd = fmpOpenFD(pkt->wrk.pinfo, (UW)cmdPara->o_mode, ofcb, &err);	if ( fd == NULL ) {		goto err_ret2;	}	pkt->cmd.ret = getFDno(fd);	return MD_RDONLY;err_ret2:	fmpRemoveOFCB(ofcb, FALSE);err_ret1:	DEBUG_PRINT(("fmpOpenFile err = %d\n", err));	pkt->cmd.ret = err;	return MD_RDONLY;}/* ------------------------------------------------------------------------ *//* * Close the file for internal use. */EXPORT ER fmpICloseFile( OFCB *ofcb, W omode ){	ER		err;	/* Write the cached data at the final close or final close of the write mode. */	if ( (ofcb->ref <= 0)	  || ((((UW)omode & F_WRITE) != 0U) && (ofcb->omode.write <= 0)) ) {		/* Write the cached data. */		err = fmpSyncFile(ofcb, ofcb->fsinfo);		if ( err < E_OK ) {			goto err_ret;		}	}	/* Delete OFCB. */	fmpRemoveOFCB(ofcb, FALSE);	return E_OK;err_ret:	DEBUG_PRINT(("fmpICloseFile err = %d\n", err));	return err;}/* * File close *	(*) It is called also from the cleanup service function. */EXPORT void fmpCloseFile( FmCmdPkt *pkt ){	FM_CLS_FIL_PARA	*cmdPara = (FM_CLS_FIL_PARA*)pkt->cmd.para;	FD		*fd;	OFCB		*ofcb;	FsInfo		*fsinfo;	ER		err, error = E_OK;	/* Obtain FD and OFCB. */	fd = getFDp(cmdPara->fd);	ofcb = fd->ofcb;	fsinfo = fd->fs;	/* Release all record locks. */	fmpUnlockAllRecord(fd, ofcb);	/* Release all record maps */	err = fmpUnmapAllRecord(fd, ofcb);	if ( err < E_OK ) {		error = err;	}	/* Write the cached data at the final close or final close of the write mode.	Write it also when the file system is connected in synchronous mode. */	if ( (fsinfo->conMode == FS_SYNC) || (ofcb->ref <= 1)	  || (((fd->omode & F_WRITE) != 0) && (ofcb->omode.write <= 1)) ) {		/* Write the cached data. */		err = fmpSyncFile(ofcb, fsinfo);		if ( err < E_OK ) {			error = err;		}	}	cancelSyncAtExit((UB)SAE_OPENF, fsinfo);	/* Release FD. */	fmpCloseFD(fd);	/* Delete OFCB. */	fmpRemoveOFCB(ofcb, FALSE);#ifdef DEBUG	if ( error < E_OK ) {		DEBUG_PRINT(("fmpCloseFile err = %d\n", error));	}#endif	pkt->cmd.ret = error;	return;}/* * Synchronize the files. */EXPORT void fmpSyncFileData( FmCmdPkt *pkt ){	FM_SYN_FIL_PARA	*cmdPara = (FM_SYN_FIL_PARA*)pkt->cmd.para;	FD		*fd;	OFCB		*ofcb;	FsInfo		*fsinfo;	ER		err, error = E_OK;	/* Obtain FD and OFCB. */	fd = getFDp(cmdPara->fd);	ofcb = fd->ofcb;	fsinfo = fd->fs;	/* Write the cached data. */	err = fmpSyncFile(ofcb, fsinfo);	if ( err < E_OK ) {		error = err;	}	cancelSyncAtExit((UB)SAE_OPENF, fsinfo);#ifdef DEBUG	if ( error < E_OK ) {		DEBUG_PRINT(("fmpSyncFileData err = %d\n", error));	}#endif	pkt->cmd.ret = error;	return;}/* ======================================================================== *//* * Replace the file header. */LOCAL ER exchangeFileHeader( OFCB *ofcb1, OFCB *ofcb2 ){	FsInfo			*fsinfo = ofcb1->fsinfo;	DfFileHeaderBlock	*fh1, *fh2;	ID			mid1, mid2;	VP			tmp;	W			tmpsize = (W)(fsinfo->sblk - sizeof(DfFileHeader));	ER			err;	/* Work memory */	tmp = Kmalloc((size_t)tmpsize);	if ( tmp == NULL ) {		err = E_SYSMEM;		goto err_ret1;	}	/* Map the file header. */	fh1 = fmpMapLogBlk(fmpDAdrToLBlk(ofcb1->fhead, fsinfo),						ofcb1, &mid1, fsinfo);	if ( fh1 == NULL ) {		err = (ER)mid1;		goto err_ret2;	}	fh2 = fmpMapLogBlk(fmpDAdrToLBlk(ofcb2->fhead, fsinfo),						ofcb2, &mid2, fsinfo);	if ( fh2 == NULL ) {		err = (ER)mid2;		goto err_ret3;	}	/* Replace the file header contents */	memcpy(tmp,     &fh1->f, (size_t)tmpsize);	memcpy(&fh1->f, &fh2->f, (size_t)tmpsize);	memcpy(&fh2->f, tmp,     (size_t)tmpsize);	xchg(H, fh1->head.nlnk,  fh2->head.nlnk);	xchg(H, fh1->head.idxlv, fh2->head.idxlv);	xchg(W, fh1->head.size,  fh2->head.size);	xchg(W, fh1->head.nblk,  fh2->head.nblk);	xchg(W, fh1->head.nrec,  fh2->head.nrec);	fmpUnmapDisk(mid1, MD_WRITE);	fmpUnmapDisk(mid2, MD_WRITE);	Kfree(tmp);	err = fmpCheckDiskError(ofcb1, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	err = fmpCheckDiskError(ofcb2, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	return err;err_ret3:	fmpUnmapDisk(mid1, MD_RDONLY);err_ret2:	Kfree(tmp);err_ret1:	DEBUG_PRINT(("exchangeFileHeader err = %d\n", err));	return err;}/* * Replace OFCB. */LOCAL void exchangeOFCB( OFCB *ofcb1, OFCB *ofcb2 ){	RCB	*top1, *top2;	/* Replace the file header information. */	xchg(H, ofcb1->idxlv, ofcb2->idxlv);	xchg(W, ofcb1->nrec,  ofcb2->nrec);	/* Replace RCB. */	top1 = FirstRCB(ofcb1);	top2 = FirstRCB(ofcb2);	if ( !isEndRCB(top1, ofcb1) ) {		QueRemove(&ofcb1->rcb);	} else {		top1 = NULL;	}	if ( !isEndRCB(top2, ofcb2) ) {		QueRemove(&ofcb2->rcb);	} else {		top2 = NULL;	}	if ( top2 != NULL ) {		QueInsert(&ofcb1->rcb, &top2->q);	} else {		QueInit(&ofcb1->rcb);	}	if ( top1 != NULL ) {		QueInsert(&ofcb2->rcb, &top1->q);	} else {		QueInit(&ofcb2->rcb);	}	/* Make all RCBs invalid. */	fmpSetInvalidAllRCB(ofcb1);	fmpSetInvalidAllRCB(ofcb2);}/* * Replace the file contents. */LOCAL ER exchangeFileContent( OFCB *ofcb1, OFCB *ofcb2 ){	ER	err;	/* Replace the file header. */	err = exchangeFileHeader(ofcb1, ofcb2);	if ( err < E_OK ) {		goto err_ret;	}	/* Replace OFCB. */	exchangeOFCB(ofcb1, ofcb2);	return E_OK;err_ret:	DEBUG_PRINT(("exchangeFileContent err = %d\n", err));	return err;}/* * Replace the file contents. */EXPORT void fmpExchangeFileContent( FmCmdPkt *pkt ){	FM_XCH_FIL_PARA	*cmdPara = (FM_XCH_FIL_PARA*)pkt->cmd.para;	FD		*fd1, *fd2;	OFCB		*ofcb1, *ofcb2;	FsInfo		*fsinfo;	ER		err;	/* Obtain FD and OFCB. */	fd1 = getFDp(cmdPara->fd_1);	ofcb1 = fd1->ofcb;	fsinfo = fd1->fs;	fd2 = fmGetFD(cmdPara->fd_2, pkt->wrk.pinfo);	if ( fd2 == NULL ) {		err = E_FD;		goto err_ret1;	}	ofcb2 = fd2->ofcb;	/* Whether it is the same file. */	if ( ofcb1 == ofcb2 ) {		err = E_PAR;		goto err_ret1;	}	/* Whether it is the same file system. */	if ( fd1->fs != fd2->fs ) {		err = E_XFS;		goto err_ret1;	}	/* Whether it is open in both update mode and exclusive mode. */	err = fmpCheckFileOpenMode(fd1, F_UPDATE|F_EXCL);	if ( err < E_OK ) {		goto err_ret1;	}	err = fmpCheckFileOpenMode(fd2, F_UPDATE|F_EXCL);	if ( err < E_OK ) {		goto err_ret1;	}	/* Whether some records are locked. */	err = fmpCheckLockAllRecord(ofcb1);	if ( err < E_OK ) {		goto err_ret1;	}	err = fmpCheckLockAllRecord(ofcb2);	if ( err < E_OK ) {		goto err_ret1;	}	/* Whether some records are mapped. */	if ( isMapRecords(fd1) || isMapRecords(fd2) ) {		err = E_BUSY;		goto err_ret1;	}	/* Replace the file contents. */	err = exchangeFileContent(ofcb1, ofcb2);	if ( err < E_OK ) {		goto err_ret2;	}	/* Define the current record as the first record. */	xchg(RCB*, fd1->crcb, fd2->crcb);	fmpMoveCurRecord(fd1, FirstRCB(ofcb1));	fmpMoveCurRecord(fd2, FirstRCB(ofcb2));	/* Update the time stamp. */	err = fmpSetTimeStamp(ofcb1, F_READ|F_WRITE);	if ( err < E_OK ) {		goto err_ret2;	}	err = fmpSetTimeStamp(ofcb2, F_READ|F_WRITE);	if ( err < E_OK ) {		goto err_ret2;	}	/* Write it here when the file system is connected in synchronous mode. */	if ( fsinfo->conMode == FS_SYNC ) {		err = fmpSyncFile(ofcb1, fsinfo);		if ( err < E_OK ) {			goto err_ret2a;		}		err = fmpSyncFile(ofcb2, fsinfo);		if ( err < E_OK ) {			goto err_ret1;		}	}	pkt->cmd.ret = E_OK;	return;err_ret2:	if ( fsinfo->conMode == FS_SYNC ) {		(void)fmpSyncFile(ofcb1, fsinfo);err_ret2a:	(void)fmpSyncFile(ofcb2, fsinfo);	}err_ret1:	DEBUG_PRINT(("fmpExchangeFileContent err = %d\n", err));	pkt->cmd.ret = err;	return;}

⌨️ 快捷键说明

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