📄 fileio.c
字号:
INODE *inode = lp->inode; ER err; /* Parameter check */ err = CheckSpaceRW((VP)para->buf, sizeof(LINK)); if ( err < E_OK ) { goto err_ret; } /* Check of file system */ if ( fs != (FS*)&STD_FS ) { err = E_ILFMT; goto err_ret; } /* Existence of file */ if ( inode->ino == NOEXS_INO ) { err = E_NOEXS; goto err_ret; } /* Acquisition of file "LINK" */ err = sf_getlink(inode, para->buf); if ( err < E_OK ) { goto err_ret; } /* Deletion of file reference node */ inode_Free(fs, inode); return E_OK;err_ret: inode_Free(fs, inode); DEBUG_PRINT(("_u_getlink err=%#x\n", err)); return err;}/* * Path analysis */LOCAL ER _u_lookup( FS *fs, CmdPkt *pkt ){ UXINFO *uxinfo = pkt->uxinfo; CDINF *curdir = &uxinfo->curdir; LOCAL_U_LOOKUP_PARA *para = pkt->cmd.para; ER err; /* Path name analysis */ if ( fs == (FS*)&STD_FS ) { err = sf_lookup(curdir, para); } else { err = (*fs->u_lookup)(fs, curdir, para); } if ( err < E_OK ) { goto err_ret; } return err;err_ret: DEBUG_PRINT(("_u_lookup err = %#x\n", err)); return err;}/* --------------------------------------------------------------------------- *//* * Diverged by each file IO routine */LOCAL ER CallFileFunction( FS *fs, CmdPkt *pkt ){ ER ret, err; switch ( pkt->cmd.fno.w ) { case LOCAL_U_LOOKUP_FN: ret = _u_lookup(fs, pkt); break; case SF_ATTACH_FN: ret = _u_attach(fs, pkt); break; case SF_DETACH_FN: ret = _u_detach(fs, pkt); break; case SF_OPEN_FN: ret = _u_open(fs, pkt); break; case SF_CLOSE_FN: ret = _u_close(fs, pkt); break; case SF_LSEEK_FN: ret = _u_lseek(fs, pkt); break; case SF_READ_FN: ret = _u_read(fs, pkt); break; case SF_WRITE_FN: ret = _u_write(fs, pkt); break; case SF_GETDENTS_FN: ret = _u_getdents(fs, pkt); break; case SF_DUP_FN: ret = _u_dup(fs, pkt); break; case SF_DUP2_FN: ret = _u_dup2(fs, pkt); break; case SF_FSYNC_FN: ret = _u_fsync(fs, pkt); break; case SF_RENAME_FN: ret = _u_rename(fs, pkt); break; case SF_UNLINK_FN: ret = _u_unlink(fs, pkt); break; case SF_CHDIR_FN: ret = _u_chdir(fs, pkt); break; case SF_FCHDIR_FN: ret = _u_fchdir(fs, pkt); break; case SF_CHMOD_FN: ret = _u_chmod(fs, pkt); break; case SF_FCHMOD_FN: ret = _u_fchmod(fs, pkt); break; case SF_MKDIR_FN: ret = _u_mkdir(fs, pkt); break; case SF_RMDIR_FN: ret = _u_rmdir(fs, pkt); break; case SF_CREAT_FN: ret = _u_creat(fs, pkt); break; case SF_UTIMES_FN: ret = _u_utimes(fs, pkt); break; case SF_UMASK_FN: ret = _u_umask(fs, pkt); break; case SF_TRUNCATE_FN: ret = _u_truncate(fs, pkt); break; case SF_FTRUNCATE_FN: ret = _u_ftruncate(fs, pkt); break; case SF_SYNC_FN: ret = _u_sync(fs, pkt); break; case SF_STAT_FN: ret = _u_stat(fs, pkt); break; case SF_LSTAT_FN: ret = _u_lstat(fs, pkt); break; case SF_FSTAT_FN: ret = _u_fstat(fs, pkt); break; case SF_GETFSSTAT_FN: ret = _u_getfsstat(fs, pkt); break; case SF_GETLINK_FN: ret = _u_getlink(fs, pkt); break; default: err = E_RSFN; goto err_ret; } pkt->cmd.ret = ret; return E_OK;err_ret: DEBUG_PRINT(("CallFileFunction err=%#x\n", err)); return err;}/* * File system task */LOCAL void FileSystemTask( FS *fs ){ UB finflg = 0; CmdPkt *pkt; RNO rdvno; TMO tmo = TMO_FEVR; ER err; /* End of task if disk is cut off */ while ( !finflg ) { /* Command packet reception */ err = tk_acp_por(fs->porid, ~0U, &rdvno, &pkt, tmo); if ( err < E_OK ) { if ( err == E_TMOUT ) { (void)SyncFS(fs->diskid, NULL); tmo = TMO_FEVR; continue; } DEBUG_PRINT(("FileSystemTask acp_por er=%d\n", err)); continue; } tmo = SyncTimeOut; /* Task address space shall be adapted to the processing request task */ err = SetTaskSpace(pkt->cmd.tid); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret; } /* File IO processing */ err = CallFileFunction(fs, pkt); if ( err < E_OK ) {err_ret: pkt->cmd.ret = err; } /* Check of disk cutoff */ if ( fs->diskid < 0 ) { finflg = 1; } /* Reply */ err = tk_rpl_rdv(rdvno, &pkt, sizeof(pkt)); if ( err < E_OK ) { DEBUG_PRINT(("FileSystemTask rpl_rdv er=%d\n", err)); } } tk_exd_tsk();}/* * Call rendezvous */LOCAL ER CallFileSystemTask( FS *fs, CmdPkt *pkt ){ ER err; err = tk_cal_por(fs->porid, 1, &pkt, sizeof(pkt), TMO_FEVR); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("CallFileSystemTask err=%#x\n", err)); return err;}/* * Call file system task (path name analysis) * The file system and directory are followed by path name, * and file reference node is acquired or created. */EXPORT ER CallFileIO_lookup( const char *path, CmdPkt *pkt ){ LOCAL_U_LOOKUP_PARA *para = pkt->cmd.para; FS *fs = para->fs; /* for rename */ ER err; /* Parameter check */ err = CheckBStrSpaceR((UB*)path, 0); if ( err < E_OK ) { goto err_ret; } /* Initialization of path name analysis parameter*/ para->fs = NULL; para->inode = NULL; para->flag = 0; para->path = (char*)path; for ( ;; ) { Lock_UX(); /* Selection of file system */ para->fs = searchFileSystem_path(¶->path, pkt->uxinfo); if ( fs != para->fs ) { Lock_FS(para->fs); } Unlock_UX(); if ( para->fs == (FS*)&STD_FS ) { err = CallFileFunction(para->fs, pkt); if ( err < E_OK ) { goto err_ret; } err = pkt->cmd.ret; if ( err < E_OK ) { goto err_ret; } } else if ( para->fs == (FS*)&ROOT_FS ) { /* Stop at root directory */ para->flag = LOOKUP_DONE; } else { err = CallFileSystemTask(para->fs, pkt); if ( err < E_OK ) { goto err_ret; } err = pkt->cmd.ret; if ( err < E_OK ) { goto err_ret; } } /* Stop when file information is acquired */ if ( (para->flag & LOOKUP_DONE) != 0 ) { break; } if ( fs != para->fs ) { Unlock_FS(para->fs); } } if (( fs != NULL )&&( fs != para->fs )) { Unlock_FS(para->fs); } return E_OK;/* Release the all locked file systems */err_ret: if ( fs != para->fs ) { Unlock_FS(para->fs); } Unlock_FS(fs); DEBUG_PRINT(("CallFileIO_lookup err=%#x\n", err)); return err;}/* * File system task call * System call individual special handling */EXPORT ER CallFileIO( int fildes, CmdPkt *pkt ){ ER err; switch ( pkt->cmd.fno.w ) { case SF_CHDIR_FN: { /* Current directory modification */ LOCAL_U_LOOKUP_PARA *lpara = pkt->exinf; FS *fs = NULL; UXINFO *uxinfo = pkt->uxinfo; /* Existing/New file system lock */ if ( uxinfo->curdir.fs != lpara->fs ) { Lock_FS(fs = uxinfo->curdir.fs); } /* No call file system task */ err = CallFileFunction(lpara->fs, pkt); if ( fs != lpara->fs ) { Unlock_FS(fs); } Unlock_FS(lpara->fs); break; } case SF_FCHDIR_FN: { /* Current directory modification */ FD *fd; FS *fs = NULL; UXINFO *uxinfo = pkt->uxinfo; Lock_UX(); /* Search of file descriptor */ fd = searchFileDescriptor(uxinfo, fildes); if ( fd == NULL ) { Unlock_UX(); err = E_FD; } else { /* Existing / New file system lock */ Lock_FS(fd->fs); if ( uxinfo->curdir.fs != fd->fs ) { Lock_FS(fs = uxinfo->curdir.fs); } Unlock_UX(); /* No call file system task */ err = CallFileFunction(fd->fs, pkt); if ( fs != fd->fs ) { Unlock_FS(fs); } Unlock_FS(fd->fs); } break; } case SF_UMASK_FN: { /* File creation mask modification */ /* No designation of file system */ err = CallFileFunction(NULL, pkt); break; } case SF_GETFSSTAT_FN: { /* Acquisition of file system list */ SF_GETFSSTAT_PARA *para = pkt->cmd.para; QUEUE *q; /* Parameter check */ if ( para->buf != NULL ) { if ( (W)para->bufsize < 0 ) { err = E_PAR; break; } err = CheckSpaceRW((VP)para->buf, para->bufsize); if ( err < E_OK ) { break; } } /* Standard file system */ err = CallFileFunction((FS*)&STD_FS, pkt); if ( err < E_OK ) { break; } Lock_UX(); for ( q = FSQue.next; q != &FSQue; q = q->next ) { /* Other file systems */ Lock_FS((FS*)q); err = CallFileSystemTask((FS*)q, pkt); Unlock_FS((FS*)q); if ( err < E_OK ) { break; } } Unlock_UX(); break; } case SF_SYNC_FN: { /* Synchronization of the disk content */ QUEUE *q; ER error = E_OK; /* Standard file system */ err = CallFileFunction((FS*)&STD_FS, pkt); if ( err < E_OK ) { error = err; } Lock_UX(); for ( q = FSQue.next; q != &FSQue; q = q->next ) { /* Other file systems */ Lock_FS((FS*)q); err = CallFileSystemTask((FS*)q, pkt); if ( err < E_OK ) { error = err; } Unlock_FS((FS*)q); } Unlock_UX(); err = error; break; } default: { err = E_RSFN; break; } } if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("CallFileIO err=%#x\n", err)); return err;}/* * Call file system task * Select the file system by the result of path name analysis. */EXPORT ER CallFileIO_path( CmdPkt *pkt ){ LOCAL_U_LOOKUP_PARA *lpara = pkt->exinf; ER err; if (( lpara->fs == (FS*)&STD_FS )|| ( lpara->fs == (FS*)&ROOT_FS )|| ( lpara->fs == (FS*)&STDIO_FS )) { err = CallFileFunction(lpara->fs, pkt); } else { err = CallFileSystemTask(lpara->fs, pkt); } /* unlock by path name analysis */ Unlock_FS(lpara->fs); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("CallFileIO_path err=%#x\n", err)); return err;}/* * Call file system task * Select file system by file descriptor */EXPORT ER CallFileIO_fd( int fildes, CmdPkt *pkt ){ FD *fd; FS *fs; ER err; Lock_UX(); /* Search of file descriptor */ fd = searchFileDescriptor(pkt->uxinfo, fildes); if ( fd == NULL ) { err = E_FD; goto err_ret2; } fs = fd->fs; Lock_FS(fs); Unlock_UX(); if (( fs == (FS*)&STD_FS )||( fs == (FS*)&ROOT_FS )||( fs == (FS*)&STDIO_FS )) { err = CallFileFunction(fs, pkt); } else { err = CallFileSystemTask(fs, pkt); } Unlock_FS(fs); if ( err < E_OK ) { goto err_ret1; } return E_OK;err_ret2: Unlock_UX();err_ret1: DEBUG_PRINT(("CallFileIO_fd err=%#x\n", err)); return err;}/* * File system connection */EXPORT ER CallFileIO_attach( CmdPkt *pkt ){ SF_ATTACH_PARA *para = pkt->cmd.para; T_CPOR cpor; T_CTSK ctsk; FS *fs; ER err; /* Parameter check */ err = CheckStrSpaceR((TC*)para->devnm, 0); if ( err < E_OK ) { goto err_ret1; } if ( err > L_DEVNM ) { err = E_PAR; goto err_ret1; } err = CheckBStrSpaceR((UB*)para->connm, 0); if ( err < E_OK ) { goto err_ret1; } if ( err > L_FCONNM ) { err = E_PAR; goto err_ret1; } Lock_UX(); if ( ((UW)para->mode & TSD_PAR_MSK_0XFF00) == SF_STDFS ) { /* Standard file system connection */ err = CallFileFunction((FS*)&STD_FS, pkt); if ( err < E_OK ) { goto err_ret2; } Unlock_UX(); return E_OK; } /* Creation of file system information */ fs = new_FileSystem(para->devnm, para->connm, para->mode, &err); if ( fs == NULL ) { goto err_ret2; } /* Acquisition of device number */ err = get_DeviceNumber(fs->devnm); if ( err < E_OK ) { goto err_ret7; } fs->devnum = err; /* Creation of lock */ err = CreateLock(&fs->lock, (UB*)"uxfs"); if ( err < E_OK ) { goto err_ret3; } /* Creation of rendezvous port */ SetOBJNAME(cpor.exinf, "uxfs"); cpor.poratr = TA_TPRI; cpor.maxcmsz = sizeof(CmdPkt*); cpor.maxrmsz = sizeof(CmdPkt*); fs->porid = err = tk_cre_por(&cpor); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret4; } /* Creation of file system task */ ctsk.exinf = fs; ctsk.tskatr = TA_HLNG|TA_RNG0; ctsk.task = FileSystemTask; ctsk.itskpri = FsTskPri; ctsk.stksz = TSD_CFA_STK_2048; fs->tskid = err = tk_cre_tsk(&ctsk); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret5; } err = tk_sta_tsk(fs->tskid, (INT)fs); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret6; } /* Call file system task */ err = CallFileSystemTask(fs, pkt); if ( err < E_OK ) { goto err_ret7; } if ( pkt->cmd.ret < E_OK ) { err = pkt->cmd.ret; goto err_ret7; } Unlock_UX(); return E_OK;err_ret7: (void)tk_ter_tsk(fs->tskid) ;err_ret6: (void)tk_del_tsk(fs->tskid) ;err_ret5: (void)tk_del_por(fs->porid) ;err_ret4: DeleteLock(&fs->lock);err_ret3: (void)del_FileSystem(fs);err_ret2: Unlock_UX();err_ret1: DEBUG_PRINT(("CallFileIO_attach err=%#x\n", err)); return err;}/* * File system detachment */EXPORT ER CallFileIO_detach( CmdPkt *pkt ){ SF_DETACH_PARA *para = pkt->cmd.para; FS *fs; ER err, error = E_OK; /* Parameter check */ err = CheckStrSpaceR((TC*)para->devnm, 0); if ( err < E_OK ) { error = err; goto err_ret1; } Lock_UX(); /* Search file system from device name */ fs = searchFileSystem_devnm(para->devnm); if ( fs == (FS*)&STD_FS ) { err = CallFileFunction(fs, pkt); if ( err < E_OK ) { error = E_PAR; goto err_ret2; } Unlock_UX(); return E_OK; } /* Call file system task */ Lock_FS(fs); err = CallFileSystemTask(fs, pkt); Unlock_FS(fs); if ( err < E_OK ) { error = err; goto err_ret2; } /* Execute the other deletion processings when disk detachment is completed*/ if ( fs->diskid < 0 ) { /* Deletion of lock */ DeleteLock(&fs->lock); /* Deletion of rendezvous port */ err = tk_del_por(fs->porid); if ( err < E_OK ) { error = E_SYS; } /* Deletion of file system information */ err = del_FileSystem(fs); if ( err < E_OK ) { error = err; } }err_ret2: Unlock_UX();err_ret1:#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("CallFileIO_detach err=%#x\n", error)); }#endif return error;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -