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

📄 fstask.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. * *---------------------------------------------------------------------- *//* *	fstask.c (file) * *	File management *	File system task (Individual section task) */#include "fsinfo.h"#include "filesys.h"#include "fileio.h"#include "others.h"#include "diskio.h"LOCAL ER fmpGetFileSystemInfo( FsInfo *fsinfo );LOCAL void fmpAttachFileSystem( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL void fmpChangeFileSystemMode( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL void fmpDetachFileSystem( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL void fmpFinish( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL void fmpBreak( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL FwdID fdEntry( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL FwdID linkEntry( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL FwdID createEntry( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL FwdID deleteEntry( FmCmdPkt *pkt, FsInfo *fsinfo );LOCAL FwdID fmpEntry( FmCmdPkt *pkt, FsInfo *fsinfo );#define TSD_FAF_MSK_0X0003	0x0003U#define TSD_FGF_CNT_4		4/* * Obtain the file system information. */LOCAL ER fmpGetFileSystemInfo( FsInfo *fsinfo ){	static const UW	bootsz[] = StdBootBlkSizeList;#define	N_BOOTSZ	( sizeof(bootsz)/sizeof(UW) )	DfSystemHeader	*syshd = NULL;	DskAdrS		dskadr;	UH		ssys, sfidt;	BOOL		bigEndian;	ID		mid;	W		i;	FsSpec		fsspec;	ER		err;	/*	 * Retrieve the boot block size.	 *	Try some sizes.	 */	fsinfo->pbadj = 0; /* Because fmpMapDskAdrS() is used. */	for ( i = 0; i < (W)N_BOOTSZ; ++i ) {		if ( (UW)fsinfo->dskInfo.blocksize > bootsz[i] ) {			continue;		}		/* Map the system header. */		syshd = fmpMapDskAdrS((DskAdrS)bootsz[i],			sizeof(DfSystemHeader), MAP_SYS(fsinfo), &mid, fsinfo);		if ( syshd == NULL ) {			err = (ER)mid;			goto err_ret;		}		/* Check the disk format. */		err = fmCheckDiskFormat(syshd);		if ( err >= 0 ) {			/* OK: Set the file system format/endian format. */			fsinfo->diskform  = DiskFormVersion(err);			fsinfo->bigEndian = DiskFormEndian(err);			break;		}		fmpUnmapDisk(mid, MD_RDONLY);	}	if ( i >= (W)N_BOOTSZ ) {		err = E_ILFMT;		goto err_ret;	}	bigEndian = fsinfo->bigEndian;	/* Correction value for computing the physical block number   Correction value when the boot block size and logical block size are not equal */	fsinfo->pbadj =		((W)bootsz[i] - (W)fmConvEndianH(syshd->sblk, bigEndian))						/ fsinfo->dskInfo.blocksize;#if !MisalignLogBlk	if ( fsinfo->pbadj != 0 ) {		fmpUnmapDisk(mid, MD_RDONLY);		err = E_ILFMT;		goto err_ret;	}#endif	/* Obtain the file system information. */	fsinfo->acclv = (H)fmConvEndianH((UH)syshd->acclv, bigEndian);	fsinfo->nbmp  = (W)fmConvEndianH(syshd->nbmp, bigEndian);	fsinfo->nfmax = fmConvEndianH(syshd->nfmax, bigEndian);	fsinfo->nlb   = (W)fmConvEndianW((UW)syshd->nlb, bigEndian);	fsinfo->sblk  = fmConvEndianH(syshd->sblk, bigEndian);	(void)fmConvEndianTC(fsinfo->fsName, (TC*)syshd->fsnm, FsNameLen, bigEndian);	if ( fsinfo->diskform >= DiskForm_B ) {		/* STDFS extended format */		fsinfo->nbmp *= TSD_FGF_CNT_4;	/* Bit map is word count. */	}	fsinfo->blkRatio = (UH)(fsinfo->sblk / fsinfo->dskInfo.blocksize);	ssys  = fmConvEndianH(syshd->ssys, bigEndian);	sfidt = fmConvEndianH(syshd->sfidt, bigEndian);	fsinfo->shead = dskadr = (DskAdrS)(UW)fsinfo->sblk;	fsinfo->usebm = (VB*)dskadr + sizeof(DfSystemHeader);	fsinfo->fidt  = (VB*)dskadr + (ssys * fsinfo->sblk);	fsinfo->fsnt  = (VB*)dskadr + ((ssys + sfidt) * fsinfo->sblk);	fmpUnmapDisk(mid, MD_RDONLY);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Notify the segment management of the file system information. */	fsspec.lbsz = fsinfo->sblk;	fsspec.btsz = (UH)bootsz[i];	err = InformFS(fsinfo->dskid, &fsspec);	if ( err < E_OK ) {		if ( err == E_BUSY ) {			err = E_SYS;		}		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpGetFileSystemInfo err = %d\n", err));	return err;}/* * att_fls: Connect the file system. */LOCAL void fmpAttachFileSystem( FmCmdPkt *pkt, FsInfo *fsinfo ){	FM_ATT_FLS_PARA		*cmdPara = (FM_ATT_FLS_PARA*)pkt->cmd.para;	DfFileHeaderBlock	*fhd;	ID			mid;	W			i;	ER			err;	/* Initialize the file system management information (FsInfo). */	for ( i = 0; i < OFCB_QSZ; ++i ) {		QueInit(&fsinfo->ofcb[i]);	}	QueInit(&fsinfo->wrkFilLst);	QueInit(&fsinfo->resumeReq);	/* Fetch the connection parameter. */	err = fmGetAplStr(fsinfo->devName, cmdPara->dev, DevNameLen);	if ( err < E_OK ) {		goto err_ret1;	}	err = fmGetAplStr(fsinfo->conName, cmdPara->name, ConNameLen);	if ( err < E_OK ) {		goto err_ret1;	}	if ( (cmdPara->mode & ~TSD_FAF_MSK_0X0003) != 0U ) {		err = E_PAR;		goto err_ret1;	}	fsinfo->conMode = cmdPara->mode;	/* Parameter check  */	err = fmCheckFileName(fsinfo->conName, ConNameLen);	if ( err < E_OK ) {		goto err_ret1;	}	err = fmConNameExist(fsinfo->conName);	if ( err < E_OK ) {		goto err_ret1;	}	if ( cmdPara->lnk != NULL ) {		err = CheckSpaceRW(cmdPara->lnk, sizeof(LINK));		if ( err < E_OK ) {			goto err_ret1;		}	}	/* Register the disk exception handler. */	err = fmpDefineDiskErrorHandler(TRUE);	if ( err < E_OK ) {		goto err_ret1;	}	/* Connect the file system. */	err = AttachFS(fsinfo->devName, D_ATTACH|D_WEXCL,				pkt->wrk.pinfo, &fsinfo->dskInfo);	if ( err < E_OK ) {		goto err_ret2;	}	fsinfo->dskid = (ID)err;	/* Check the disk partition information. */	err = fmCheckPartitionID(fsinfo->devName);	if ( err < E_OK ) {		goto err_ret3;	}	/* Obtain the file system information. */	err = fmpGetFileSystemInfo(fsinfo);	if ( err < E_OK ) {		goto err_ret3;	}	/* Check the file header ID of the root file. */	fhd = fmpMapFileHeader(0, NULL, &mid, fsinfo);	if ( fhd == NULL ) {		err = ( mid == E_NOEXS )? E_ILFMT: mid;		goto err_ret3;	}	i = ( (fmpConvEndianW(fhd->head.startid, fsinfo) == FileHeaderTopID)	   && (fmpConvEndianW(fhd->head.endid,   fsinfo) == FileHeaderEndID) )?							E_OK: E_ILFMT;	fmpUnmapDisk(mid, MD_RDONLY);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret3;	}	err = i;	if ( err < E_OK ) {		goto err_ret3;	}	/* Whether the file system of the same name is already connected. */	err = fmFsNameExist(fsinfo->fsName);	if ( err < E_OK ) {		goto err_ret3;	}	if ( cmdPara->lnk != NULL ) {		/* Return the link to the root file. */		*cmdPara->lnk = RootFile(fsinfo);	}	pkt->cmd.ret = E_OK;	return;err_ret3:	(void)DetachFS(fsinfo->dskid, NULL, FALSE);err_ret2:	(void)fmpDefineDiskErrorHandler(FALSE);err_ret1:	DEBUG_PRINT(("fmpAttachFileSystem err = %d\n", err));	pkt->cmd.ret = err;	return;}/* * chg_fsm: Change the connection mode of the file system. */LOCAL void fmpChangeFileSystemMode( FmCmdPkt *pkt, FsInfo *fsinfo ){	FM_CHG_FSM_PARA	*cmdPara = (FM_CHG_FSM_PARA*)pkt->cmd.para;	UW		old;	ER		err;	/* Parameter check  */	if ( (cmdPara->mode & ~TSD_FAF_MSK_0X0003) != 0U ) {		err = E_PAR;		goto err_ret;	}	/* Access right check */	err = CheckFS(cmdPara->dev, D_ATTACH, pkt->wrk.pinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Synchronize the disk. */	err = SyncFS(fsinfo->dskid, 0);	if ( err < E_OK ) {		goto err_ret;	}	/* Change the connection mode. */	old = fsinfo->conMode;	fsinfo->conMode = cmdPara->mode;	pkt->cmd.ret = (W)old;	return;err_ret:	DEBUG_PRINT(("fmpChangeFileSystemMode err = %d\n", err));	pkt->cmd.ret = err;	return;}/* * det_fls: Disconnect the file system. */LOCAL void fmpDetachFileSystem( FmCmdPkt *pkt, FsInfo *fsinfo ){	FM_DET_FLS_PARA	*cmdPara = (FM_DET_FLS_PARA*)pkt->cmd.para;	W		i;	ER		err;	/* Whether there is a file being opened. */	for ( i = 0; i < OFCB_QSZ; ++i ) {		if ( !isQueEmpty(&fsinfo->ofcb[i]) ) {			err = E_BUSY;			goto err_ret;		}	}	/* Whether it is specified as the work file */	if ( !isQueEmpty(&fsinfo->wrkFilLst) ) {		err = E_BUSY;		goto err_ret;	}	/* Disconnect the file system. */	err = DetachFS(fsinfo->dskid, pkt->wrk.pinfo, cmdPara->eject);	i   = fmpCheckDiskError(NULL, fsinfo);	if ( (err < E_OK) || ((err = i) < E_OK) ) {		goto err_ret;	}	/*** Hereafter, the disconnection processing can not be stopped. ***/	/* Deregister the disk exception handler. */	(void)fmpDefineDiskErrorHandler(FALSE);	pkt->cmd.ret = E_OK;	return;err_ret:	DEBUG_PRINT(("fmpDetachFileSystem err = %d\n", err));	pkt->cmd.ret = err;	return;}/* * Forcefully disconnect the file system. */LOCAL void fmpFinish( FmCmdPkt *pkt, FsInfo *fsinfo ){	ER	err, error = E_OK;	/* Disconnect the file system. */	err = DetachFS(fsinfo->dskid, NULL, TRUE);	if ( err < E_OK ) {		error = err;	}	/* Deregister the disk exception handler. */	(void)fmpDefineDiskErrorHandler(FALSE);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		error = err;	}	/* Delete OFCB and RCB. */	err = fmpDeleteAllOFCB(fsinfo);	if ( err < E_OK ) {		error = err;	}	/* Detach the queue just in case. */	QueRemove(&fsinfo->wrkFilLst);	QueRemove(&fsinfo->resumeReq);#ifdef DEBUG	if ( error < E_OK ) {		DEBUG_PRINT(("fmpFinish err = %d\n", error));	}#endif	pkt->cmd.ret = error;	return;}/* * Break service */LOCAL void fmpBreak( FmCmdPkt *pkt, FsInfo *fsinfo ){	FM_BREAK_PARA	*cmdPara = (FM_BREAK_PARA*)pkt->cmd.para;	PINFO		*pinfo;	QUEUE		*fdList, *q;	FD		*fd;	FmCmdPkt	*waitReq;	ER		err, error = E_OK;	/* Process to break */	pinfo = GET_PINFO(cmdPara->tskid);	if ( pinfo == NULL ) {		error = E_CTX;		goto err_ret;	}	LockFD();	fdList = &pinfo->file.fdList;	for ( q = fdList->next; q != fdList; q = q->next ) {		fd = (FD*)q;		if ( fd->fs != fsinfo ) {			continue;		}		waitReq = fd->waitReq;		if ( (waitReq != NULL) && (waitReq->cmd.tid == cmdPara->tskid) ) {			/* Release the lock waiting. */			err = fmpBreakLockWait(waitReq, fsinfo);			if ( err < E_OK ) {				error = err;			}			fd->waitReq = NULL;		}	}	UnlockFD();err_ret:#ifdef DEBUG	if ( error < E_OK ) {		DEBUG_PRINT(("fmpBreak err = %d\n", error));	}#endif	pkt->cmd.ret = error;	return;}/* * Request processing entry when the file is specified by FD. */LOCAL FwdID fdEntry( FmCmdPkt *pkt, FsInfo *fsinfo ){	FD		*fd;	FmCmdPkt	*waitReq;	FwdID		fwd = NoForward;	ER		err;	/* Obtain FD. */	fd = fmGetFD(((W*)pkt->cmd.para)[0], pkt->wrk.pinfo);	if ( fd == NULL ) {		err = E_FD;		goto err_ret1;	}	waitReq = fd->waitReq;	if ( (waitReq != NULL) && (waitReq != pkt) ) {		/* There exists an indeterminate waiting request (Double execution) */		err = E_BUSY;		goto err_ret1;	}	switch ( pkt->cmd.fno.w ) {	  case FM_CLS_FIL_FN:		fmpCloseFile(pkt);		break;	  case FM_SEE_REC_FN:		fmpSeekRecord(pkt);		break;	  case FM_FND_REC_FN:		fmpFindRecord(pkt);		break;	  case FM_FND_LNK_FN:		fmpFindLinkRecord(pkt);		break;	  case FM_REA_REC_FN:		fmpReadRecord(pkt);		break;	  case FM_WRI_REC_FN:		fmpWriteRecord(pkt);		break;	  case FM_INS_REC_FN:		fmpInsertRecord(pkt);		break;	  case FM_APD_REC_FN:		fmpAppendRecord(pkt);		break;

⌨️ 快捷键说明

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