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; }