int DfsWriteBlock(int blocknum, dfs_block *b){ int i; int ratio; disk_block disk_b; int disk_blocknum; // printf("In DfsWriteBlock\n"); if (sb.valid == 0){ printf("File system not open!\n"); return DFS_FAIL; } if((blocknum<0)||(blocknum>sb.filesys_blocknum)){ printf("Invalid blocknum = %d\n",blocknum); return DFS_FAIL; } if(Dfscheck(blocknum)== DFS_FAIL){ printf("Error,DFS block %d not allocated!\n",blocknum); return DFS_FAIL; } ratio = sb.filesys_blocksize/(DISK_BLOCKSIZE); disk_blocknum=(blocknum*ratio); for(i=0;i<ratio;i++){ bcopy((char *)((int)b+i*(DISK_BLOCKSIZE)),(char *)(&disk_b),DISK_BLOCKSIZE); if (DiskWriteBlock((uint32)(disk_blocknum + i),&disk_b) == DISK_FAIL){ printf("Cannot write to block %d on disk!\n",disk_blocknum); return DISK_FAIL; } } return (sb.filesys_blocksize); }
//------------------------------------------------------------------- // DfsCloseFileSystem writes the current memory version of the // filesystem metadata to the disk, and invalidates the memory's // version. //------------------------------------------------------------------- int DfsCloseFileSystem() { dfs_block dfsb; disk_block diskb; int i; char* inbytes; if(!sb.valid) { printf("DfsCloseFileSystem: Filesystem not already open\n"); return DFS_FAIL; } // Write inodes inbytes = (char*) inodes; for(i = sb.inode_start_block; i < sb.fbv_start_block; i++) { bcopy(&(inbytes[(i - sb.inode_start_block) * sb.blocksize]), dfsb.data, sb.blocksize); DfsWriteBlock(i, &dfsb); } // Write free block vector inbytes = (char*) fbv; for(i = sb.fbv_start_block; i < sb.data_start_block; i++) { bcopy(&(inbytes[(i - sb.fbv_start_block) * sb.blocksize]), dfsb.data, sb.blocksize); DfsWriteBlock(i, &dfsb); } bzero(diskb.data, DISK_BLOCKSIZE); bcopy((char*)(&sb), diskb.data, sizeof(sb)); if(DiskWriteBlock(1, &diskb) == DISK_FAIL) { printf("DfsCloseFileSystem: DiskWriteBlock failed\n"); return DFS_FAIL; } sb.valid = 0; return DFS_SUCCESS; }
int DfsOpenFileSystem() { disk_block diskb; dfs_block dfsb; char* inbytes; unsigned int i; //Basic steps: // Check that filesystem is not already open if(sb.valid) { printf("DfsOpenFilesystem: File system is already open\n"); return DFS_FAIL; } // 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. DiskReadBlock(1, &diskb); // Copy the data from the block we just read into the superblock in memory bcopy(diskb.data, (char*) &sb, sizeof(sb)); // sb should be valid at this point since sb was supposed to be valid on disk if(!sb.valid) { printf("DfsOpenFileSystem: Filesystem on disk is not valid\n"); return DFS_FAIL; } // All other blocks are sized by virtual block size: // Read inodes inbytes = (char*) inodes; for(i = sb.inode_start_block; i < sb.fbv_start_block; i++) { DfsReadBlock(i, &dfsb); bcopy(dfsb.data, &(inbytes[(i - sb.inode_start_block) * sb.blocksize]), sb.blocksize); } // Read free block vector inbytes = (char*) fbv; for(i = sb.fbv_start_block; i < sb.data_start_block; i++) { DfsReadBlock(i, &dfsb); bcopy(dfsb.data, &(inbytes[(i - sb.fbv_start_block) * sb.blocksize]), sb.blocksize); } // Change superblock to be invalid, write back to disk, then change // it back to be valid in memory sb.valid = 0; bzero(diskb.data, DISK_BLOCKSIZE); bcopy((char*)&sb, diskb.data, sizeof(sb)); DiskWriteBlock(1, &diskb); sb.valid = 1; return DFS_SUCCESS; }
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; }
//--------------------------------------------------------------------- // Disk write block handler // // handle trap that calls DiskWriteBlock() // disk_write_block(uint32 blocknum, disk_block *b) //---------------------------------------------------------------------- static int TrapDiskWriteBlockHandler(uint32 *trapArgs, int sysMode) { uint32 blocknum; // Holds block number disk_block *user_block = NULL; // Holds user-space address of disk_block disk_block b; // Holds block data in kernel space // If we're not in system mode, we need to copy everything from the // user-space virtual address to the kernel space address if (!sysMode) { // Get the arguments themselves into system space // Argument 0: block number MemoryCopyUserToSystem (currentPCB, (trapArgs+0), &blocknum, sizeof(uint32)); // Argument 1: address of user-space disk_block structure MemoryCopyUserToSystem (currentPCB, (trapArgs+1), &user_block, sizeof(uint32)); // Now copy block from user space to kernel space MemoryCopyUserToSystem (currentPCB, user_block, &b, sizeof(disk_block)); } else { // Already in kernel space, no address translation necessary blocknum = trapArgs[0]; bcopy ((void *)(trapArgs[1]), (void *)&b, sizeof(disk_block)); // Copy message into local variable for simplicity } return DiskWriteBlock(blocknum, &b); }
//----------------------------------------------------------------- // DfsWriteBlock writes to an allocated DFS block on the disk // (which could span multiple physical disk blocks). The block // must be allocated in order to write to it. Returns DFS_FAIL // on failure, and the number of bytes written on success. //----------------------------------------------------------------- int DfsWriteBlock(uint32 blocknum, dfs_block *b) { disk_block diskb; int diskblocksize; int factor; int i; int count = 0; if(fbv[blocknum / 32] & (1 << (blocknum % 32))) { printf("DfsWriteBlock: the block %d is not allocated\n", blocknum); return DFS_FAIL; } diskblocksize = DiskBytesPerBlock(); factor = sb.blocksize / diskblocksize; for(i = 0; i < factor; i++) { bcopy(&(b->data[i * diskblocksize]), diskb.data, diskblocksize); if(DiskWriteBlock((blocknum * factor) + i, &diskb) == DISK_FAIL) { printf("DfsWriteBlock: Disk write failed copied %d of %d\n", count, sb.blocksize); break; } count += diskblocksize; } return count; }
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; }