int OssFS::del_file(const char *path) { if (strcmp(path, "/") == 0) { return -ENOENT; } OssObject *obj = find_certain_path(path); if (obj == NULL) { return -ENOENT; } //先删除OSS对象 obj->delete_oss_object(); //删除meta_db中的记录 string tmpPath = obj->get_path_name(); cloudfs_sqlite_remove_file_meta(tmpPath); //删除父目录中的记录 OssDirObject *parent_dir = (OssDirObject *)get_parent(path); if (parent_dir != NULL) { parent_dir->remove_record(obj->get_file_name()); } return 0; }
// 下面做的工作就是为每个文件实例化一个相应的类 // 目录文件实例化为 OssDirObject int OssFS::load_files(vector<oss_object_desc_t>& objects, bool initial_load, size_t sync_flag) { std::vector<OssStats *> group_stats; vector<oss_object_desc_t>::iterator iter; OSS_FILE_META meta; OssObject *tmpObj = NULL; for (iter = objects.begin(); iter != objects.end(); iter++) { meta.clear(); convert_object_to_meta(&(*iter), meta); //先检查本该文件是否已经存在, 如果已经存在则不需要加载 //第一次的全量加载不进行本步骤的检查, 提高加载速度 if (!initial_load) { tmpObj = get_file(iter->name.c_str()); if (tmpObj != NULL) { //先判断该文件是否已经被打开读写, 如果已经被打开, 则保持该文件状态不变化 if (tmpObj->is_open()) { log_error("file [%s] is opened, ignore it", iter->name.c_str()); if (sync_flag != 0) { tmpObj->set_sync_flag(sync_flag); } continue; } /* obj可能是目录, 普通文件, 链接文件的任意一种 目录: 设置同步标识, 直接跳过 普通文件与链接文件: 如果文件文件大小不一致, 直接删除cloudfs中的对象, 重新创建一个新的对象 */ OssStats *pTmpStat = const_cast<OssStats *>(tmpObj->get_stats()); if (pTmpStat->type == OSS_DIR) { if (sync_flag != 0) { tmpObj->set_sync_flag(sync_flag); } continue; } else if ((pTmpStat->type == OSS_REGULAR) || (pTmpStat->type == OSS_LINK)) { //后台文件与前台文件一致, 直接continue if (pTmpStat->get_size() == iter->size) { if (sync_flag != 0) { tmpObj->set_sync_flag(sync_flag); } continue; } log_error("file [%s] in OSS size[%zd] is different from cloudfs size[%zd], updating ...", iter->name.c_str(), iter->size, pTmpStat->get_size()); //后台文件与前台文件不一致, 删除前台对象, 后面会重新创建该对象 //删除上层目录表中该对象的信息 OssDirObject * parent_dir = (OssDirObject *)get_parent(iter->name.c_str()); if (parent_dir != NULL) { parent_dir->remove_record(tmpObj->get_file_name()); } else { log_error("file [%s] get parent directory failed", iter->name.c_str()); } } else { log_error("file [%s] invalid object type %zd", iter->name.c_str(), pTmpStat->type); continue; } } } log_debug("file:[%s] need online sync", iter->name.c_str()); group_stats.clear(); OssStats stats = OssStats(meta); if (stats.type == OSS_REGULAR) { log_debug("stats.size:[%d]", stats.size); create_group_stats(stats.size, 0, group_stats); tmpObj = this->add_file(iter->name.c_str(), group_stats, stats.type); //subobject不再需要保存stats, 此处循环释放所有的stat delete_group_stats(group_stats); } //增加对LINK文件的初始化处理 else if (stats.type == OSS_DIR) { tmpObj = this->add_file(iter->name.c_str(), group_stats, stats.type); } else if (stats.type == OSS_LINK) { OssStats *pTmpStat = new OssStats(meta); group_stats.push_back(pTmpStat); tmpObj = this->add_file(iter->name.c_str(), group_stats, stats.type); } else { log_error("invalid stats.type %d", stats.type); } /* 检查add_file的结果, 并设置对应的sync_flag */ if (tmpObj != NULL) { if (sync_flag != 0) tmpObj->set_sync_flag(sync_flag); } } return 0; }
OssObject * OssFS::add_file(const char* path, std::vector<OssStats *> &stats, oss_obj_type_t type) { string filename(path); if (filename.at(0) == '/') filename = filename.substr(1); std::vector < string > paths; split(filename, paths, "/"); log_debug("path:%s, paths.size:%d", path, paths.size()); OssDirObject *root = (OssDirObject *)m_root; OssObject *obj = NULL; oss_obj_type_t tmpType; string tmpFilename; for (size_t i = 0; i < paths.size(); i++) { log_debug("paths[%d]:%s", i, paths[i].c_str()); OssObject * pTmp = root->get_record(paths[i].c_str()); if (i < (paths.size() -1)) { if ((pTmp != NULL) ) { root = (OssDirObject *)pTmp; continue; } else { // 当一个路径中的某个子路径在系统中还没有被创建时 tmpType = OSS_DIR; tmpFilename.clear(); for (size_t j = 0; j <= i; j++) { tmpFilename += paths[j] + "/"; } } } else //i == paths.size() -1 { tmpType = type; tmpFilename.assign(filename); } log_debug("type:%d,filename:%s", tmpType, tmpFilename.c_str()); if (tmpType == OSS_DIR) { OssStats * o_stats = NULL; o_stats = new OssStats(4096, (time(0) - AliConf::ONLINE_SYNC_CYCLE - 2), tmpType); obj = new OssDirObject(this, m_oss, AliConf::BUCKET.c_str(), tmpFilename.c_str(), paths[i].c_str(), o_stats); root->add_record(obj->get_file_name(), obj); root = (OssDirObject *)obj; } else if (tmpType == OSS_REGULAR) { obj = new OssGroupObject(this, m_oss, AliConf::BUCKET.c_str(), tmpFilename.c_str(), paths[i].c_str(), stats); root->add_record(obj->get_file_name(), obj); } else if (tmpType == OSS_LINK) { if (stats.size() != 1) { log_error("symlink stats size error: %d", stats.size()); } OssStats * o_stats = stats[0]; obj = new OssSymObject(this, m_oss, AliConf::BUCKET.c_str(), tmpFilename.c_str(), paths[i].c_str(), o_stats); root->add_record(obj->get_file_name(), obj); } } return obj; }