📄 filesys.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. * *---------------------------------------------------------------------- *//* * filesys.c (file) * * File management * File system connection/disconnection etc. */#include "filesys.h"#include "diskio.h"LOCAL WER attachDevice( DevName dev, UW omode, PINFO *pinfo, DiskInfo *diskinfo, FsInfo **fs );LOCAL ER detachDevice( ID diskid, FsInfo *fs );LOCAL ER checkRootFileHeaderID( DfSystemHeader *sh, DiskMapInfo *dmInfo );LOCAL void getFileSystemStatus( FS_STATE *fs, DfSystemHeader *sh, BOOL big );LOCAL ER changeRootFileName( FileName fname, DfSystemHeader *sh, DiskMapInfo *dmInfo );LOCAL ER changeFileSystemInfo( TC *fsnm, TC *dlnm, FsInfo *fs, DfSystemHeader *sh, DiskMapInfo *dmInfo, UW *mdflg );#define TSD_FMC_CNT_M2 (-2)/* * Select a file system by the device name. */EXPORT FsInfo* fmSelectFileSystemOfDevName( DevName dev ){ QUEUE *q; FsInfo *fs; W cmp; for ( q = fmInfo.fsLink.next; q != &fmInfo.fsLink; q = q->next ) { fs = (FsInfo*)q; cmp = tc_strncmp(dev, fs->devName, DevNameLen); if ( cmp == 0 ) { return fs; } } return (FsInfo*)NULL;}/* * Select a file system by the connection name. */EXPORT FsInfo* fmSelectFileSystemOfConName( ConName con ){ QUEUE *q; FsInfo *fs; W cmp; for ( q = fmInfo.fsLink.next; q != &fmInfo.fsLink; q = q->next ) { fs = (FsInfo*)q; cmp = tc_strncmp(con, fs->conName, ConNameLen); if ( cmp == 0 ) { return fs; } } return (FsInfo*)NULL;}/* * Select a file system by the file system name. */EXPORT FsInfo* fmSelectFileSystemOfFsName( FsName fsnm ){ QUEUE *q; FsInfo *fs; W cmp; for ( q = fmInfo.fsLink.next; q != &fmInfo.fsLink; q = q->next ) { fs = (FsInfo*)q; cmp = tc_strncmp(fsnm, fs->fsName, FsNameLen); if ( cmp == 0 ) { return fs; } } return (FsInfo*)NULL;}/* ------------------------------------------------------------------------ *//* * att_fls: File system connection */EXPORT void fmcAttachFileSystem( FmCmdPkt *pkt ){ FsInfo *fs; T_CTSK ctsk; ER err; /* Reserve the memory for the file system management information. */ fs = (FsInfo*)Kmalloc(sizeof(FsInfo)); if ( fs == NULL ) { err = E_NOMEM; goto err_ret1; } memset(fs, 0, (size_t)sizeof(FsInfo)); /* Create the lock for exclusive access. */ err = CreateLock(&fs->lock, (UB*)"FSys"); if ( err < E_OK ) { goto err_ret2; } /* Generate the rendezvous port for command forwarding. */ SetOBJNAME(fmPortAttr.exinf, "FSys"); err = tk_cre_por(&fmPortAttr); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret3; } fs->port = (ID)err; /* Generate/Start the file system task. */ SetFsTaskAttr(&ctsk, fs, fmInfo.fsTskPri); err = tk_cre_tsk(&ctsk); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret4; } fs->tskid = (ID)err; err = tk_sta_tsk(fs->tskid, fs->port); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret5; } /* Connection request to the file system task. */ err = fmcCallFsTask(fs->port, pkt); if ( err < E_OK ) { goto err_ret6; } err = pkt->cmd.ret; if ( err < E_OK ) { goto err_ret6; } QueInsert(&fs->q, &fmInfo.fsLink); return; /* * Error processing */err_ret6: (void)tk_ter_tsk(fs->tskid);err_ret5: (void)tk_del_tsk(fs->tskid);err_ret4: (void)tk_del_por(fs->port);err_ret3: DeleteLock(&fs->lock);err_ret2: Kfree((VB*)fs);err_ret1: DEBUG_PRINT(("fmcAttchFileSystem err = %d\n", err)); pkt->cmd.ret = err; return;}/* * det_fls: Disconnect the file system. */EXPORT void fmcDetachFileSystem( FmCmdPkt *pkt ){ FM_DET_FLS_PARA *cmdPara = (FM_DET_FLS_PARA*)pkt->cmd.para; FsInfo *fs; ER err; /* Select a file system. */ err = CheckStrSpaceR(cmdPara->dev, DevNameLen); if ( err < E_OK ) { goto ret; } fs = fmSelectFileSystemOfDevName(cmdPara->dev); if ( fs == NULL ) { err = E_NOFS; goto ret; } /* Disconnection request to the file system task. */ err = fmcCallFsTask(fs->port, pkt); if ( err < E_OK ) { goto ret; } err = pkt->cmd.ret; if ( err < E_OK ) { goto ret; } /*** Hereafter, the disconnection processing can not be stopped. ***/ /* Delete the file system. */ (void)fmcDeleteFileSystem(fs);ret: pkt->cmd.ret = err; return;}/* * Delete the file system * (Even if an error occurs halfway through the processing, it is not stopped.) */EXPORT ER fmcDeleteFileSystem( FsInfo *fs ){ ER err = E_OK; /* Stop/Delete the file system task. */ err = tk_ter_tsk(fs->tskid); if ( err != E_OK ) { DEBUG_PRINT(("tk_ter_tsk er = %d\n", err)); err = ERtoERR(err); } err = tk_del_tsk(fs->tskid); if ( err != E_OK ) { DEBUG_PRINT(("tk_del_tsk er = %d\n", err)); err = ERtoERR(err); } /* Delete the rendezvous port for command forwarding */ err = tk_del_por(fs->port); if ( err != E_OK ) { DEBUG_PRINT(("tk_del_por er = %d\n", err)); err = ERtoERR(err); } /* Delete the lock for exclusive access. */ DeleteLock(&fs->lock); /* Delete the memory for file system management information. */ QueRemove(&fs->q); Kfree((VB*)fs); return err;}/* * syn_fls: Synchronize the file system. */EXPORT void fmcSyncFileSystem( FmCmdPkt *pkt ){ QUEUE *q; ER err, error = E_OK; /* Synchronize all the file systems being connected in sequence. */ for ( q = fmInfo.fsLink.next; q != &fmInfo.fsLink; q = q->next ) { err = SyncFS(((FsInfo*)q)->dskid, 0); if ( err < E_OK ) { error = err; } }#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("fmcSyncFileSystem err = %d\n", error)); }#endif pkt->cmd.ret = error; return;}/* ------------------------------------------------------------------------ *//* * lst_fls: List the file systems. */EXPORT void fmcListFileSystem( FmCmdPkt *pkt ){ FM_LST_FLS_PARA *cmdPara = (FM_LST_FLS_PARA*)pkt->cmd.para; W cnt = cmdPara->cnt; F_ATTACH *buf = cmdPara->buff; W nfs; /* The number of connected file systems */ FsInfo *fs; ER err; /* Parameter check */ if ( (cnt == 0) || (cnt < TSD_FMC_CNT_M2) ) { err = E_PAR; goto err_ret; } if ( cnt < 0 ) { cnt = 1; } err = CheckSpaceRW(buf, (W)(sizeof(F_ATTACH)*(UW)cnt)); if ( err != E_OK ) { goto err_ret; } if ( cmdPara->cnt > 0 ) { QUEUE *q; /* Listing */ nfs = 0; for ( q = fmInfo.fsLink.next; q != &fmInfo.fsLink; q = q->next ) { if ( ++nfs > cnt ) { continue; } fs = (FsInfo*)q; tc_strncpy(buf->a_name, fs->conName, ConNameLen); tc_strncpy(buf->dev, fs->devName, DevNameLen); buf++; } } else { if ( cmdPara->cnt == F_GETDEV ) { /* Obtain the device name. (F_GETDEV) */ fs = fmSelectFileSystemOfConName(buf->a_name); if ( fs == NULL ) { err = E_NOFS; goto err_ret; } tc_strncpy(buf->dev, fs->devName, DevNameLen); } else { /* Obtain the connection name. (F_GETNAM) */ fs = fmSelectFileSystemOfDevName(buf->dev); if ( fs == NULL ) { err = E_NOFS; goto err_ret; } tc_strncpy(buf->a_name, fs->conName, ConNameLen); } nfs = 1; } pkt->cmd.ret = nfs; return;err_ret: DEBUG_PRINT(("fmcListFileSystem err = %d\n", err)); pkt->cmd.ret = err; return;}/* ------------------------------------------------------------------------ *//* * Connect the disk device. * When already connected, perform only the check of access right, * and lock the file system task. */LOCAL WER attachDevice( DevName dev, UW omode, PINFO *pinfo, DiskInfo *diskinfo, FsInfo **fs ){ ID diskid; ER err; /* Whether the device of the same name is connected. */ *fs = fmSelectFileSystemOfDevName(dev); if ( *fs == NULL ) { /* Not connected yet: Make new connection. */ err = AttachFS(dev, omode, pinfo, diskinfo); if ( err < E_OK ) { goto err_ret1; } diskid = (ID)err; /* Check the disk partition information. */ err = fmCheckPartitionID(dev); if ( err < E_OK ) { goto err_ret2; } } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -