void BufferManager::deleteRecord(const std::string& fileName, int blockOffset, int start)//给recordManager { int n = fileName.find(".table",0); std::string tableName = fileName.substr(0, n); Table* tablePtr = Cat.getTablePtr(tableName); std::string ss = ""; for (int i = 0; i < tablePtr->recordSize; i++) ss += '\0'; std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); if (start + tablePtr->recordSize>BLOCK_SIZE) { int length1 = BLOCK_SIZE - start; int length2 = tablePtr->recordSize - length1; (*it)->changeContent(start,ss.substr(0,length1)); it = readFileBlock(fileName, blockOffset+1); (*it)->changeContent(0,ss.substr(0,length2)); } else (*it)->changeContent(start, ss); int recordOffset = (blockOffset*BLOCK_SIZE + start) / tablePtr->recordSize; tablePtr->emptyRecordOffset.push_back(recordOffset); }
int BufferManager::insertBlock(const std::string &fileName, const std::string& content) { int n = fileName.find(".index", 0); std::string indexName = fileName.substr(0, n); Index* indexPtr = Cat.getIndexPtr(indexName); std::list<Block*>::iterator it; if (indexPtr->emptyBlockOffset.empty() == 1) { it = addBlockInFile(fileName); (*it)->blockOffset = indexPtr->blockNum; (*it)->fileName = fileName; (*it)->isDirty = 1; indexPtr->blockNum++; (*it)->changeContent(0, content); } else { int blockOffset = indexPtr->emptyBlockOffset.back(); indexPtr->emptyBlockOffset.pop_back(); it = readFileBlock(fileName, blockOffset); (*it)->changeContent(0, content); } return (*it)->blockOffset; }
/* * Reads a file and locks it */ bool Directory::openFile(string path, string name, string &data) { if (!initialised) throw std::runtime_error("Directory not Initialised"); if (isPathNameLegal(path) && isNameLegal(name)) { // check the path is valid int directoryNode = directoryTree->getPathNode(path); if (directoryNode < 0) { cout << "path " << path << " is invalid" << endl; return false; } // cache the directory (path) if it is not already cached int directoryNodeCache = getCachedDirectory(directoryNode); // check the filename exists if (cachedDirectory[directoryNodeCache]->cache.count(name) < 1) { cout << "file " << name << " does not exist" << endl; freeCachedDirectory(directoryNodeCache); return false; } else if (iNodeList->isINodeDirectory(cachedDirectory[directoryNodeCache]->cache[name])) { cout << name << " refers to directory - unable to read" << endl; freeCachedDirectory(directoryNodeCache); return false; } data.clear(); iNodeList->lockINode(cachedDirectory[directoryNodeCache]->cache[name]); // read the file and put the data in data and the length in fileLength for (int i=0;i<iNodeList->getNumberOfBlocks(cachedDirectory[directoryNodeCache]->cache[name]);i++) { readFileBlock(iNodeList->getBlockNumber(cachedDirectory[directoryNodeCache]->cache[name],i),data); } freeCachedDirectory(directoryNodeCache); return true; } else { cout << "Path or filename not legal" << endl; return false; } }
std::string BufferManager::getBlock(const std::string& fileName, int blockOffset,int start,int end) { int n = fileName.find(".index", 0); Index *indexPtr = Cat.getIndexPtr(fileName.substr(0, n)); std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); std::string record = ""; for (int i = start; i < end; i++) record += (*it)->content[i]; return record; }
std::string BufferManager::getRecord(const std::string& fileName, int blockOffset, int start) { int n = fileName.find(".table",0); Table* tablePtr = Cat.getTablePtr(fileName.substr(0, n)); std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); std::string record = ""; if (start + tablePtr->recordSize > BLOCK_SIZE) { int length1 = BLOCK_SIZE - start; int length2 = tablePtr->recordSize - length1; for (int i = 0; i < length1; i++) record += (*it)->content[start + i]; it = readFileBlock(fileName, blockOffset+1); for (int i = 0; i < length2; i++) record += (*it)->content[i]; } else for (int i = 0; i < tablePtr->recordSize; i++) record += (*it)->content[i+start]; return record; }
void BufferManager::changeValue(const std::string& fileName, int blockOffset, int start, std::string& c) { std::list<Block*>::iterator it = findBlockInBuffer(fileName, blockOffset); if (it != fullBuffer.end()) { (*it)->changeContent(start, c); fullBuffer.push_front((*it)); fullBuffer.erase(it); } else { std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); (*it)->changeContent(start, c); } }
void BufferManager::readFile(const std::string& fileName) { int blockNum; int n; if ((n = fileName.find(".table", 0)) != std::string::npos) { Table* tablePtr = Cat.getTablePtr(fileName.substr(0,n)); blockNum = tablePtr->blockNum; } if ((n = fileName.find(".index", 0)) != std::string::npos) { Index* indexPtr = Cat.getIndexPtr(fileName.substr(0, n)); blockNum = indexPtr->blockNum; } std::list<Block*>::iterator it; for (int i = 0; i < blockNum; i++) it = readFileBlock(fileName, i); }
void BufferManager::deleteBlock(const std::string &fileName, int blockOffset)//给indexManager { int n = fileName.find(".index", 0); std::string indexName = fileName.substr(0, n); std::vector<Index*>::iterator indexPtr = Cat.findIndex(indexName); std::string ss = ""; for (int i = 0; i < BLOCK_SIZE; i++) ss += '\0'; std::list<Block*>::iterator it = findBlockInBuffer(fileName, blockOffset); if (it != fullBuffer.end()) { (*it)->changeContent(0, ss); fullBuffer.push_front((*it)); fullBuffer.erase(it); } else { it = readFileBlock(fileName, blockOffset); (*it)->changeContent(0, ss); } (*indexPtr)->emptyBlockOffset.push_back(blockOffset); }
int BufferManager::insertRecord(const std::string& fileName, const std::string& content) { int n = fileName.find(".table", 0); std::string tableName = fileName.substr(0, fileName.size()-6); Table* tablePtr = Cat.getTablePtr(tableName); std::list<Block*>::iterator it; if (tablePtr->emptyRecordOffset.empty() == 1)//没有空位 { it = addBlockInFile(fileName); (*it)->blockOffset = tablePtr->blockNum; (*it)->fileName = fileName; (*it)->isDirty = 1; tablePtr->blockNum++; (*it)->changeContent(0, content); int recordOffset = ((tablePtr->blockNum - 1)*BLOCK_SIZE )/ tablePtr->recordSize; int num; if (BLOCK_SIZE % tablePtr->recordSize == 0) num = BLOCK_SIZE / tablePtr->recordSize; else num = BLOCK_SIZE / tablePtr->recordSize + 1; for (int i = 1; i < num; i++) tablePtr->emptyRecordOffset.push_back(recordOffset + i); return (*it)->blockOffset << 16; } else//有空位 { int recordOffset = *((tablePtr->emptyRecordOffset).begin()); (tablePtr->emptyRecordOffset).erase((tablePtr->emptyRecordOffset).begin()); int blockOffset = (recordOffset*tablePtr->recordSize) / BLOCK_SIZE; int start = (recordOffset*tablePtr->recordSize) % BLOCK_SIZE; it = readFileBlock(fileName, blockOffset); if (start + tablePtr->recordSize > BLOCK_SIZE)//记录跨block { int length1 = BLOCK_SIZE - start; int length2 = tablePtr->recordSize - length1; (*it)->changeContent(start, content.substr(0, length1)); if (blockOffset + 1 == tablePtr->blockNum)//所跨block的下一个需要生成 { it = addBlockInFile(fileName); (*it)->blockOffset = tablePtr->blockNum; (*it)->fileName = fileName; (*it)->isDirty = 1; tablePtr->blockNum++; (*it)->changeContent(0, content.substr(length1, length2)); int i = recordOffset+1; int size = length2; while (size < BLOCK_SIZE) { tablePtr->emptyRecordOffset.push_back(i); size += tablePtr->recordSize; i++; } } else//所跨block的下一个不需要生成 { it = readFileBlock(fileName,blockOffset+1); (*it)->changeContent(0, content.substr(length1, length2)); } } else//记录不跨block (*it)->changeContent(start, content); return (blockOffset << 16) | start; } }
/** * @brief * try opening a legal pathname with "." and ".." * @return 1 if successful, 0 otherwise */ error_t openTest26(){ bool_t cpWritten; INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(prev_log_addr); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_file); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_dir2); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_dir1); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_root); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr); dirent_flash *dirent_ptr = CAST_TO_DIRENT(fs_buffer); inode_t *ino_ptr = CAST_TO_INODE(fs_buffer); uint8_t *f_full_name = "/directory1/../directory1/directory2/file1.dat"; uint32_t i; int32_t fd, flags = NANDFS_O_RDONLY; user_id user = 1; init_logical_address(prev_log_addr); init_logical_address(log_addr_file); init_logical_address(log_addr_dir2); init_logical_address(log_addr_dir1); init_logical_address(log_addr_root); init_logical_address(log_addr); /* set user in process*/ SET_CURRENT_USER(user); /* write file inode */ VERIFY(!writeNewInode(4, INO_NUM_EMPTY, FTYPE_FILE, log_addr_file)); /* write directory2 inode*/ VERIFY(!writeNewInode(3, 2, FTYPE_DIR, log_addr_dir2)); /* write directory1 inode*/ VERIFY(!writeNewInode(2, 1, FTYPE_DIR, log_addr_dir1)); /* write file1.dat direntry in directory2*/ VERIFY(!readFileBlock(fs_buffer, 3, INODE_FILE_DATA_SIZE, log_addr_dir2, TID_EMPTY)); /* iterate until we find an empty directory entry*/ while(!IS_DIRENT_EMPTY(dirent_ptr)) moveToNextDirentry(&dirent_ptr, DIRENT_GET_LEN(dirent_ptr)); setNewDirentry(dirent_ptr, 4, FTYPE_FILE, "file1.dat"); VERIFY(!allocAndWriteBlock(log_addr, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* write directory2 inode with new pointer to the above block*/ VERIFY(!fsReadBlockSimple(log_addr_dir2, fs_buffer)); INODE_SET_DIRECT(ino_ptr,0,log_addr); VERIFY(!allocAndWriteBlock(log_addr_dir2, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* write directory2 direntry in directory1*/ VERIFY(!readFileBlock(fs_buffer, 2, INODE_FILE_DATA_SIZE, log_addr_dir1,TID_EMPTY)); /* iterate until we find an empty directory entry*/ while(!IS_DIRENT_EMPTY(dirent_ptr)) moveToNextDirentry(&dirent_ptr, DIRENT_GET_LEN(dirent_ptr)); setNewDirentry(dirent_ptr, 3, FTYPE_DIR, "directory2"); VERIFY(!allocAndWriteBlock(log_addr, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* write directory1 inode with new pointer to the above block*/ VERIFY(!fsReadBlockSimple(log_addr_dir1, fs_buffer)); INODE_SET_DIRECT(ino_ptr,0,log_addr); VERIFY(!allocAndWriteBlock(log_addr_dir1, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* write directory1 direntry in root*/ VERIFY(!readFileBlock(fs_buffer, 1, INODE_FILE_DATA_SIZE, log_addr_root, TID_EMPTY)); /* iterate until we find an empty directory entry*/ while(!IS_DIRENT_EMPTY(dirent_ptr)) moveToNextDirentry(&dirent_ptr, DIRENT_GET_LEN(dirent_ptr)); setNewDirentry(dirent_ptr, 2, FTYPE_DIR, "directory1"); VERIFY(!allocAndWriteBlock(log_addr, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* write directory1 inode with new pointer to the above block*/ VERIFY(!fsReadBlockSimple(log_addr_root, fs_buffer)); INODE_SET_DIRECT(ino_ptr,0,log_addr); VERIFY(!allocAndWriteBlock(log_addr_root, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* write inode0 with pointers to the new root address*/ VERIFY(!fsReadBlockSimple(FS_GET_INO0_ADDR_PTR(), fs_buffer)); INODE_SET_DIRECT(ino_ptr,0,log_addr_root); INODE_SET_DIRECT(ino_ptr,1,log_addr_dir1); INODE_SET_DIRECT(ino_ptr,2,log_addr_dir2); INODE_SET_DIRECT(ino_ptr,3,log_addr_file); INODE_SET_NBYTES(ino_ptr, CAST_VAL_TO_UINT32(INODE_FILE_DATA_SIZE+4*FS_BLOCK_SIZE)); VERIFY(!allocAndWriteBlock(FS_GET_INO0_ADDR_PTR(), fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0)); /* and now try opening file1.dat*/ fd = open(f_full_name, flags, 0); VERIFY(!IS_NEGATIVE(fd)); VERIFY(COMPARE(VNODE_GET_INO_NUM(OPEN_FILE_GET_VNODE(fd)), 4)); VERIFY(IS_RDONLY(OPEN_FILE_GET_FLAGS(fd))); for(i=0; i< FS_MAX_OPEN_FILES;i++){ if(i==fd){ VERIFY(verifyOpenFileEntry(fd, flags,0,user, 0)); } else{ VERIFY(verifyOpenFileEntryEmpty(i)); } } for(i=0; i<FS_MAX_VNODES;i++){ if(i!=fd){ VERIFY(verifyVnodeEmpty(i)); } else{ VERIFY(verifyVnode(i, 4, 1)); } } // return 1; }