bool FdManager::RawCheckAllCache()

in src/fdcache.cpp [973:1114]


bool FdManager::RawCheckAllCache(FILE* fp, const char* cache_stat_top_dir, const char* sub_path, int& total_file_cnt, int& err_file_cnt, int& err_dir_cnt)
{
    if(!cache_stat_top_dir || '\0' == cache_stat_top_dir[0] || !sub_path || '\0' == sub_path[0]){
        S3FS_PRN_ERR("Parameter cache_stat_top_dir is empty.");
        return false;
    }

    // open directory of cache file's stats
    DIR*   statsdir;
    std::string target_dir = cache_stat_top_dir;
    target_dir       += sub_path;
    if(NULL == (statsdir = opendir(target_dir.c_str()))){
        S3FS_PRN_ERR("Could not open directory(%s) by errno(%d)", target_dir.c_str(), errno);
        return false;
    }

    // loop in directory of cache file's stats
    struct dirent* pdirent = NULL;
    while(NULL != (pdirent = readdir(statsdir))){
        if(DT_DIR == pdirent->d_type){
            // found directory
            if(0 == strcmp(pdirent->d_name, ".") || 0 == strcmp(pdirent->d_name, "..")){
                continue;
            }

            // reentrant for sub directory
            std::string subdir_path = sub_path;
            subdir_path       += pdirent->d_name;
            subdir_path       += '/';
            if(!RawCheckAllCache(fp, cache_stat_top_dir, subdir_path.c_str(), total_file_cnt, err_file_cnt, err_dir_cnt)){
                // put error message for this dir.
                ++err_dir_cnt;
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_DIR_PROB, subdir_path.c_str());
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_CRIT_HEAD, "Something error is occurred in checking this directory");
            }

        }else{
            ++total_file_cnt;

            // make cache file path
            std::string strOpenedWarn;
            std::string cache_path;
            std::string object_file_path = sub_path;
            object_file_path       += pdirent->d_name;
            if(!FdManager::MakeCachePath(object_file_path.c_str(), cache_path, false, false) || cache_path.empty()){
                ++err_file_cnt;
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_PROB, object_file_path.c_str(), strOpenedWarn.c_str());
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_CRIT_HEAD, "Could not make cache file path");
                continue;
            }

            // check if the target file is currently in operation.
            {
                AutoLock auto_lock(&FdManager::fd_manager_lock);

                UpdateEntityToTempPath();
                fdent_map_t::iterator iter = fent.find(object_file_path);
                if(fent.end() != iter){
                    // This file is opened now, then we need to put warning message.
                    strOpenedWarn = CACHEDBG_FMT_WARN_OPEN;
                }
            }

            // open cache file
            int cache_file_fd;
            if(-1 == (cache_file_fd = open(cache_path.c_str(), O_RDONLY))){
                ++err_file_cnt;
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_PROB, object_file_path.c_str(), strOpenedWarn.c_str());
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_CRIT_HEAD, "Could not open cache file");
                continue;
            }

            // get inode number for cache file
            struct stat st;
            if(0 != fstat(cache_file_fd, &st)){
                ++err_file_cnt;
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_PROB, object_file_path.c_str(), strOpenedWarn.c_str());
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_CRIT_HEAD, "Could not get file inode number for cache file");

                close(cache_file_fd);
                continue;
            }
            ino_t cache_file_inode = st.st_ino;

            // open cache stat file and load page info.
            PageList      pagelist;
            CacheFileStat cfstat(object_file_path.c_str());
            if(!cfstat.ReadOnlyOpen() || !pagelist.Serialize(cfstat, false, cache_file_inode)){
                ++err_file_cnt;
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_PROB, object_file_path.c_str(), strOpenedWarn.c_str());
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_CRIT_HEAD, "Could not load cache file stats information");

                close(cache_file_fd);
                continue;
            }
            cfstat.Release();

            // compare cache file size and stats information
            if(st.st_size != pagelist.Size()){
                ++err_file_cnt;
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_PROB, object_file_path.c_str(), strOpenedWarn.c_str());
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_CRIT_HEAD2 "The cache file size(%lld) and the value(%lld) from cache file stats are different", static_cast<long long int>(st.st_size), static_cast<long long int>(pagelist.Size()));

                close(cache_file_fd);
                continue;
            }

            // compare cache file stats and cache file blocks
            fdpage_list_t err_area_list;
            fdpage_list_t warn_area_list;
            if(!pagelist.CompareSparseFile(cache_file_fd, st.st_size, err_area_list, warn_area_list)){
                // Found some error or warning
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_PROB, object_file_path.c_str(), strOpenedWarn.c_str());
                if(!warn_area_list.empty()){
                    S3FS_PRN_CACHE(fp, CACHEDBG_FMT_WARN_HEAD);
                    for(fdpage_list_t::const_iterator witer = warn_area_list.begin(); witer != warn_area_list.end(); ++witer){
                        S3FS_PRN_CACHE(fp, CACHEDBG_FMT_PROB_BLOCK, static_cast<size_t>(witer->offset), static_cast<size_t>(witer->bytes));
                    }
                }
                if(!err_area_list.empty()){
                    ++err_file_cnt;
                    S3FS_PRN_CACHE(fp, CACHEDBG_FMT_ERR_HEAD);
                    for(fdpage_list_t::const_iterator eiter = err_area_list.begin(); eiter != err_area_list.end(); ++eiter){
                        S3FS_PRN_CACHE(fp, CACHEDBG_FMT_PROB_BLOCK, static_cast<size_t>(eiter->offset), static_cast<size_t>(eiter->bytes));
                    }
                }
            }else{
                // There is no problem!
                if(!strOpenedWarn.empty()){
                    strOpenedWarn += "\n ";
                }
                S3FS_PRN_CACHE(fp, CACHEDBG_FMT_FILE_OK, object_file_path.c_str(), strOpenedWarn.c_str());
            }
            err_area_list.clear();
            warn_area_list.clear();
            close(cache_file_fd);
        }
    }
    closedir(statsdir);

    return true;
}