int DfsInodeAllocateVirtualBlock(int handle, int virtual_blocknum) { dfs_block indirect_table; int blocknum; uint32 *table; // printf("In DfsInodeAllocateVirtualBlock\n"); if (sb.valid == 0){ printf("File system not opened\n"); return DFS_FAIL; } if((handle<0)||(handle>DFS_INODE_MAX_NUM)){ printf("Invalid inode handle = %d\n",handle); return DFS_FAIL; } if(inodes[handle].inuse == 0){ printf("Inode not allocated!\n"); return DFS_FAIL; } if((virtual_blocknum<0)||(virtual_blocknum>(sb.filesys_blocksize/sizeof(uint32)+10))){ printf("Invalid virtural_blocknum = %d\n",virtual_blocknum); return DFS_FAIL; } //check direct or indirect if(virtual_blocknum < 10){ if((blocknum = DfsAllocateBlock()) == DFS_FAIL){ printf("Cannot allocate block for direct table\n"); return DFS_FAIL; } inodes[handle].direct[virtual_blocknum] =(uint32)blocknum; return blocknum; } else{ table =(uint32 *)(&indirect_table); if((inodes[handle].indirect)!=0){ DfsReadBlock(inodes[handle].indirect,(dfs_block *)table); if((blocknum = DfsAllocateBlock()) == DFS_FAIL){ printf("Cannot allocate block for direct table\n"); return DFS_FAIL; } table[virtual_blocknum-10] =(uint32)blocknum; DfsWriteBlock(inodes[handle].indirect,(dfs_block *)table); return blocknum; } else{ if((blocknum = DfsAllocateBlock()) == DFS_FAIL){ printf("Cannot allocate block for indirect table\n"); return DFS_FAIL; } inodes[handle].indirect = (uint32)blocknum; bzero((char *)table,sb.filesys_blocksize); if((blocknum = DfsAllocateBlock()) == DFS_FAIL){ printf("Cannot allocate block for indirect address\n"); return DFS_FAIL; } table[virtual_blocknum-10] = (uint32)blocknum; DfsWriteBlock(inodes[handle].indirect,(dfs_block *)table); return blocknum; } } }
//---------------------------------------------------------------------- // // main // // This routine is called when the OS starts up. It allocates a // PCB for the first process - the one corresponding to the initial // thread of execution. Note that the stack pointer is already // set correctly by _osinit (assembly language code) to point // to the stack for the 0th process. This stack isn't very big, // though, so it should be replaced by the system stack of the // currently running process. // //---------------------------------------------------------------------- void main (int argc, char *argv[]) { int i,j; int n; char buf[120]; char *userprog = (char *)0; int base=0; int numargs=0; int allargs_offset = 0; char allargs[SIZE_ARG_BUFF]; debugstr[0] = '\0'; printf ("Got %d arguments.\n", argc); printf ("Available memory: 0x%x -> 0x%x.\n", (int)lastosaddress, MemoryGetSize ()); printf ("Argument count is %d.\n", argc); for (i = 0; i < argc; i++) { printf ("Argument %d is %s.\n", i, argv[i]); } FsModuleInit (); for (i = 0; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'D': dstrcpy (debugstr, argv[++i]); break; case 'i': n = dstrtol (argv[++i], (void *)0, 0); ditoa (n, buf); printf ("Converted %s to %d=%s\n", argv[i], n, buf); break; case 'f': { int start, codeS, codeL, dataS, dataL, fd, j; int addr = 0; static unsigned char buf[200]; fd = ProcessGetCodeInfo (argv[++i], &start, &codeS, &codeL, &dataS, &dataL); printf ("File %s -> start=0x%08x\n", argv[i], start); printf ("File %s -> code @ 0x%08x (size=0x%08x)\n", argv[i], codeS, codeL); printf ("File %s -> data @ 0x%08x (size=0x%08x)\n", argv[i], dataS, dataL); while ((n = ProcessGetFromFile (fd, buf, &addr, sizeof (buf))) > 0) { for (j = 0; j < n; j += 4) { printf ("%08x: %02x%02x%02x%02x\n", addr + j - n, buf[j], buf[j+1], buf[j+2], buf[j+3]); } } close (fd); break; } case 'u': userprog = argv[++i]; base = i; // Save the location of the user program's name break; default: printf ("Option %s not recognized.\n", argv[i]); break; } if(userprog) break; } } dbprintf ('i', "About to initialize queues.\n"); AQueueModuleInit (); dbprintf ('i', "After initializing queues.\n"); MemoryModuleInit (); dbprintf ('i', "After initializing memory.\n"); ProcessModuleInit (); dbprintf ('i', "After initializing processes.\n"); SynchModuleInit (); dbprintf ('i', "After initializing synchronization tools.\n"); KbdModuleInit (); dbprintf ('i', "After initializing keyboard.\n"); ClkModuleInit(); for (i = 0; i < 100; i++) { buf[i] = 'a'; } i = FsOpen ("vm", FS_MODE_WRITE); dbprintf ('i', "VM Descriptor is %d\n", i); FsSeek (i, 0, FS_SEEK_SET); FsWrite (i, buf, 80); FsClose (i); // JSM -- commented out for initial build, MUST ADD BACK IN!! DfsModuleInit(); dbprintf ('i', "After initializing dfs filesystem.\n"); //////////////////////////////////////// // JSM -- add debug stuff, and close file system before fdisk app has run // FOR TESTING PURPOSES!! i = DfsAllocateBlock(); j = DfsAllocateBlock(); DfsFreeBlock(i); DfsFreeBlock(j); dbprintf('F', "ProcessFork: closing filesystem and exiting simulator\n"); DfsCloseFileSystem(); exitsim(); //////////////////////////////////////// // Setup command line arguments if (userprog != (char *)0) { numargs=0; allargs_offset = 0; // Move through each of the argv addresses for(i=0; i<argc-base; i++) { // At each argv address, copy the string into allargs, including the '\0' for(j=0; allargs_offset < SIZE_ARG_BUFF; j++) { allargs[allargs_offset++] = argv[i+base][j]; if (argv[i+base][j] == '\0') break; // end of this string } numargs++; } allargs[SIZE_ARG_BUFF-1] = '\0'; // set last char to NULL for safety ProcessFork(0, (uint32)allargs, userprog, 1); } else { dbprintf('i', "No user program passed!\n"); } // Start the clock which will in turn trigger periodic ProcessSchedule's ClkStart(); intrreturn (); // Should never be called because the scheduler exits when there // are no runnable processes left. GracefulExit(); // NEVER RETURNS! }
uint32 DfsInodeAllocateVirtualBlock(uint32 handle, uint32 virtual_blocknum) { dfs_block dfsb; int blocknum; int* block_entry_table; if(!sb.valid) { printf("DfsInodeAllocateVirtualBlock: invalid file system\n"); return DFS_FAIL; } if(!inodes[handle].valid) { printf("DfsInodeAllocateVirtualBlock: invalid inode\n"); return DFS_FAIL; } if(virtual_blocknum >= 10) { block_entry_table = (int*) dfsb.data; if(!DFS_IS_BLOCK_ENTRY_VALID(inodes[handle].indir_block_entry)) { blocknum = DfsAllocateBlock(); if(blocknum == DFS_FAIL) { printf("DfsInodeAllocateVirtualBlock: DfsAllocateBlock failed\n"); return DFS_FAIL; } bzero(dfsb.data, sb.blocksize); DfsWriteBlock(blocknum, &dfsb); inodes[handle].indir_block_entry = DFS_SET_BLOCK_ENTRY(blocknum, 1); } DfsReadBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb); virtual_blocknum -= 10; // Before allocating new block // Extra check to make sure that there is no already valid entry here if(DFS_IS_BLOCK_ENTRY_VALID(block_entry_table[virtual_blocknum])) { return DFS_GET_BLOCK_NUM(block_entry_table[virtual_blocknum]); } else { blocknum = DfsAllocateBlock(); if(blocknum == DFS_FAIL) { printf("DfsInodeAllocateVirtualBlock: DfsAllocateBlock failed\n"); return DFS_FAIL; } block_entry_table[virtual_blocknum] = DFS_SET_BLOCK_ENTRY(blocknum, 1); DfsWriteBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb); } return blocknum; } else { block_entry_table = inodes[handle].direct_block_entries; // Before allocating new block // Extra check to make sure that there is no already valid entry here if(DFS_IS_BLOCK_ENTRY_VALID(block_entry_table[virtual_blocknum])) { return DFS_GET_BLOCK_NUM(block_entry_table[virtual_blocknum]); } else { blocknum = DfsAllocateBlock(); if(blocknum == DFS_FAIL) { printf("DfsInodeAllocateVirtualBlock: DfsAllocateBlock failed\n"); return DFS_FAIL; } block_entry_table[virtual_blocknum] = DFS_SET_BLOCK_ENTRY(blocknum, 1); return blocknum; } } printf("---THIS SHOULD NOT HAPPEN---\n"); return DFS_FAIL; }