TFS文件系统数据服务器启动加载分析
TFS文件系统的数据服务器在启动时会有加载超级块,加载文件块的操作,可以对照代码,
做下分析.
(1). 启动加载
int BlockFileManager::bootstrap(const SysParam::FileSystemParam& fs_param) { //装载超级块 int ret = load_super_blk(fs_param); if (TFS_SUCCESS != ret){ return ret; } //装载块文件 return load_block_file(); } |
(2). 装载超级块
//加载超级块 int BlockFileManager::load_super_blk(const SysParam::FileSystemParam& fs_param) { bool fs_init_status = true; //reserve:储备,mount:安装 TBSYS_LOG(INFO, "read super block. mount name: %s, offset: %d/n", fs_param.mount_name_.c_str(),fs_param.super_block_reserve_offset_); //会去读取超级块存成的文件 super_block_impl_ = new SuperBlockImpl(fs_param.mount_name_, fs_param.super_block_reserve_offset_); int ret = super_block_impl_->read_super_blk(super_block_); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "read super block error. ret: %d, desc: %s/n", ret, strerror(errno)); return ret; } //在检查超级块的状态:是否是DEV_TAG="TAOBAO" if (!super_block_impl_->check_status(DEV_TAG, super_block_)) { fs_init_status = false; } //接上面的判断是否进行了文件系统格式化 if (!fs_init_status) { TBSYS_LOG(ERROR, "file system not inited. please format it first./n"); return EXIT_FS_NOTINIT_ERROR; } //假定主块是,扩展块是,在接着依据这个条件展开 //计算项目个数=主块数+扩展块数+1=9+3+1=13 unsigned item_count = super_block_.main_block_count_ + super_block_.extend_block_count_ + 1; TBSYS_LOG(INFO, "file system bitmap size: %u/n", item_count); normal_bit_map_ = new BitMap(item_count); error_bit_map_ = new BitMap(item_count); //那么这个时候bit_map_size_=2 bit_map_size_ = normal_bit_map_->get_slot_count(); //假定分配个字节的缓冲 char* tmp_bit_map_buf = new char[4 * bit_map_size_]; memset(tmp_bit_map_buf, 0, 4 * bit_map_size_); ret = super_block_impl_->read_bit_map(tmp_bit_map_buf, 4 * bit_map_size_); if (TFS_SUCCESS != ret) { tbsys::gDeleteA(tmp_bit_map_buf); return ret; } // 连续对前面四个小段进行比较:因为是* bit_map_size_ // 先比较前面两个,在比较后面两个 if (memcmp(tmp_bit_map_buf, tmp_bit_map_buf + bit_map_size_, bit_map_size_) != 0) { tbsys::gDeleteA(tmp_bit_map_buf); TBSYS_LOG(ERROR, "normal bitmap conflict"); //位图有冲突 return EXIT_BITMAP_CONFLICT_ERROR; } if (memcmp(tmp_bit_map_buf + 2 * bit_map_size_, tmp_bit_map_buf + 3 * bit_map_size_, bit_map_size_) != 0) { tbsys::gDeleteA(tmp_bit_map_buf); TBSYS_LOG(ERROR, "error bitmap conflict"); return EXIT_BITMAP_CONFLICT_ERROR; } //在装载位图:bit_map_size_=2 tmp_bit_map_buf=4*2=8,分两段,前面一段是普通位图,后面一段是错误位图 normal_bit_map_->copy(bit_map_size_, tmp_bit_map_buf); error_bit_map_->copy(bit_map_size_, tmp_bit_map_buf + 2 * bit_map_size_); //计算位图使用的个数 TBSYS_LOG(DEBUG, "bitmap used count: %u, error: %u", normal_bit_map_->get_set_count(),error_bit_map_->get_set_count()); tbsys::gDeleteA(tmp_bit_map_buf); return TFS_SUCCESS; } |
(3)SuperBlockImpl类
//flag默认值是true,slave:附件 SuperBlockImpl::SuperBlockImpl(const std::string& mount_name, const int32_t super_start_offset, const bool flag) : super_reserve_offset_(super_start_offset) { //dir if (true == flag) { //比如mount_name=/data/tfs1,那么super_block_file_=/data/tfs1/fs_super super_block_file_ = mount_name + SUPERBLOCK_NAME; ///SUPERBLOCK_NAME: /fs_super } else { super_block_file_ = mount_name; } //bitmap起始偏移量=超级快存储偏移量+2个超级块大小+一个整形大小 bitmap_start_offset_ = super_reserve_offset_ + 2 * sizeof(SuperBlock) + sizeof(int); //superblock file is already exist //已经确定了超级块的文件名 file_op_ = new FileOperation(super_block_file_, O_RDWR | O_SYNC); if (NULL == file_op_) { assert(false); } } |
int SuperBlockImpl::read_super_blk(SuperBlock& super_block) const { memset(&super_block, 0, sizeof(SuperBlock)); //super_reserve_offset_:读位置的偏移量 return file_op_->pread_file((char*) (&super_block), sizeof(SuperBlock), super_reserve_offset_); } |
int SuperBlockImpl::write_super_blk(const SuperBlock& super_block) { //内存拷贝两个超级块 char* tmp_buf = new char[2 * sizeof(SuperBlock)]; memcpy(tmp_buf, &super_block, sizeof(SuperBlock)); memcpy(tmp_buf + sizeof(SuperBlock), &super_block, sizeof(SuperBlock)); int ret = file_op_->pwrite_file(tmp_buf, 2 * sizeof(SuperBlock), super_reserve_offset_); tbsys::gDeleteA(tmp_buf); |