📄 fmtask.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. * *---------------------------------------------------------------------- *//* * fmtask.c (file) * * File management * File manager task (Common section task) */#include "fminfo.h"#include "filesys.h"#include "others.h"#include "etc.h"Inline FD* getNextFD( FINFO *finfo );LOCAL void fmcInitialize( FmCmdPkt *pkt );LOCAL void fmcInitialize( FmCmdPkt *pkt );LOCAL void fmcFinish( FmCmdPkt *pkt );LOCAL void fmcCleanup( FmCmdPkt *pkt );LOCAL void fmcRequestAllFS( FmCmdPkt *pkt );LOCAL FwdID fmcSelectForward( FmCmdPkt *pkt );LOCAL FwdID selectLINK( FmCmdPkt *pkt, LINK *lnk );LOCAL FwdID fmcSelectLINK( FmCmdPkt *pkt );LOCAL FwdID fmcSelectFD( FmCmdPkt *pkt );LOCAL FwdID fmcChangeWorkFile( FmCmdPkt *pkt );LOCAL FwdID fmcDeleteFile( FmCmdPkt *pkt );LOCAL FwdID fmcChangeFileSystemMode( FmCmdPkt *pkt );LOCAL FwdID fmcEntry( FmCmdPkt *pkt );/* * Initialize the manager task. */LOCAL void fmcInitialize( FmCmdPkt *pkt ){ ER err; /* Initialize the link to FsInfo. */ QueInit(&fmInfo.fsLink); /* Initialize the file descriptor table. */ err = fmInitFileDescriptorTable(); if ( err < E_OK ) { goto err_ret; } return; /* * Error processing */err_ret: pkt->cmd.ret = err; return;}/* * Manager task termination */LOCAL void fmcFinish( FmCmdPkt *pkt ){ QUEUE *q; ER err; ER error = E_OK; /* Termination request to all the file systems being connected. */ while ( (q = fmInfo.fsLink.next) != &fmInfo.fsLink ) { FsInfo *fs = (FsInfo*)q; err = fmcCallFsTask(fs->port, pkt); if ( err < E_OK ) { error = err; } if ( pkt->cmd.ret < E_OK ) { error = pkt->cmd.ret; } err = fmcDeleteFileSystem(fs); if ( err < E_OK ) { error = err; } } /* Delete the file descriptor table. */ fmDeleteFileDescriptorTable(); pkt->cmd.ret = error; return;}/* * Fetch FD from FINFO. */Inline FD* getNextFD( FINFO *finfo ){ FD *fd; LOCK_PINFO_SECTION( fd = (FD*)finfo->fdList.next ); return fd;}/* * Cleanup service */LOCAL void fmcCleanup( FmCmdPkt *pkt ){ FM_CLEANUP_PARA *cmdPara = (FM_CLEANUP_PARA*)pkt->cmd.para; FINFO *finfo = &cmdPara->pinfo->file; FD *fd; ER err, error = E_OK; /* Close all files. */ while ( (fd = getNextFD(finfo)) != (FD*)&finfo->fdList ) { err = fmcICloseFile(fd); if ( err < E_OK ) { error = err; } } /* Release the work file. */ err = fmChangeWorkFile(cmdPara->pinfo, NULL, NULL); if ( err < E_OK ) { error = err; }#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("fmcCleanup err = %d\n", error)); }#endif pkt->cmd.ret = error;}/* * Processing request to all the file system tasks */LOCAL void fmcRequestAllFS( FmCmdPkt *pkt ){ QUEUE *q; ER err, error = E_OK; /* Processing request to all the file systems being connected. */ for ( q = fmInfo.fsLink.next; q != &fmInfo.fsLink; q = q->next ) { err = fmcCallFsTask(((FsInfo*)q)->port, pkt); if ( err < E_OK ) { error = err; } if ( pkt->cmd.ret < E_OK ) { error = pkt->cmd.ret; } } pkt->cmd.ret = error; return;}/* * Selection in the case of forwarding request from the file system task. */LOCAL FwdID fmcSelectForward( FmCmdPkt *pkt ){ FsInfo *fs; fs = fmSelectFileSystemOfLink(&pkt->wrk.lnk); if ( fs == NULL ) { DEBUG_PRINT(("fmcSelectForward: file system is not found\n")); pkt->cmd.ret = E_NOFS; return NoForward; } return fs->port;}/* * Select a file system with lnk. */LOCAL FwdID selectLINK( FmCmdPkt *pkt, LINK *lnk ){ FsInfo *fs; ER err; /* Check lnk. */ err = CheckSpaceR(lnk, sizeof(LINK)); if ( err != E_OK ) { DEBUG_PRINT(("CheckSpace err = %d\n", err)); pkt->cmd.ret = err; return NoForward; } /* Select a file system. */ fs = fmSelectFileSystemOfLink(lnk); if ( fs == NULL ) { DEBUG_PRINT(("selectLINK: file system is not found\n")); pkt->cmd.ret = E_NOFS; return NoForward; } return fs->port;}/* * Selection when the file is specified by LINK. */LOCAL FwdID fmcSelectLINK( FmCmdPkt *pkt ){ return selectLINK(pkt, (LINK*)((W*)pkt->cmd.para)[0]);}/* * Selection when the file is specified by file descriptor. */LOCAL FwdID fmcSelectFD( FmCmdPkt *pkt ){ W no; FD *fd; FsInfo *fs; ER err; /* Obtain the file descriptor number. */ no = ((W*)pkt->cmd.para)[0]; /* Obtain the file descriptor. */ fd = fmGetFD(no, pkt->wrk.pinfo); if ( fd == NULL ) { err = E_FD; goto err_ret; } fs = fd->fs; if ( fs == NULL ) { err = E_FD; goto err_ret; } return fs->port;err_ret: DEBUG_PRINT(("fmcSelectFD err = %d, fno = 0x%08x\n", err, pkt->cmd.fno.w)); pkt->cmd.ret = err; return NoForward;}/* * chg_wrk: Change the work file. */LOCAL FwdID fmcChangeWorkFile( FmCmdPkt *pkt ){ FM_CHG_WRK_PARA *cmdPara = (FM_CHG_WRK_PARA*)pkt->cmd.para; ER err; if ( cmdPara->lnk != NULL ) { return fmcSelectLINK(pkt); } /* Make the work file undefined. */ err = fmChangeWorkFile(pkt->wrk.pinfo, NULL, NULL); pkt->cmd.ret = err; return NoForward;}/* * del_fil: Select the file system of deletion file. */LOCAL FwdID fmcDeleteFile( FmCmdPkt *pkt ){ FM_DEL_FIL_PARA *cmdPara = (FM_DEL_FIL_PARA*)pkt->cmd.para; LINK *lnk; lnk = ( cmdPara->org != NULL )? cmdPara->org: cmdPara->lnk; return selectLINK(pkt, lnk);}/* * chg_fsm: Select the file system specified in the connection mode. */LOCAL FwdID fmcChangeFileSystemMode( FmCmdPkt *pkt ){ FM_CHG_FSM_PARA *cmdPara = (FM_CHG_FSM_PARA*)pkt->cmd.para; FsInfo *fs; ER err; /* Parameter check */ err = CheckStrSpaceR(cmdPara->dev, DevNameLen); if ( err < E_OK ) { goto err_ret; } /* Select a file system. */ fs = fmSelectFileSystemOfDevName(cmdPara->dev); if ( fs == NULL ) { err = E_NOFS; goto err_ret; } return fs->port;err_ret: DEBUG_PRINT(("fmcChangeFileSystemMode err = %d\n", err)); pkt->cmd.ret = err; return NoForward;}/* * Processing request entry */LOCAL FwdID fmcEntry( FmCmdPkt *pkt ){ FwdID fwdPort = NoForward; if ( isCmdForward(pkt) != 0 ) { /* Forwarding request from the file system task */ return fmcSelectForward(pkt); } switch ( pkt->cmd.fno.w ) { /* * Service request from inside OS */ case FM_INIT_FN: fmcInitialize(pkt); break; case FM_FINISH_FN: fmcFinish(pkt); break; case FM_CLEANUP_FN: fmcCleanup(pkt); break; case FM_BREAK_FN: fmcRequestAllFS(pkt); break; case FM_STARTUP_FN: /* These services should not be requested. */ pkt->cmd.ret = E_SYS; break; /* * One that specifies the file by path name */ case FM_GET_LNK_FN: fwdPort = fmcGetLink(pkt); break; /* * One that specifies the file by LINK */ case FM_CHG_WRK_FN: fwdPort = fmcChangeWorkFile(pkt); break; case FM_DEL_FIL_FN: fwdPort = fmcDeleteFile(pkt); break; case FM_CRE_FIL_FN: case FM_CRE_LNK_FN: case FM_GEN_FIL_FN: case FM_OPN_FIL_FN: case FM_CHK_FIL_FN: case FM_CHG_FMD_FN: case FM_CHG_FAT_FN: case FM_CHG_FNM_FN: case FM_CHG_FTM_FN: case FM_FIL_STS_FN: case FM_LNK_STS_FN: case FM_SYN_LNK_FN: case FM_GET_NLK_FN: case FMI_GetFileInfo_FN: case FMI_ChangeLinkFileName_FN: case FMI_SetWorkFile_FN: fwdPort = fmcSelectLINK(pkt); break; /* * One that specifies the file by file descriptor */ case FM_CLS_FIL_FN: case FM_SEE_REC_FN: case FM_FND_REC_FN: case FM_FND_LNK_FN: case FM_REA_REC_FN: case FM_WRI_REC_FN: case FM_INS_REC_FN: case FM_APD_REC_FN: case FM_DEL_REC_FN: case FM_TRC_REC_FN: case FM_XCH_FIL_FN: case FM_LOC_REC_FN: case FM_OFL_STS_FN: case FM_MAP_REC_FN: case FM_UMP_REC_FN: case FM_SYN_FIL_FN: case FM_GETRECINFO_FN: fwdPort = fmcSelectFD(pkt); break; /* * One that does not specify the file. */ case FM_GET_DFM_FN: fmcGetDefaultAccMode(pkt); break; case FM_SET_DFM_FN: fmcSetDefaultAccMode(pkt); break; /* * One relating to the file system */ case FM_ATT_FLS_FN: fmcAttachFileSystem(pkt); break; case FM_CHG_FSM_FN: fwdPort = fmcChangeFileSystemMode(pkt); break; case FM_DET_FLS_FN: fmcDetachFileSystem(pkt); break; case FM_SYN_FLS_FN: fmcSyncFileSystem(pkt); break; case FM_FLS_STS_FN: fmcGetFileSystemStatus(pkt); break; case FM_CHG_FLS_FN: fmcChangeFileSystemInfo(pkt); break; case FM_LST_FLS_FN: fmcListFileSystem(pkt); break; default: pkt->cmd.ret = E_RSFN; break; } return fwdPort;}/* * Manager task entry * calptn Type of rendezvous to receive */EXPORT void fmcMgrTask( UINT calptn ){ FmCmdPkt *pkt; FwdID fwdPort; RNO rdvno; INT cmsgsz; ER err; /* * Lock it except when the manager task goes into waiting. */ Lock(&fmInfo.lock); for ( ;; ) { /* It does not end by itself. */ /* Request reception */ Unlock(&fmInfo.lock); cmsgsz = tk_acp_por(fmInfo.entryPort, calptn, &rdvno, &pkt, TMO_FEVR); Lock(&fmInfo.lock); if ( cmsgsz < E_OK ) { DEBUG_PRINT(("acp_por er = %d\n", cmsgsz)); continue; } pkt->cmd.ret = E_OK; if ( pkt->cmd.tid != 0 ) { /* Obtain the process management information of request task. */ pkt->wrk.pinfo = GET_PINFO(pkt->cmd.tid); if ( pkt->wrk.pinfo == NULL ) { err = E_CTX; goto err_ret; } } /* Conform the task address space to the processing request task. */ err = SetTaskSpace(pkt->cmd.tid); if ( err != E_OK ) { goto err_ret; } /* Request processing */ fwdPort = fmcEntry(pkt); if ( fwdPort != NoForward ) { /* Forward to the file system task (Individual section task). */ err = fmForwardFsTask(fwdPort, rdvno, pkt); if ( err == E_OK ) { continue; } err_ret: pkt->cmd.ret = err; DEBUG_PRINT(("fmcMgrTask err = %d\n", err)); } /* Result response */ err = tk_rpl_rdv(rdvno, &pkt, sizeof(VP)); if ( err != E_OK ) { DEBUG_PRINT(("tk_rpl_rdv er = %d\n", err)); } } tk_exd_tsk(); /* It should not come here. */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -