Exemple #1
0
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;
}