void DfsModuleInit() { // You essentially set the file system as invalid and then open // using DfsOpenFileSystem(). int i,j; DfsInvalidate(); lock_fbv = LockCreate(); lock_inode = LockCreate(); if (DfsOpenFileSystem()== DFS_FAIL){ printf("Failed to open the file syatem\n"); } }
int DfsCloseFileSystem() { int i; int num; dfs_block dfs_b; disk_block disk_b; // printf("In DfsCloseFileSystem\n"); if(sb.valid == 0){ printf("The file system is NOT open!\n"); return DFS_FAIL; } bzero((char *)(&dfs_b),sizeof(dfs_block)); for(i=sb.filesys_inodestart;i<sb.filesys_fbvstart;i++){ bcopy((char *)(&inodes[(i-sb.filesys_inodestart)*(sb.filesys_blocksize)/sizeof(dfs_inode)]),(char *)(&dfs_b),sb.filesys_blocksize); if((num = DfsWriteBlock (i, &dfs_b))== DFS_FAIL){ printf("Cannot write inodes to disk!\n"); return DFS_FAIL; } } bzero((char *)(&dfs_b),sizeof(dfs_block)); for(i=sb.filesys_fbvstart;i<sb.filesys_datastart;i++){ bcopy((char *)(&fbv[(i-sb.filesys_fbvstart)*(sb.filesys_blocksize)/sizeof(uint32)]),(char *)(&dfs_b),sb.filesys_blocksize); if((num = DfsWriteBlock (i, &dfs_b)) == DFS_FAIL){ printf("Cannot write free block vector to disk!\n"); return DFS_FAIL; } } bzero((char *)(&disk_b),sizeof(disk_block)); bcopy((char *)(&sb),(char *)(&disk_b),sizeof(dfs_superblock)); if (DiskWriteBlock (1, &disk_b) == DISK_FAIL){ printf("Cannot write superblock into Disk!\n"); return DFS_FAIL; } DfsInvalidate(); return DFS_SUCCESS; }
int DfsOpenFileSystem() { int i; int num; dfs_block dfs_b; disk_block disk_b; //Basic steps: // Check that filesystem is not already open // Read superblock from disk. Note this is using the disk read rather // than the DFS read function because the DFS read requires a valid // filesystem in memory already, and the filesystem cannot be valid // until we read the superblock. Also, we don't know the block size // until we read the superblock, either. // printf("In DfsOpenFileSystem\n"); // Copy the data from the block we just read into the superblock in memory // All other blocks are sized by virtual block size: // Read inodes // Read free block vector // Change superblock to be invalid, write back to disk, then change // it back to be valid in memory if (sb.valid == 1){ printf("The filesystem is already open!\n"); return DFS_FAIL; } if ((num = DiskReadBlock(1,&disk_b)) == DISK_FAIL){ printf("Cannot read superblock from disk!\n"); return DFS_FAIL; } bcopy((char *)(&disk_b),(char *)(&sb),sizeof(dfs_superblock)); //print superblock info from disk /* printf("superblock.valid %d\n",sb.valid); printf("superblock.filesys_blocksize %d\n",sb.filesys_blocksize); printf("superblock.filesys_blocknum %d\n",sb.filesys_blocknum); printf("superblock.filesys_inodestart %d\n",sb.filesys_inodestart); printf("superblock.inodenum %d\n",sb.inodenum); printf("superblock.filesys_fbvstart %d\n",sb.filesys_fbvstart); printf("superblock.filesys_datastart %d\n",sb.filesys_datastart); */ for(i=sb.filesys_inodestart;i<sb.filesys_fbvstart;i++){ if (( num = DfsReadBlock (i,&dfs_b)) == DFS_FAIL){ printf("Cannot read inode from disk!\n"); return DFS_FAIL; } bcopy((char *)(&dfs_b),(char *)(&inodes[(i-sb.filesys_inodestart)*(sb.filesys_blocksize)/sizeof(dfs_inode)]),sb.filesys_blocksize); } SetupRootDir(); //print inode info from disk // for(i=0;i<192;i++){ // printf("inodes[%d].inuse=%d,inodes[%d].filesize=%d\n",i,inodes[i].inuse,i,inodes[i].filesize); // } // for(i=sb.filesys_fbvstart;i<sb.filesys_datastart;i++){ if (( num = DfsReadBlock(i, &dfs_b)) == DFS_FAIL){ printf("Cannot read free block vector from disk!\n"); return DFS_FAIL; } bcopy((char *)(&dfs_b),(char *)(&fbv[(i-sb.filesys_fbvstart)*(sb.filesys_blocksize)/sizeof(uint32)]),sb.filesys_blocksize); } //print fbv info from disk // for(i=0;i<DFS_FBV_MAX_NUM;i++){ // printf("fbv[%d]=0x%x\n",i,fbv[i]); // } // DfsInvalidate(); bzero((char *)(&disk_b),sizeof(disk_block)); bcopy((char *)(&sb),(char *)(&disk_b),sizeof(dfs_superblock)); if (DiskWriteBlock(1,&disk_b) == DISK_FAIL){ printf("Cannot write superblock back to disk!\n"); return DFS_FAIL; } sb.valid = 1; // printf("Exit DfsOpenFileSystem\n"); return DFS_SUCCESS; }
//---------------------------------------------------------------------- // // doInterrupt // // Handle an interrupt or trap. // //---------------------------------------------------------------------- void dointerrupt (unsigned int cause, unsigned int iar, unsigned int isr, uint32 *trapArgs) { int result; int i; uint32 args[4]; int intrs; uint32 handle; int ihandle; dbprintf ('t',"Interrupt cause=0x%x iar=0x%x isr=0x%x args=0x%08x.\n", cause, iar, isr, (int)trapArgs); // If the TRAP_INSTR bit is set, this was from a trap instruction. // If the bit isn't set, this was a system interrupt. if (cause & TRAP_TRAP_INSTR) { cause &= ~TRAP_TRAP_INSTR; switch (cause) { case TRAP_CONTEXT_SWITCH: dbprintf ('t', "Got a context switch trap!\n"); ProcessSchedule (); ClkResetProcess(); break; case TRAP_EXIT: case TRAP_USER_EXIT: dbprintf ('t', "Got an exit trap!\n"); ProcessDestroy (currentPCB); ProcessSchedule (); ClkResetProcess(); break; case TRAP_PROCESS_FORK: dbprintf ('t', "Got a fork trap!\n"); break; case TRAP_PROCESS_SLEEP: dbprintf ('t', "Got a process sleep trap!\n"); ProcessSuspend (currentPCB); ProcessSchedule (); ClkResetProcess(); break; case TRAP_PRINTF: // Call the trap printf handler and pass the arguments and a flag // indicating whether the trap was called from system mode. dbprintf ('t', "Got a printf trap!\n"); TrapPrintfHandler (trapArgs, isr & DLX_STATUS_SYSMODE); break; case TRAP_OPEN: // Get the arguments to the trap handler. If this is a user mode trap, // copy them from user space. if (isr & DLX_STATUS_SYSMODE) { args[0] = trapArgs[0]; args[1] = trapArgs[1]; } else { char filename[32]; // trapArgs points to the trap arguments in user space. There are // two of them, so copy them to to system space. The first argument // is a string, so it has to be copied to system space and the // argument replaced with a pointer to the string in system space. MemoryCopyUserToSystem (currentPCB, trapArgs, args, sizeof(args[0])*2); MemoryCopyUserToSystem (currentPCB, args[0], filename, 31); // Null-terminate the string in case it's longer than 31 characters. filename[31] = '\0'; // Set the argument to be the filename args[0] = (uint32)filename; } // Allow Open() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, args[1] + 0x10000); printf ("Got an open with parameters ('%s',0x%x)\n", (char *)(args[0]), args[1]); RestoreIntrs (intrs); break; case TRAP_CLOSE: // Allow Close() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_READ: // Allow Read() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_WRITE: // Allow Write() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_DELETE: intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_SEEK: intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_PROCESS_GETPID: ProcessSetResult(currentPCB, GetCurrentPid()); break; case TRAP_PROCESS_CREATE: TrapProcessCreateHandler(trapArgs, isr & DLX_STATUS_SYSMODE); break; case TRAP_SEM_CREATE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = SemCreate(ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_SEM_WAIT: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = SemHandleWait(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_SEM_SIGNAL: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = SemHandleSignal(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_LOCK_CREATE: ihandle = LockCreate(); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_LOCK_ACQUIRE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = LockHandleAcquire(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_LOCK_RELEASE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = LockHandleRelease(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_COND_CREATE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondCreate(ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_COND_WAIT: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleWait(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; case TRAP_COND_SIGNAL: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleSignal(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; case TRAP_COND_BROADCAST: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleBroadcast(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; // Traps for Disk Access case TRAP_DISK_WRITE_BLOCK: ihandle = TrapDiskWriteBlockHandler(trapArgs, isr & DLX_STATUS_SYSMODE); ProcessSetResult(currentPCB, ihandle); break; case TRAP_DISK_SIZE: ProcessSetResult(currentPCB, DiskSize()); break; case TRAP_DISK_BLOCKSIZE: ProcessSetResult(currentPCB, DiskBytesPerBlock()); break; case TRAP_DISK_CREATE: ProcessSetResult(currentPCB, DiskCreate()); break; // Traps for DFS filesystem case TRAP_DFS_INVALIDATE: DfsInvalidate(); break; // Traps for file functions case TRAP_FILE_OPEN: ProcessSetResult(currentPCB, TrapFileOpenHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_CLOSE: ProcessSetResult(currentPCB, TrapFileCloseHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_DELETE: ProcessSetResult(currentPCB, TrapFileDeleteHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_READ: ProcessSetResult(currentPCB, TrapFileReadHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_WRITE: ProcessSetResult(currentPCB, TrapFileWriteHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_SEEK: ProcessSetResult(currentPCB, TrapFileSeekHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; // Traps for running OS testing code case TRAP_TESTOS: RunOSTests(); break; default: printf ("Got an unrecognized trap (0x%x) - exiting!\n", cause); GracefulExit (); break; } } else { switch (cause) { case TRAP_TIMER: dbprintf ('t', "Got a timer interrupt!\n"); // ClkInterrupt returns 1 when 1 "process quantum" has passed, meaning // that it's time to call ProcessSchedule again. if (ClkInterrupt()) { ProcessSchedule (); } break; case TRAP_KBD: do { i = *((uint32 *)DLX_KBD_NCHARSIN); result = *((uint32 *)DLX_KBD_GETCHAR); printf ("Got a keyboard interrupt (char=0x%x(%c), nleft=%d)!\n", result, result, i); } while (i > 1); break; case TRAP_ACCESS: printf ("Exiting after illegal access at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; case TRAP_ADDRESS: printf ("Exiting after illegal address at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; case TRAP_ILLEGALINST: printf ("Exiting after illegal instruction at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; case TRAP_PAGEFAULT: printf ("Exiting after page fault at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; default: printf ("Got an unrecognized system interrupt (0x%x) - exiting!\n", cause); GracefulExit (); break; } } dbprintf ('t',"About to return from dointerrupt.\n"); // Note that this return may schedule a new process! intrreturn (); }