int FileDelete(char *filename) { int inode_handle; if(dstrlen(filename) > FILE_MAX_FILENAME_LENGTH) { printf("FileDelete -- Filename is too large!\n"); return(FILE_FAIL); } inode_handle = DfsInodeFilenameExists(filename); if(inode_handle == -1) { printf("FileDelete -- File does not exist!\n"); return(FILE_FAIL); } if(DfsInodeDelete(inode_handle) == -1) { printf("FileDelete -- Unable to delete inode\n"); return(FILE_FAIL); } printf("FileDelete -- Successfully deleted file: %s\n", filename); return(FILE_SUCCESS); }
//----------------------------------------------------------------- // DfsInodeOpen: search the list of all inuse inodes for the // specified filename. If the filename exists, return the handle // of the inode. If it does not, allocate a new inode for this // filename and return its handle. Return DFS_FAIL on failure. // Remember to use locks whenever you allocate a new inode. //----------------------------------------------------------------- uint32 DfsInodeOpen(char *filename) { uint32 i; if(!sb.valid) { printf("DfsInodeOpen: invalid file system\n"); return DFS_FAIL; } i = DfsInodeFilenameExists(filename); if(i != DFS_FAIL) { printf("[DEBUG] Opened inode:%d\n", i); return i; } while(LockHandleAcquire(dfs_inode_lock) != SYNC_SUCCESS); for(i = 0; i < sb.total_inodes; i++) { if(inodes[i].valid) { continue; } inodes[i].valid = 1; inodes[i].filesize = 0; dstrncpy(inodes[i].filename, filename, DFS_FILENAME_LENGTH); break; } LockHandleRelease(dfs_inode_lock); printf("[DEBUG] Opened inode:%d\n", i); return i; }
int DfsInodeOpen(char *filename,int handle,int type,int ownerid,unsigned char permission) { int i,j; int handler; // printf("In DfsInodeOpen\n"); if(sb.valid == 0){ printf("File system not open!\n"); return DFS_FAIL; } if((handler = DfsInodeFilenameExists(filename,handle))!= DFS_FAIL){ printf("Open existing file!\n"); return handler; } else{ for(i=0;i<sb.inodenum;i++){ if(inodes[i].inuse == 0){ LockHandleAcquire(lock_inode); inodes[i].inuse = 1; inodes[i].filesize = 0; for(j=0;j<sb.dirnum;j++){ if(dir[j].inuse == 0){ inodes[i].dir = &dir[j]; break; } } inodes[i].permission = permission; inodes[i].type = type; inodes[i].ownerid = ownerid; handler=i; LockHandleRelease(lock_inode); if(InsertEntry(filename,handle,handler)== DFS_FAIL){ printf ("Error: Cannot insert inode %d into dir of inode %d\n",handler,handle); return DFS_FAIL; } return handler; } } } printf("No free inodes!\n"); return DFS_FAIL; }
void RunOSTests() { // STUDENT: run any os-level tests here int handle = 0; char *file1 = "test1"; char mem[20000]; char mem_read[20000]; int start_byte = 0; int num_bytes = 0; int ct = 0; char stuff = 'a'; int ct_err = 0; // first, initialize the file system if(DfsOpenFileSystem() == DFS_FAIL) { dbprintf('s', "ostests: failed to open file system.\n"); } //make sure such file does not exist, if yes, error if(DfsInodeFilenameExists(file1) != DFS_FAIL) { dbprintf('s', "Error: found unexisted file.\n"); } // now create an inode for such file handle = DfsInodeOpen(file1); // now check if such file exists printf("hello.\n"); if(DfsInodeFilenameExists(file1) != handle) { dbprintf('s', "Error: file inode did not create.\n"); } // start to write bytes into memory // first write something into the mem for(ct = 0; ct < 512; ct++) { mem[ct] = stuff; stuff = 'z' ? 'a' : (stuff + 1); } // now that mem is stuffed, we write part of it into file num_bytes = 350; // write 350 bytes start_byte = 0; // start from 25th byte //////////////////////// ERROR HERE /////////////////////// if(DfsInodeWriteBytes(handle, mem, start_byte, num_bytes) != num_bytes) { dbprintf('s', "dfs write: write 350 bytes failed.\n"); } // now check if previous 25 bytes are empty and all stuff are written, read from 0, to 512 if(DfsInodeReadBytes(handle, mem_read, 0, 512) != num_bytes) { dbprintf('s', "dfs read: read 350 bytes failed.\n"); } // now test if the read data is identicle to the written // first test if first 25 are 0 for(ct = 0; ct < 25; ct++) { if(mem_read[ct] != 0) { ct_err++; } } /* dbprintf('s', "Among the first 25 data, %d are not correct.\n", ct_err); */ printf("Among the first 25 data, %d are not correct.\n", ct_err); // then test if next 350 bytes are what were written ct_err = 0; for(; ct < 375; ct++) { if(mem_read[ct] != mem[ct-25]) { ct_err++; } } /* dbprintf('s', "Among the next 350 bytes, %d are not correct.\n", ct_err); */ printf("Among the next 350 bytes, %d are not correct.\n", ct_err); // last check if the remaining 138 bytes are null ct_err = 0; for(; ct < 512; ct++) { if(mem_read[ct] != 0) { ct_err++; } } /* dbprintf('s', "Among the last 138 bytes, %d are not correct.\n", ct_err); */ printf("Among the last 138 bytes, %d are not correct.\n", ct_err); // next test if we can over write into the file // change the mem stuff = '1'; for(ct = 0; ct < 1024; ct++) { mem[ct] = stuff; stuff = '9' ? '1' : (stuff + 1); } // now write this into the previous if(DfsInodeWriteBytes(handle, (void *)mem, 0, 1024) != num_bytes) { dbprintf('s', "dfs write: write 1024 bytes failed.\n"); } // now check if previous 25 bytes are empty and all stuff are written, read from 0, to 512 if(DfsInodeReadBytes(handle, mem_read, 0, 1024) != num_bytes) { dbprintf('s', "dfs read: read 1024 bytes failed.\n"); } ct_err = 0; for(ct = 0; ct < 1024; ct++) { if(mem_read[ct] != mem[ct]) { ct_err++; } } /* dbprintf('s', "Among the first dfs block, %d are not correct.\n", ct_err); */ printf("Among the first dfs block, %d are not correct.\n", ct_err); // we need to check if those data still there after closing file system // now we test how it works when write more than one block stuff = 'a'; for(ct = 0; ct < 1025; ct++) { mem[ct] = stuff; stuff = 'z' ? 'a' : (stuff + 1); } // now write this into the previous if(DfsInodeWriteBytes(handle, (void *)mem, 1024, 1025) != num_bytes) { dbprintf('s', "dfs write: write 1024 bytes failed.\n"); } // now check if previous 25 bytes are empty and all stuff are written, read from 0, to 512 if(DfsInodeReadBytes(handle, mem_read, 1024, 1025) != num_bytes) { dbprintf('s', "dfs read: read 1024 bytes failed.\n"); } ct_err = 0; for(ct = 0; ct < 1025; ct++) { if(mem_read[ct] != mem[ct]) { ct_err++; } } /* dbprintf('s', "Among the second dfs block, %d are not correct.\n", ct_err); */ printf("Among the second dfs block, %d are not correct.\n", ct_err); // check if in the third block, all are null except the first byte if(DfsInodeReadBytes(handle, mem_read, 2048, 1024) != 1024) { dbprintf('s', "dfs read: third 1024 bytes failed.\n"); } if(mem_read[0] == 0) { dbprintf('s', "Error: previous write was not right.\n"); } for(ct = 1; ct < 1024; ct++) { if(mem_read[ct] != 0) { dbprintf('s', "Error: a byte is not written while it is not supposed to.\n"); break; } } // now we write into enough bytes to create indirect table stuff = 'A'; for(ct = 0; ct < 13313; ct++) { mem[ct] = stuff; stuff = 'Z' ? 'A' : (stuff + 1); } // write till 5th indirect block, and one more extra byte in 6th if(DfsInodeWriteBytes(handle, (void *)mem, 2048, 13313) != 13313) { dbprintf('s', "dfs write: write 13313 bytes failed.\n"); } // we should check this by using block print // close inode if(DfsInodeDelete(handle) != DFS_SUCCESS) { dbprintf('s', "Error: inode delete fail.\n"); } // close the file system if(DfsCloseFileSystem() != DFS_SUCCESS) { dbprintf('s', "Error: file system close fail.\n"); } printf("======================== ostests completed ===============================.\n"); }
int FileOpen(char *filename, char *mode){ int inode_handle; int i; if(dstrlen(filename) > FILE_MAX_FILENAME_LENGTH) { printf("FileOpen -- Filename is too large!\n"); return(FILE_FAIL); } if((dstrlen(mode) == 2) && (*mode == 'r') && (*(mode+1) == 'w')) { printf("RW MODE\n"); // get inode_handle (create if doesn't exist) inode_handle = DfsInodeOpen(filename); if(inode_handle == -1) { printf("FileOpen -- Unable to open file in read/write mode\n"); return(FILE_FAIL); } } else if((dstrlen(mode) == 1) && (*mode == 'r')) { printf("R MODE\n"); // get inode_handle (create if doesn't exist) inode_handle = DfsInodeOpen(filename); if(inode_handle == -1) { printf("FileOpen -- Unable to open file in read mode\n"); return(FILE_FAIL); } } else if((dstrlen(mode) == 1) && (*mode == 'w')) { printf("W MODE\n"); // check if exists inode_handle = DfsInodeFilenameExists(filename); if(inode_handle != -1) // if it exists, delete { dbprintf('F', "FileOpen -- Opening in W mode and file exists... deleting inode!\n"); if(DfsInodeDelete(inode_handle) == -1) { printf("FileOpen -- Unable to delete inode\n"); return(FILE_FAIL); } // TODO: invalidate all file descriptors corresponding to the deleted inode. } // then open inode_handle = DfsInodeOpen(filename); if(inode_handle == -1) { printf("FileOpen -- Unable to open file in read mode\n"); return(FILE_FAIL); } } else { printf("FileOpen -- Invalid mode!\n"); return(FILE_FAIL); } // We now have an inode descriptor for a given file // Find an available file descriptor to hold data for(i=0; i<FILE_MAX_OPEN_FILES; i++) { if(fd_array[i].FD_Valid == 0) { // Populate file descriptor with appropriate data dstrncpy ((char*)&fd_array[i].FD_FileName, filename, FILE_MAX_FILENAME_LENGTH); fd_array[i].FD_InodeHandle = inode_handle; fd_array[i].FD_CurrentPosition = 0; fd_array[i].FD_EOF_Flag = 0; if(dstrlen(mode) == 2) fd_array[i].FD_Mode = FILE_READWRITE; else if((dstrlen(mode) == 1) && (*mode == 'r')) fd_array[i].FD_Mode = FILE_READ; else fd_array[i].FD_Mode = FILE_WRITE; fd_array[i].FD_PID = GetCurrentPid(); // mark as valid, and return handle to file descriptor fd_array[i].FD_Valid = 1; dbprintf('F', "FileOpen -- Using file descriptor #%d for newly opened file\n", i); return(i); } } printf("FileOpen -- Unable to find an empty file descriptor!\n"); return(FILE_FAIL); }