int OssFS::readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fileInfo) { log_debug("path:%s", path); (void) offset; (void) fileInfo; //先准备两个子目录, 当前子目录和上级目录 filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); OssObject *pTargetDir = NULL; OSS_OBJS_MAP *target_dir = NULL; string Prefix; const char *pDelimiter = "/"; if (strcmp(path, "/") == 0) { //根目录不需要设置Prefix Prefix = ""; } else { //非根目录, prefix组装形式为fun/模式 Prefix = (path+1); Prefix = Prefix + "/"; } pTargetDir = get_file(path); target_dir = pTargetDir->get_subs(); int is_syncd = 0; //检查同步时间配置, 如果时间间隔不为0, 则按照配置进行文件夹访问时间刷新 if (AliConf::ONLINE_SYNC_CYCLE != 0) { //pTargetDir是当前要读取的目录对象, 判断当前操作与上一次操作的时间间隔 OssStats *pStat = (OssStats *)pTargetDir->get_stats(); time_t current_time = time(0); vector<oss_object_desc_t> object_list; if ((size_t)(current_time - pStat->mtime) > AliConf::ONLINE_SYNC_CYCLE) { size_t sync_flag = pTargetDir->get_sync_flag() + 1; pTargetDir->set_sync_flag(sync_flag); int ret_code = m_oss->get_bucket(AliConf::BUCKET.c_str(), Prefix.c_str(), pDelimiter, object_list); if (ret_code != 0) { //如果向OSS请求更新目录子文件与子目录失败, 记录error日志, 按照已有的缓存数据继续处理 log_error("get_bucket failed"); } else { //更新对象的访问时间 pStat->mtime = current_time; //更新load过来的文件 load_files(object_list, false, pTargetDir->get_sync_flag()); //用于下面函数判断是否进行了一次同步 is_syncd = 1; } } } OssObject* tmpObj; map<const char *, OssObject *>::iterator it; vector<const char *> vecDel; vector<const char *>::iterator vec_iter; //遍历目录的map结构, 启用目录的读锁 ((OssDirObject *)pTargetDir)->rdlock(); for (it = target_dir->begin(); it != target_dir->end(); it++) { tmpObj = it->second; if (1 == is_syncd) { // 本次readdir进行过数据同步 if (tmpObj->get_sync_flag() == pTargetDir->get_sync_flag()) { filler(buf, it->first, NULL, 0); } else { log_debug("file:[%s] need delete.", it->first); vecDel.push_back(it->first); } } else { // 本次readdir没有进行过数据同步, 不需要比较同步flag filler(buf, it->first, NULL, 0); } } //遍历结束, 关闭锁 ((OssDirObject *)pTargetDir)->unlock(); for (vec_iter = vecDel.begin(); vec_iter != vecDel.end(); vec_iter++) { del_file(*vec_iter); } return 0; }