inode * getFile(FILE *fs, char ** path, uint32_t inode_off, uint32_t part_off, uint32_t zone_size) { uint32_t inode_num = ROOT_INODE_NUM; uint8_t *dir_data; inode *Inode; uint32_t i; uint32_t dir_num_entries; FATALCALL((Inode=malloc(INODE_SIZE))==NULL,"malloc"); getInode(Inode, ROOT_INODE_NUM, inode_off, fs); if(path[0] == NULL)/*magic number*/ return Inode; for(i=0; path[i] != NULL; i++) { FATALCALL((dir_data=malloc(Inode->size))==NULL,"malloc"); dir_data = getData(fs, Inode, part_off, zone_size); dir_num_entries = (Inode->size/DIR_ENTRY_SIZE); inode_num = existsInPath(dir_data, dir_num_entries, path[i]); if (inode_num == 0) return NULL; getInode(Inode, inode_num, inode_off, fs); if (path[i+1] == NULL) return Inode; free(dir_data); } return Inode; }
/* pseudo open que en base un inode number me lo carga en la tabla para hacer raed y open y baialr la conga*/ static int popen(int inodeNumber){ INODE * inode = getInode(inodeNumber); BLOCK block = getBlock(inode->blocks[0]); if( block == NULL ) { printf("ERROR AL ABRIR EL FILE\n"); return -1; } /* Inicializaicon en tabla */ int i; for( i=0; i<50; i++){ if (openFiles[i].file == NULL) break; } if( i == 50 ){ printf("Tabla llena\n"); return -1; } openFiles[i].pid = currentProc->pid; openFiles[i].file = block; openFiles[i].offset = 0; openFiles[i].currentBlock = 0; openFiles[i].inode = inode; openFiles[i].inodeNumber = inodeNumber; return i; }
ErrorCode freeInode(FileSystem* fs, size_type* inodeId) { //Input is FileSystem* fs, Inode* inode //If successful, Inode* inode will be freed on disk SuperBlock* super = &(fs->super_block); //super->numOfFreeInodes records the current number of free inodes, it is a wrong use. //Use fs->super_block.numOfInodes - By Yan //Corrected by Peng if (*inodeId<0 || *inodeId>=fs->super_block.numOfInodes){ printf("[Free Inode] Inode %ld is not in the legal range :(\n",*inodeId); return OutOfBound; } Inode inode; ErrorCode err_getInode=getInode(fs, inodeId, &inode); if (err_getInode==Success){ //change the mode of inode so that it could be used for garbage collection inode.used=false; ErrorCode err_putInode=putInode(fs, inodeId, &inode); if (err_putInode==Success){ printf("[Free Inode] Inode %ld has been freed\n",*inodeId); return Success; } else{ printf("[Free Inode] Freed Inode %ld can not be written to disk\n",*inodeId); return Err_PutInode; } } else{ printf("[Free Inode] To free Inode %ld, it can not be read from disk\n",*inodeId); return Err_GetInode; } }
//not yet do direct block2, indirect block int read_t( int inode_number, int offset, void *buf, int count) { struct inode inode; inode = getInode(inode_number); if(inode.i_number != inode_number) return -1; //error if(offset>=inode.i_size) { printf("Offset is at or past the end of file, no bytes are read.\n"); return 0; } dirDataBlkIndex = inode.direct_blk[0]; int fd = open ("HD", O_RDWR, 660); lseek(fd, DATA_OFFSET + dirDataBlkIndex * BLOCK_SIZE + offset, SEEK_SET); read(fd, buf, count); if(count>=inode.i_size) { //read only up to count return inode.i_size; }else return count; }
int main () { int rc; /* Return code */ int fd; /* Device descriptor */ int sector; /* IN: sector to read */ struct partition partitions[16]; struct ext2_group_desc groupdescriptors[32]; struct ext2_inode inode; struct ext2_super_block superblock; int block_size; int dir_in_location; int partition_start; int start = 446; int inode_num; int dir_count; int gd_count; int partition_count; /* Open the device */ fd = open ( "disk", O_RDWR ); if ( fd == -1 ) { perror ( "Could not open device file" ); exit(-1); } /* Read the partitions */ partition_count = getPartitions(fd, partitions); partition_start = partitions[0].start_sect; /* Read the Superblock */ superblock = readSuperBlock(fd, partition_start); if (superblock.s_magic == EXT2_SUPER_MAGIC) { printf("\nSuperblock Magic Number: %x (Correct)", superblock.s_magic); } else { printf("\nSuperblock Magic Number: %x (Incorrect)", superblock.s_magic); } block_size = pow(2, superblock.s_log_block_size) * 1024; printf("\nBlock Size: %d\n", block_size); /* Read the group descriptors */ gd_count = getGroupDescriptors(fd, partition_start, groupdescriptors); /* Read the root inode */ inode_num = 2; inode = getInode(fd, inode_num, groupdescriptors, partition_start, superblock.s_inodes_per_group); printf("\nRoot Inode File Mode: "); printFileMode(inode.i_mode); /* See if root inode is allocated */ if (checkAllocation(fd, 1, inode_num, groupdescriptors, partition_start, superblock.s_blocks_per_group, superblock.s_inodes_per_group) == 1) { printf("\nInode Allocated\n"); } else { printf("\nInode Not Allocated\n"); } /* Read the data for root inode */ printf("\nRoot Inode Directory Data..."); dir_in_location = partition_start + (inode.i_block[0] * 2); dir_count = printDirs(fd, dir_in_location); /* Read the oz inode */ inode_num = 28; inode = getInode(fd, inode_num, groupdescriptors, partition_start, superblock.s_inodes_per_group); /* Read the data for oz inode */ printf("\n\nOz Directory Data..."); dir_in_location = partition_start + (inode.i_block[0] * 2); dir_count = printDirs(fd, dir_in_location); /* Read the ohmy.txt inode */ inode_num = 4021; inode = getInode(fd, inode_num, groupdescriptors, partition_start, superblock.s_inodes_per_group); printf("\n\nohmy.txt Inode Data Blocks: %d", inode.i_blocks); /* See if ohmy.txt's blocks are allocated */ if (checkBlockAllocation(fd, inode.i_block, groupdescriptors, partition_start, superblock.s_blocks_per_group, superblock.s_inodes_per_group) == 1) { printf("\nAll Blocks Allocated"); } else { printf("\nNot All Blocks Allocated"); } /* Read the glinda inode */ inode_num = 30; inode = getInode(fd, inode_num, groupdescriptors, partition_start, superblock.s_inodes_per_group); printf("\n\nglinda Inode File Mode: "); printFileMode(inode.i_mode); printf("\nglinda Link: "); printFastSymbolic(fd, inode_num, inode.i_size, groupdescriptors, partition_start, superblock.s_inodes_per_group); close(fd); return 0; }
void Database::traverseFiles(string dirpath) { DIR * dir= opendir(dirpath.c_str()); if(!dir) { Error::ret("opendir"); return; } if (dirpath.back() != '/') { dirpath += "/"; } struct dirent* e; while( (e = readdir(dir)) ) { if(e->d_type == 4 && strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { traverseFiles(dirpath + e->d_name); } else if(e->d_type == 8) { string filepath = dirpath + e->d_name; string inode = getInode(filepath.c_str()); cout << "\n\nmd5sum: " << filepath << " ..." << endl; string md5str = md5sum(filepath.c_str()); string sizestr = getFilesize(filepath); cout << "filepath: " << filepath << "md5str: " << md5str << "sizestr: " << sizestr << endl; string ghostfilename; ghostfilename += getCurrentTime(); ghostfilename += "_" + md5str + "_"; ghostfilename += e->d_name; string ghostPath = GHOSTDIR + ghostfilename; if (!md5str.empty() && !sizestr.empty()) { std::map<string, string> selectParamMap = { {"MD5SUM", md5str} }; if (select("file", selectParamMap)) { vector< map<string ,string> > resultMapVector = getResult(); if (resultMapVector.empty()) { std::map<string, string> insertParamMap = { {"MD5SUM", md5str}, {"MD5RAND", "NULL"}, {"ABSPATH", ghostPath}, {"FILENAME", ghostfilename}, {"INODE", inode}, {"SIZE", sizestr} }; if (insert("file", insertParamMap)) { Error::msg("Success: insert new file MD5SUM"); if (link(filepath.c_str(), ghostPath.c_str()) < 0) { Error::ret("\033[31mlink\033[0m"); cerr << filepath << ":" << ghostPath << endl; } } else { Error::msg("\033[31mDatabase insert error\033[0m"); } } else { Error::msg("\033[31mMD5SUM already exist\033[0m"); printResult(); } } else { Error::msg("\033[31mDatabase select error\033[0m"); } } } } closedir(dir); }
int main(){ FileSystem fs; size_type size = 0x7FFFFFF; printf("system size set to: %ld\n", size); initFS(size, 20, &fs); loadFS(&fs); printFileSystem(&fs); // printDisk(&(fs.disk_emulator), 0); Inode inode; size_type inode_id = ROOT_INODE_ID; if(getInode(&fs, &inode_id, &inode)!=Success){ printf("[Potato mount] Error: root directory not exist.\n"); //return Err_GetInode; return -1; } //allocate a block to root directory size_type block_id; allocBlock(&fs, &block_id); inode.fileType = Directory; size_type i = 0; for(i=0; i<DIRECT_BLOCK_NUM; i++){ inode.directBlock[i] = -1; } inode.singleBlock = -1; inode.doubleBlock = -1; inode.tripleBlock = -1; inode.directBlock[0] = block_id; inode.used = true; strcpy(inode.fileOwner, "NULL"); inode.fileModifiedTime = time(NULL); inode.fileAccessTime = time(NULL); inode.inodeModifiedTime = time(NULL); inode.Permission = S_IFDIR | 0755; DirEntry dir_entry[2]; strcpy(dir_entry[0].key, "."); dir_entry[0].inodeId = ROOT_INODE_ID; strcpy(dir_entry[1].key, ".."); dir_entry[1].inodeId = ROOT_INODE_ID; BYTE* buf = malloc(BLOCK_SIZE); memcpy(buf, dir_entry, sizeof(dir_entry)); put(&fs, block_id + fs.super_block.firstDataBlockId, buf); inode.fileSize = sizeof(dir_entry); //for . and .. inode.numOfLinks = 2; ErrorCode err = putInode(&fs, &inode_id, &inode); if(err != Success){ printf("put root failed: Error %d", err); } Inode cur_inode; getInode(&fs, &inode_id, &cur_inode); printf("inode links: %ld\n", cur_inode.numOfLinks); printDisk(&(fs.disk_emulator), 1); //put free list buf into disk put(&fs, fs.super_block.pDataFreeListHead + fs.super_block.firstDataBlockId, &(fs.dataBlockFreeListHeadBuf)); put(&fs, fs.super_block.pDataFreeListTail + fs.super_block.firstDataBlockId, &(fs.dataBlockFreeListTailBuf)); SuperBlockonDisk super_block_on_disk; mapSuperBlockonDisk(&(fs.super_block), &(super_block_on_disk)); memcpy(buf, &super_block_on_disk, sizeof(SuperBlockonDisk)); put(&fs, SUPER_BLOCK_OFFSET, buf); //set root acess time free(buf); closefs(&fs); FileSystem new_fs; loadFS(&new_fs); // printFileSystem(&new_fs); getInode(&new_fs, &inode_id, &cur_inode); printf("inode links: %ld\n", cur_inode.numOfLinks); closefs(&fs); return 0; }
void init_fs() { char block[512] = {0}; useSector(0, block, READ,1); if ( *((int*)block) == 0x12345678 ) { //printSomewhere(300, "POR ACA"); root = kmalloc(sizeof(ENTRY)); strcpy(root->name, "/"); root->inodeNumber = 0; root->link = 0; int i; for ( i = 5 ; i < 2048 ; i++ ) { INODE * inodeAux = getInode(i-5); freeInodes[i-5] = inodeAux->attributes.free; free(inodeAux); } return; } *((int*)block) = 0x12345678; ENTRY rootEntry; strcpy(rootEntry.name , "/"); rootEntry.inodeNumber = 0; rootEntry.link = 0; memcpy( block + sizeof(int), (char*)&rootEntry, sizeof(ENTRY)); useSector(0, block, WRITE, 1); /*sete mapa d bits*/ int i; char mapBlock[4*512]; for ( i = 1 ; i < 4*512 ; i++ ) { mapBlock[i] = 0xFF; } mapBlock[0] = 0x7F; setBitMap(mapBlock); INODE inode; inode.attributes.free = 1; inode.blocks[0] = -1; for ( i = 5 ; i < 2048 ; i++ ) { if ( i == 5 ) { INODE rootInode; rootInode.blocks[0] = 0; rootInode.blocks[1] = -1; rootInode.attributes.prev_version = -1; rootInode.attributes.parentDir = 0; int seconds = _clock(0); rootInode.attributes.creation_time.seconds = ((seconds&0xF0) >> 4) * 10 + (seconds&0x0F); int minutes = _clock(2); rootInode.attributes.creation_time.minutes = ((minutes&0xF0) >> 4) * 10 + (minutes&0x0F); int hours = _clock(4); rootInode.attributes.creation_time.hours = ((hours&0xF0) >> 4) * 10 + (hours&0x0F); int day = _clock(7); rootInode.attributes.creation_time.day = ((day&0xF0) >> 4) * 10 + (day&0x0F); int month = _clock(8); rootInode.attributes.creation_time.month = ((month&0xF0) >> 4) * 10 + (month&0x0F); int year = _clock(9); rootInode.attributes.creation_time.year = ((year&0xF0) >> 4) * 10 + (year&0x0F); strcpy(rootInode.attributes.name , "/"); rootInode.attributes.size = 3 * sizeof(ENTRY); rootInode.attributes.free = 0; rootInode.attributes.alive = 1; char buffer[512] = {0}; memcpy(buffer, (char*)&rootInode, 512); useSector(5, buffer, WRITE, 1); } else {
/* Parsea el path y me mallokea un Entry con el name y inode Number correspondiente. Si no existia, dir sera null */ static void setEntry( char * path, ENTRY * dir, int flag) { //printf("SETTING ENTRY\n"); char ** aux; if ( !strcmp(path, "/") ) { memcpy((char*)dir, (char*)root, sizeof(ENTRY)); return; } if ( !strcmp(path, "") ) { ENTRY nothing; strcpy(nothing.name, ""); memcpy( (char*) dir, (char*) ¬hing, sizeof(ENTRY) ); return; } int size; aux = split(path, '/', &size); ENTRY * current = kmalloc(sizeof(ENTRY)); int i; int start = 1; if ( !strcmp(aux[0], "") ) { memcpy( (char*)current, (char*)root, sizeof(ENTRY)); } else { if ( !strcmp(aux[0], ".") ) { memcpy( (char*)current, (char*)&(currentProc->tty->cwd), sizeof(ENTRY)); } else if ( !strcmp(aux[0], "..") ) { memcpy( (char*)current, (char*)&(currentProc->tty->pcwd), sizeof(ENTRY)); } else { /* memcpy( (char*)current, (char*)&(currentProc->tty->cwd), sizeof(ENTRY)); int xx; for ( xx = strlen(path) ; xx >= 0 ; xx-- ) { path[xx+2] = path[xx]; } path[0] = '.'; path[1] = '/'; start = 0;*/ ENTRY nothing; strcpy(nothing.name, ""); memcpy( (char*) dir, (char*) ¬hing, sizeof(ENTRY) ); free(current); for ( i = 0 ; i < size ; i++ ) { free(aux[i]); } free(aux); return; } } //printf("seteado el start\n"); int exists = 1; i = start; while( i < size && exists) { //printf("I = %d\n", i); int j, fd; fd = popen(current->inodeNumber); ENTRY currentEntry; for ( j = 0 ; read(fd, ¤tEntry, sizeof(ENTRY)) == sizeof(ENTRY) ; j++ ) { //printf("ENTRY {%s, %d}\n", currentEntry.name, currentEntry.inodeNumber); if ( !strcmp(currentEntry.name, "") ) { exists = 0; break; } //printf("GETTING INODE %d\n", currentEntry.inodeNumber); INODE * auxInode = getInode(currentEntry.inodeNumber); //printf("GET INODE\n"); if ( auxInode->attributes.alive || flag ) { if ( !strcmp(currentEntry.name, aux[i]) ) { *current = currentEntry; free(auxInode); break; } } free(auxInode); } close(fd); i++; } //printf("POR AQUI %d\n", size); for ( i = 0 ; i < size ; i++ ) { free(aux[i]); } //printf("LIBERADO AUX[i -> AUX = %d]\n", aux); free(aux); //printf("LIBERADO AUX\n"); if ( !exists ) { //printf("CPIANDO\n"); strcpy(current->name, ""); //printf("COPIADO\n"); } memcpy((char*)dir, (char*)current, sizeof(ENTRY)); free(current); //printf("TERMINO SET ENTRY\n"); }
/** * @brief * open directory and read readdir. than do another readdir, where the next direntry is in * an triple entry. should succeed * @return 1 if successful, 0 otherwise */ error_t readdirTest5(){ uint8_t *dir = "/", *file = "/file1"; NANDFS_DIR *ds; nandfs_dirent* de; dirent_flash *de_flash; inode_t *ino_ptr = CAST_TO_INODE(fs_buffer); int32_t offset, f_id = 2, f_type = FTYPE_FILE; INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(entries_addr); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(indirect_addr); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(double_addr); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(triple_addr); INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(root_addr); bool_t cpWritten; user_id uid = 1; /* verify we can write to triple offset*/ if(FS_MAX_FILESIZE < TRIPLE_DATA_OFFSET){ return 1; } SET_CURRENT_USER(uid); init_logical_address(entries_addr); init_logical_address(indirect_addr); init_logical_address(double_addr); init_logical_address(triple_addr); init_logical_address(root_addr); /* write entries block*/ init_fsbuf(fs_buffer); de_flash = CAST_TO_DIRENT(fs_buffer); DIRENT_SET_INO_NUM(de_flash, f_id); DIRENT_SET_LEN(de_flash, calcNameLen(file)); DIRENT_SET_NAME(de_flash, file); DIRENT_SET_TYPE(de_flash, f_type); VERIFY(!allocAndWriteBlock(entries_addr, fs_buffer, 0, entries_addr, &cpWritten, fsCheckpointWriter, 0)); /* write indirect block */ init_fsbuf(fs_buffer); BLOCK_SET_INDEX(fs_buffer, 0, entries_addr); VERIFY(!allocAndWriteBlock(indirect_addr, fs_buffer, 0, entries_addr, &cpWritten, fsCheckpointWriter, 0)); /* write double block */ init_fsbuf(fs_buffer); BLOCK_SET_INDEX(fs_buffer, 0, indirect_addr); VERIFY(!allocAndWriteBlock(double_addr, fs_buffer, 0, entries_addr, &cpWritten, fsCheckpointWriter, 0)); /* write double block */ init_fsbuf(fs_buffer); BLOCK_SET_INDEX(fs_buffer, 0, double_addr); VERIFY(!allocAndWriteBlock(triple_addr, fs_buffer, 0, entries_addr, &cpWritten, fsCheckpointWriter, 0)); /* write to root inode */ VERIFY(!getInode(fs_buffer, 1, root_addr)); INODE_SET_TRIPLE(ino_ptr, triple_addr); init_logical_address(root_addr); VERIFY(!allocAndWriteBlock(root_addr, fs_buffer, 0, entries_addr, &cpWritten, fsCheckpointWriter, 0)); /* change inode0*/ fsReadBlockSimple(FS_GET_INO0_ADDR_PTR(), fs_buffer); INODE_SET_DIRECT(ino_ptr, 0, root_addr); VERIFY(!allocAndWriteBlock(FS_GET_INO0_ADDR_PTR(), fs_buffer, 0, entries_addr, &cpWritten, fsCheckpointWriter, 0)); /* open directory and start reading */ ds = opendir(dir); VERIFY(!IS_NULL(ds)); /* read "."*/ de = readdir(ds); VERIFY(!IS_NULL(de)); /* read ".."*/ de = readdir(ds); VERIFY(!IS_NULL(de)); /* read file entry */ de = readdir(ds); VERIFY(!IS_NULL(de)); de_flash = CAST_TO_DIRENT(de); // PRINT("\nverify 3rd readdir success"); VERIFY(verifyDirenty(de_flash, f_id, f_type, calcNameLen(file), file)); // PRINT("\n3rd direntry success"); // PRINT("\ndirentry 1 success"); offset = TRIPLE_DATA_OFFSET+DIRENT_GET_LEN(de_flash); // PRINT_MSG_AND_NUM("\nexpeted offset=", offset); // PRINT_MSG_AND_NUM(" actual offset=", OPEN_FILE_GET_OFFSET(DS_GET_FD_BY_PTR(ds))); VERIFY(COMPARE(offset, OPEN_FILE_GET_OFFSET(DS_GET_FD_BY_PTR(ds)))); /* verify no more entries*/ de = readdir(ds); VERIFY(IS_NULL(de)); return 1; }
void SrvDTP::insertNewFileMD5SUM(const char * pathname, Database *pdb) { string inode = getInode(pathname); cout << "md5sum computing... " << endl; string md5str = md5sum(pathname); string sizestr = getFilesize(string(pathname)); cout << "insertNewFileMD5SUM # filepath: " << pathname << "md5str: " << md5str << "sizestr: " << sizestr << endl; string ghostfilename; ghostfilename += getCurrentTime(); ghostfilename += "_" + md5str + "_"; ghostfilename += psrvPI->getFilename(); string ghostPath = GHOSTDIR + ghostfilename; if (!md5str.empty() && !sizestr.empty()) { std::map<string, string> selectParamMap = { {"MD5SUM", md5str} }; if (pdb->select("file", selectParamMap)) { vector< map<string ,string> > resultMapVector = pdb->getResult(); if (resultMapVector.empty()) { std::map<string, string> insertParamMap = { {"MD5SUM", md5str}, {"MD5RAND", "NULL"}, {"ABSPATH", ghostPath}, {"FILENAME", ghostfilename}, {"INODE", inode}, {"SIZE", sizestr} }; if (pdb->insert("file", insertParamMap)) { Error::msg("Success: insert new file MD5SUM"); if (link(pathname, ghostPath.c_str()) < 0) { Error::ret("\033[31mlink\033[0m"); cerr << pathname << ":" << ghostPath << endl; } } else { Error::msg("\033[31mDatabase insert error\033[0m"); } } else { Error::msg("\033[31mThis MD5SUM already exists\033[0m"); /*std::map<string, string> whereParamMap = { {"MD5SUM", md5sum(pathname)} }; std::map<string, string> updateParamMap = { {"VALID", "1"} }; if (pdb->update("file", whereParamMap, updateParamMap)) { vector< map<string ,string> > resultMapVector = pdb->getResult(); if (!resultMapVector.empty()) { printf("Success: update VALID=1\n"); } else { printf("update: not find record\n"); } } else { Error::msg("\033[31mDatabase update error\033[0m"); }*/ } } else { Error::msg("\033[31mDatabase select error\033[0m"); } } }
void SrvDTP::sendFile(const char *pathname, uint32_t nslice, uint32_t sindex, uint16_t slicecap) { //cout << endl << endl << pathname << endl << endl; Packet & packet = *(this->ppacket); char buf[MAXLINE]; Database * pdb = psrvPI->getPDB(); string inode = getInode(pathname); std::map<string, string> selectParamMap = { {"INODE", inode} }; if (pdb->select("file", selectParamMap)) { vector< map<string ,string> > resultMapVector = pdb->getResult(); if (!resultMapVector.empty()) { string dbAccess = resultMapVector[0]["ACCESS"]; unsigned long long access = std::stoull(dbAccess) + 1; snprintf(buf, MAXLINE, "%llu", access); dbAccess = buf; std::map<string, string> updateParamMap = { {"ACCESS", dbAccess} }; if (pdb->update("file", resultMapVector[0]["ID"], updateParamMap)) { cout << "update ACCESS+1 ok" <<endl; } else { printf("\033[31mupdate ACCESS+1 error\033[0m\n"); } } else { printf("\033[31mINODE not exist\033[0m\n"); } } else { Error::msg("\033[31mDatabase select error\033[0m\n"); } int n; //uint32_t nslice =0, sindex = 0; // off64_t curpos = sindex * slicecap; // if ( lseek64(fileno(psrvPI->getFp()), curpos, SEEK_SET) < 0) // { // packet.sendSTAT_ERR(strerror_r(errno, buf, MAXLINE)); // return; // } else { // printf("Recv file [%s %u/%u] now\n", pathname, sindex, nslice); // // send STAT_OK // packet.sendSTAT_OK(); // } string sizestr = getFilesize(string(pathname)); if (sizestr.empty()) { packet.sendSTAT_ERR("getFilesize() failed"); return; } // confirm enough space to write on client host packet.sendSTAT(STAT_SIZE, sizestr); psrvPI->recvOnePacket(); if (packet.getTagid() == TAG_STAT && packet.getStatid() == STAT_ERR) { return; } else if (packet.getTagid() == TAG_STAT && packet.getStatid() == STAT_OK) { ; } else { Error::msg("unknown packet"); packet.print(); return; } //if ( (fp = fopen(pathname, "rb")) == NULL) if ( psrvPI->setFp(fopen(pathname, "rb")) == NULL) { // send STAT_ERR Response // GNU-specific strerror_r: char *strerror_r(int errnum, char *buf, size_t buflen); packet.sendSTAT_ERR(strerror_r(errno, buf, MAXLINE)); return; } else if ( (n = getFileNslice(pathname, &nslice)) <= 0) { if ( n == 0) { printf("EOF[%s]: 0 bytes\n", pathname); Fclose(&psrvPI->getFp()); packet.sendSTAT_OK(); packet.sendDATA_TEXT(getFileSizeString(pathname)); packet.sendDATA_FILE(0, 0, 0, NULL); packet.sendSTAT_EOF("EOF: 0 bytes"); return; } else if ( n == -2) { snprintf(buf, MAXLINE, "Too large file size"); packet.sendSTAT_ERR(buf); } else { snprintf(buf, MAXLINE, "File stat error"); packet.sendSTAT_ERR(buf); } return; } else { // send STAT_OK packet.sendSTAT_OK(); } packet.sendDATA_TEXT(getFileSizeString(pathname)); char body[PBODYCAP]; printf("Send [%s] now\n", pathname); while( (n = fread(body, sizeof(char), PBODYCAP, psrvPI->getFp())) >0 ) { packet.sendDATA_FILE(nslice, ++sindex, n, body); } // send EOF Fclose(&psrvPI->getFp()); printf("EOF [%s]\n", pathname); packet.sendSTAT_EOF(); }
LinnFileSystem::LinnFileSystem(const char *p, Storage *s) : FileSystem(p), storage(s), groups(ZERO) { LinnInode *rootInode; LinnGroup *group; Size offset; Error e; /* Open the system log. */ openlog("LinnFS", LOG_PID, LOG_USER); /* Read out the superblock. */ if ((e = s->read(LINN_SUPER_OFFSET, &super, sizeof(super))) <= 0) { syslog(LOG_ERR, "reading superblock failed: %s", strerror(e)); exit(EXIT_FAILURE); } /* Verify magic. */ if (super.magic0 != LINN_SUPER_MAGIC0 || super.magic1 != LINN_SUPER_MAGIC1) { syslog(LOG_ERR, "magic mismatch"); exit(EXIT_FAILURE); } /* Create groups vector. */ groups = new Vector<LinnGroup *>(LINN_GROUP_COUNT(&super)); groups->fill(ZERO); /* Read out group descriptors. */ for (Size i = 0; i < LINN_GROUP_COUNT(&super); i++) { /* Allocate buffer. */ group = new LinnGroup; offset = (super.groupsTable * super.blockSize) + (sizeof(LinnGroup) * i); /* Read from storage. */ if ((e = s->read(offset, group, sizeof(LinnGroup))) <= 0) { syslog(LOG_ERR, "reading group descriptor failed: %s", strerror(e)); exit(EXIT_FAILURE); } /* Insert in the groups vector. */ groups->insert(i, group); } syslog(LOG_INFO, "%d group descriptors", LINN_GROUP_COUNT(&super)); /* Print out superblock information. */ syslog(LOG_INFO, "%d inodes, %d blocks", super.inodesCount - super.freeInodesCount, super.blocksCount - super.freeBlocksCount); /* Read out the root directory. */ rootInode = getInode(LINN_INODE_ROOT); setRoot(new LinnDirectory(this, rootInode)); /* Done. */ syslog(LOG_INFO, "mounted as '%s'", p); }
ErrorCode allocInode(FileSystem* fs, size_type* inodeId, Inode* inode) { //Input is FileSystem* fs //WARNING: the caller should define an Inode and use the pointer of that Inode as input to this function //If successful, Inode* inode will have inode information according to size_type* inodeId //If falied, inodeId and inode will point to nowhere SuperBlock* super = &(fs->super_block); if (getFreeListNum(super) > 0){//there are free inodes in the free inodes list cache //assign free inode Id *inodeId = super->freeInodeList[super->freeInodeIndex]; //update superblock information //freeInodeList[super->freeInodeIndex]=-1 means this item is used super->freeInodeList[super->freeInodeIndex]=-1; super->numOfFreeInodes--; super->freeInodeIndex--; super->modified = true; PrintInfo(super, inodeId); if (super->freeInodeIndex==-1){ printf("[Allocate Inode] Free Inodes List Is Empty #>.<#\n"); } ErrorCode err_getInode=getInode(fs, inodeId, inode); if (err_getInode==Success){ printf("[Allocate Inode] Get Inode Successful!\n"); ErrorCode err_InitInode=InitInode(inode); if (err_InitInode==Success){ printf("[Allocate Inode] Initialize Inode Successful!\n"); ErrorCode err_putInode=putInode(fs, inodeId, inode); if (err_putInode==Success){ printf("[Allocate Inode] Allocate Inode Successful!\n"); return Success; } else{ printf("[Allocate Inode] Failure to Put Inode\n"); return err_putInode; } } else{ printf("[Allocate Inode] Failure to Initialize Inode\n"); return err_InitInode; } } else{ printf("[Allocate Inode] Falied to Get Inode\n"); return err_getInode; } } else{//there are no free inodes in the free inodes list cashe, need to garbage collection of the free inodes list cache //before garbage collection, we need to shift super->freeInodeIndex to the right index ErrorCode err_garbcollectInode = garbcollectInode(fs); super->freeInodeIndex = FREE_INODE_NUM - 1; if (err_garbcollectInode==Success){ //assign free inode Id *inodeId = super->freeInodeList[super->freeInodeIndex]; //update superblock information //freeInodeList[super->freeInodeIndex]=-1 means this item is used super->freeInodeList[super->freeInodeIndex]=-1; super->numOfFreeInodes--; super->freeInodeIndex--; super->modified = true; PrintInfo(super, inodeId); ErrorCode err_getInode=getInode(fs, inodeId, inode); if (err_getInode==Success){ printf("[Allocate Inode] Get Inode Successful!\n"); ErrorCode err_InitInode=InitInode(inode); if (err_InitInode==Success){ printf("[Allocate Inode] Initialize Inode Successful!\n"); ErrorCode err_putInode=putInode(fs, inodeId, inode); if (err_putInode==Success){ printf("[Allocate Inode] Allocate Inode Successful!\n"); return Success; } else{ printf("[Allocate Inode] Failure to Put Inode\n"); return err_putInode; } } else{ printf("[Allocate Inode] Failure to Initialize Inode\n"); return err_InitInode; } } else{ printf("[Allocate Inode] Falied to Get Inode\n"); return err_getInode; } } else{ printf("[Allocate Inode] After Garbage Collection, Failed to Allocate New Inode\n"); return err_garbcollectInode; } } }