int DfsInodeReadBytes(int handle, void *mem, int start_byte, int num_bytes) { int i; int end_byte = start_byte+num_bytes-1; int byte_start,byte_end; int block_start,block_end; dfs_block block; int blocknum; int byte_read; // printf("In DfsInodeReadBytes\n"); if(sb.valid == 0){ printf("File system not open!\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((start_byte<0)||(num_bytes<0)||((end_byte)>inodes[handle].filesize)){ printf("Invalid start_byte = %d or num_byte= %d\n",start_byte,num_bytes); return DFS_FAIL; } block_start = (start_byte/sb.filesys_blocksize); byte_start = (start_byte%sb.filesys_blocksize); block_end = (end_byte/sb.filesys_blocksize); byte_end = (end_byte%sb.filesys_blocksize); if(block_start == block_end){ blocknum = DfsInodeTranslateVirtualToFilesys(handle,block_start); // printf("read from block(start=end) %d\n",blocknum); DfsReadBlock(blocknum,&block); bcopy((char *)((int)&block+byte_start),(char *)mem,num_bytes); return (num_bytes); } else{ blocknum = DfsInodeTranslateVirtualToFilesys(handle,block_start); // printf("read from block(1st) %d\n",blocknum); DfsReadBlock(blocknum,&block); byte_read = sb.filesys_blocksize-(byte_start); bcopy((char *)((int)&block+byte_start),(char *)mem,byte_read); for(i=(block_start)+1;i<(block_end);i++){ blocknum = DfsInodeTranslateVirtualToFilesys(handle,i); // printf("read from block(middle) %d\n",blocknum); DfsReadBlock(blocknum,&block); bcopy((char *)(&block),(char *)((int)mem+byte_read),sb.filesys_blocksize); byte_read +=sb.filesys_blocksize; } blocknum = DfsInodeTranslateVirtualToFilesys(handle,block_end); // printf("read from block(last) %d\n",blocknum); DfsReadBlock(blocknum,&block); bcopy((char *)(&block),(char *)((int)mem+byte_read),(byte_end)+1); byte_read +=(byte_end)+1; return (byte_read); } }
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 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; } } }
int DfsInodeDelete(int handle) { int i; dfs_block indirect_table; uint32 *table; // printf("In DfsInodeDelete\n"); if (sb.valid == 0){ printf("File system not open!\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; } LockHandleAcquire(lock_inode); //Free direct table then check if there is indirect address for(i=0;i<10;i++){ if(inodes[handle].direct[i]!=0){ if(DfsFreeBlock((int)inodes[handle].direct[i])==DFS_FAIL){ printf("Cannot free blocks in direct table!\n"); return DFS_FAIL; } inodes[handle].direct[i]=0; } } //Free the indirect table if(inodes[handle].indirect != 0){ table =(uint32 *)(&indirect_table); DfsReadBlock(inodes[handle].indirect,&indirect_table); for(i=0;i<(sb.filesys_blocksize)/sizeof(uint32);i++){ if(table[i]!=0){ if (DfsFreeBlock((int)table[i])== DFS_FAIL){ printf("Cannot free blocks in indirect table\n"); return DFS_FAIL; } } } if(DfsFreeBlock((int)inodes[handle].indirect)==DFS_FAIL){ printf("Cannot free blocks in indirect table\n"); } inodes[handle].indirect=0; } FreeEntry(handle); inodes[handle].filesize = 0; // for(i=0;i< FILENAME_LENGTH;i++){ // inodes[handle].filename[i]='\0'; // } inodes[handle].permission = 0; inodes[handle].type = 0; inodes[handle].ownerid = 0; inodes[handle].inuse = 0; LockHandleRelease(lock_inode); return DFS_SUCCESS; }
//----------------------------------------------------------------- // DfsInodeTranslateVirtualToFilesys translates the // virtual_blocknum to the corresponding file system block using // the inode identified by handle. Return DFS_FAIL on failure. //----------------------------------------------------------------- uint32 DfsInodeTranslateVirtualToFilesys(uint32 handle, uint32 virtual_blocknum) { dfs_block dfsb; int* block_entry_table; if(!sb.valid) { printf("DfsInodeTranslateVirtualToFilesys: invalid file system\n"); return DFS_FAIL; } if(!inodes[handle].valid) { printf("DfsInodeTranslateVirtualToFilesys: 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)) { printf("DfsInodeTranslateVirtualToFilesys: invalid block entry in indirect blocks %d\n", virtual_blocknum); return DFS_FAIL; } DfsReadBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb); virtual_blocknum -= 10; if(DFS_IS_BLOCK_ENTRY_VALID(block_entry_table[virtual_blocknum])) { return DFS_GET_BLOCK_NUM(block_entry_table[virtual_blocknum]); } else { printf("DfsInodeTranslateVirtualToFilesys: invalid block's block entry in indirect blocks %d\n", virtual_blocknum); return DFS_FAIL; } } else { block_entry_table = inodes[handle].direct_block_entries; if(DFS_IS_BLOCK_ENTRY_VALID(block_entry_table[virtual_blocknum])) { return DFS_GET_BLOCK_NUM(block_entry_table[virtual_blocknum]); } else { printf("DfsInodeTranslateVirtualToFilesys: invalid block entry in direct blocks %d\n", virtual_blocknum); return DFS_FAIL; } } printf("---THIS SHOULD NOT HAPPEN---\n"); return DFS_FAIL; }
int DfsInodeTranslateVirtualToFilesys(int handle, int virtual_blocknum) { dfs_block indirect_table; uint32 *table; uint32 blocknum; // printf("In DfsInodeTranslateVirtualToFilesys\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){ return (inodes[handle].direct[virtual_blocknum]); } else{ if(inodes[handle].indirect == 0){ printf("Indirect address table not exist!\n"); return DFS_FAIL; } else{ table = (uint32 *)(&indirect_table); DfsReadBlock(inodes[handle].indirect,&indirect_table); blocknum = table[virtual_blocknum-10]; return (int)blocknum; } } return DFS_FAIL; }
int DfsInodeTruncateFile(uint32 handle) { int i; dfs_block dfsb; int* inints = (int*) dfsb.data; if(!sb.valid) { printf("DfsInodeTruncateFile: invalid file system\n"); return DFS_FAIL; } if(!inodes[handle].valid) { printf("DfsInodeTruncateFile: invalid inode\n"); return DFS_FAIL; } while(LockHandleAcquire(dfs_fbv_lock) != SYNC_SUCCESS); if(DFS_IS_BLOCK_ENTRY_VALID(inodes[handle].indir_block_entry)) { DfsReadBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb); for(i = 0; i < (sb.blocksize / sizeof(int)); i++) { if(DFS_IS_BLOCK_ENTRY_VALID(inints[i])) { SetFreeVector(DFS_GET_BLOCK_NUM(inints[i]), 1); } } // clear out the indirect block entry table bzero(dfsb.data, sb.blocksize); DfsWriteBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb); SetFreeVector(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), 1); inodes[handle].indir_block_entry = DFS_SET_BLOCK_ENTRY(0, 0); } for(i = 0; i < 10; i++) { if(DFS_IS_BLOCK_ENTRY_VALID(inodes[handle].direct_block_entries[i])) { SetFreeVector(DFS_GET_BLOCK_NUM(inodes[handle].direct_block_entries[i]), 1); inodes[handle].direct_block_entries[i] = DFS_SET_BLOCK_ENTRY(0, 0); } } LockHandleRelease(dfs_fbv_lock); inodes[handle].filesize = 0; return DFS_SUCCESS; }
//----------------------------------------------------------------- // DfsInodeWriteBytes writes num_bytes from the memory pointed to // by mem to the file represented by the inode handle, starting at // virtual byte start_byte. Note that if you are only writing part // of a given file system block, you'll need to read that block // from the disk first. Return DFS_FAIL on failure and the number // of bytes written on success. //----------------------------------------------------------------- int DfsAllocateCheck(int handle,int blocknum){ uint32 *table; dfs_block indirect_table; if(blocknum<10){ if(inodes[handle].direct[blocknum]==0){ return DFS_FAIL; } } else{ if(inodes[handle].indirect==0){ return DFS_FAIL; } else{ table =(uint32 *)(&indirect_table); DfsReadBlock(inodes[handle].indirect,&indirect_table); if(table[blocknum-10]==0){ return DFS_FAIL; } } } return DFS_SUCCESS; }
//----------------------------------------------------------------- // DfsInodeReadBytes reads num_bytes from the file represented by // the inode handle, starting at virtual byte start_byte, copying // the data to the address pointed to by mem. Return DFS_FAIL on // failure, and the number of bytes read on success. //----------------------------------------------------------------- int DfsInodeReadBytes(uint32 handle, void *mem, int start_byte, int num_bytes) { int cur_byte = start_byte; int blocknum; int data_bytes; int byte_count = 0; dfs_block dfsb; char* mem_bytes = (char*) mem; if(!sb.valid) { printf("DfsInodeReadBytes: invalid file system\n"); return DFS_FAIL; } if(!inodes[handle].valid) { printf("DfsInodeReadBytes: invalid inode\n"); return DFS_FAIL; } while(byte_count < num_bytes) { blocknum = DfsInodeTranslateVirtualToFilesys(handle, cur_byte / sb.blocksize); if(blocknum == DFS_FAIL) { printf("Error: Trying to read from part of file that wasn't written already\n"); return DFS_FAIL; } if(DfsReadBlock(blocknum, &dfsb) == DFS_FAIL) { printf("DfsInodeReadBytes: DfsReadBlock failed\n"); break; } data_bytes = sb.blocksize - (cur_byte % sb.blocksize); if((byte_count + data_bytes) > num_bytes) { // remove the extra data bytes data_bytes = data_bytes - ((byte_count + data_bytes) - num_bytes); } bcopy(&(dfsb.data[cur_byte % sb.blocksize]), &(mem_bytes[byte_count]), data_bytes); byte_count += data_bytes; cur_byte = start_byte + byte_count; } return byte_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; }
int DfsInodeWriteBytes(int handle, void *mem, int start_byte, int num_bytes) { int i; int end_byte = start_byte+num_bytes-1; int byte_start,byte_end; int block_start,block_end; dfs_block block; int blocknum; int byte_write; // printf("In DfsInodeWriteBytes\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((start_byte<0)||(num_bytes<0)||((end_byte)>(sb.filesys_blocknum*sb.filesys_blocksize))){ printf("Invalid start_byte = %d or num_byte= %d\n",start_byte,num_bytes); return DFS_FAIL; } block_start = (start_byte/sb.filesys_blocksize); byte_start = (start_byte%sb.filesys_blocksize); block_end = (end_byte/sb.filesys_blocksize); byte_end = (end_byte%sb.filesys_blocksize); if(block_start == block_end){ //check if the virtual block table is valid if(DfsAllocateCheck(handle,block_start)!= DFS_FAIL){ blocknum = DfsInodeTranslateVirtualToFilesys(handle,block_start); // printf("write to block(start=end,noalloc) %d\n",blocknum); DfsReadBlock(blocknum,&block); bcopy((char *)mem,(char *)((int)&block+byte_start),num_bytes); DfsWriteBlock(blocknum,&block); } else{ if((blocknum = DfsInodeAllocateVirtualBlock(handle,block_start))== DFS_FAIL){ printf("Cannot allocate a virtual block\n"); return DFS_FAIL; } // printf("write to block(start=end alloc) %d\n",blocknum); DfsReadBlock(blocknum,&block); bzero((char *)&block,sizeof(dfs_block)); bcopy((char *)mem,(char *)((int)&block+byte_start),num_bytes); DfsWriteBlock(blocknum,&block); } inodes[handle].filesize+=num_bytes; return (num_bytes); } else{ if(DfsAllocateCheck(handle,block_start)!=DFS_FAIL){ blocknum = DfsInodeTranslateVirtualToFilesys(handle,block_start); // printf("write to block(1st,noalloc) %d\n",blocknum); DfsReadBlock(blocknum,&block); byte_write = sb.filesys_blocksize-(byte_start); bcopy((char *)mem,(char *)((int)&block+byte_start),byte_write); DfsWriteBlock(blocknum,&block); } else{ if((blocknum = DfsInodeAllocateVirtualBlock(handle,block_start)) == DFS_FAIL){ printf("Cannot allocate a virtual block!\n"); return DFS_FAIL; } // printf("write to block(1st,alloc) %d\n",blocknum); DfsReadBlock(blocknum,&block); bzero((char *)&block,sizeof(dfs_block)); byte_write = sb.filesys_blocksize-(byte_start); bcopy((char *)mem,(char *)((int)&block+byte_start),byte_write); DfsWriteBlock(blocknum,&block); } for(i=(block_start)+1;i<(block_end);i++){ if((DfsAllocateCheck(handle,i)!=DFS_FAIL)){ blocknum = DfsInodeTranslateVirtualToFilesys(handle,i); // printf("noalloc "); } else{ if((blocknum = DfsInodeAllocateVirtualBlock(handle,i)) == DFS_FAIL){ // printf("Cannot allocate a virtual block!\n"); return DFS_FAIL; } } // printf("write to block(middle) %d\n",blocknum); bzero((char *)&block,sizeof(dfs_block)); bcopy((char *)((int)mem+byte_write),(char *)(&block),sb.filesys_blocksize); DfsWriteBlock(blocknum,&block); byte_write +=sb.filesys_blocksize; } if(DfsAllocateCheck(handle,block_end)!=DFS_FAIL){ blocknum = DfsInodeTranslateVirtualToFilesys(handle,block_end); // printf("write to block(last,noalloc) %d\n",blocknum); DfsReadBlock(blocknum,&block); bcopy((char *)((int)mem+byte_write),(char *)(&block),(byte_end)+1); DfsWriteBlock(blocknum,&block); byte_write +=(byte_end)+1; } else{ if((blocknum = DfsInodeAllocateVirtualBlock(handle,block_end)) == DFS_FAIL){ printf("Cannot allocate a virtual block!\n"); return DFS_FAIL; } // printf("write to block(last alloc) %d\n",blocknum); DfsReadBlock(blocknum,&block); bzero((char *)&block,sizeof(dfs_block)); bcopy((char *)((int)mem+byte_write),(char *)(&block),(byte_end)+1); DfsWriteBlock(blocknum,&block); byte_write +=(byte_end)+1; } inodes[handle].filesize+=byte_write; return (byte_write); } }
//----------------------------------------------------------------- // DfsInodeWriteBytes writes num_bytes from the memory pointed to // by mem to the file represented by the inode handle, starting at // virtual byte start_byte. Note that if you are only writing part // of a given file system block, you'll need to read that block // from the disk first. Return DFS_FAIL on failure and the number // of bytes written on success. //----------------------------------------------------------------- int DfsInodeWriteBytes(uint32 handle, void *mem, int start_byte, int num_bytes) { int cur_byte = start_byte; int blocknum; int data_bytes; int byte_count = 0; dfs_block dfsb; char* mem_bytes = (char*) mem; if(!sb.valid) { printf("DfsInodeWriteBytes: invalid file system\n"); return DFS_FAIL; } if(!inodes[handle].valid) { printf("DfsInodeWriteBytes: invalid inode\n"); return DFS_FAIL; } while(byte_count < num_bytes) { // allocate block first checks whether there's existing otherwise allocates blocknum = DfsInodeAllocateVirtualBlock(handle, cur_byte / sb.blocksize); data_bytes = sb.blocksize - (cur_byte % sb.blocksize); if(data_bytes == sb.blocksize) { // the start is blocksize aligned // check if end is not block aligned if((byte_count + data_bytes) > num_bytes) { // remove the extra data bytes data_bytes = data_bytes - ((byte_count + data_bytes) - num_bytes); // not block aligned so read whole block if(DfsReadBlock(blocknum, &dfsb) == DFS_FAIL) { printf("DfsInodeReadBytes: DfsReadBlock failed\n"); break; } } } else { // start is not block algined // check if end is not block aligned if((byte_count + data_bytes) > num_bytes) { // remove the extra data bytes data_bytes = data_bytes - ((byte_count + data_bytes) - num_bytes); } // We need to do this any way since start is not block aligned if(DfsReadBlock(blocknum, &dfsb) == DFS_FAIL) { printf("DfsInodeWriteBytes: DfsReadBlock failed\n"); break; } } bcopy(&(mem_bytes[byte_count]), &(dfsb.data[cur_byte % sb.blocksize]), data_bytes); if(DfsWriteBlock(blocknum, &dfsb) == DFS_FAIL) { printf("DfsInodeWriteBytes: DfsWriteBlock failed\n"); break; } byte_count += data_bytes; cur_byte = start_byte + byte_count; } if(inodes[handle].filesize < (start_byte + byte_count)) { inodes[handle].filesize = start_byte + byte_count; } return byte_count; }
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; }