static int caching_list_directory(const char *path, dir_entry **list) { pthread_mutex_lock(&dmut); if (!strcmp(path, "/")) path = ""; dir_cache *cw; for (cw = dcache; cw; cw = cw->next) if (!strcmp(cw->path, path)) break; if (!cw) { if (!cloudfs_list_directory(path, list)) return 0; cw = new_cache(path); } else if (cache_timeout > 0 && (time(NULL) - cw->cached > cache_timeout)) { if (!cloudfs_list_directory(path, list)) return 0; cloudfs_free_dir_list(cw->entries); cw->cached = time(NULL); } else *list = cw->entries; cw->entries = *list; pthread_mutex_unlock(&dmut); return 1; }
//returns first file entry in linked list. if not in cache will be downloaded. int caching_list_directory(const char* path, dir_entry** list) { debugf(DBG_LEVEL_EXT, "caching_list_directory(%s)", path); pthread_mutex_lock(&dcachemut); bool new_entry = false; if (!strcmp(path, "/")) path = ""; dir_cache* cw; for (cw = dcache; cw; cw = cw->next) { if (cw->was_deleted == true) { debugf(DBG_LEVEL_EXT, KMAG"caching_list_directory status: dir(%s) is empty as cached expired, reload from cloud", cw->path); if (!cloudfs_list_directory(cw->path, list)) debugf(DBG_LEVEL_EXT, KMAG"caching_list_directory status: cannot reload dir(%s)", cw->path); else { debugf(DBG_LEVEL_EXT, KMAG"caching_list_directory status: reloaded dir(%s)", cw->path); //cw->entries = *list; cw->was_deleted = false; cw->cached = time(NULL); } } if (cw->was_deleted == false) { if (!strcmp(cw->path, path)) break; } } if (!cw) { //trying to download this entry from cloud, list will point to cached or downloaded entries if (!cloudfs_list_directory(path, list)) { //download was not ok pthread_mutex_unlock(&dcachemut); debugf(DBG_LEVEL_EXT, "exit 0: caching_list_directory(%s) "KYEL"[CACHE-DIR-MISS]", path); return 0; } debugf(DBG_LEVEL_EXT, "caching_list_directory: new_cache(%s) "KYEL"[CACHE-CREATE]", path); cw = new_cache(path); new_entry = true; } else if (cache_timeout > 0 && (time(NULL) - cw->cached > cache_timeout)) { if (!cloudfs_list_directory(path, list)) { //mutex unlock was forgotten pthread_mutex_unlock(&dcachemut); debugf(DBG_LEVEL_EXT, "exit 1: caching_list_directory(%s)", path); return 0; } //fixme: this frees dir subentries but leaves the dir parent entry, this confuses path_info //which believes this dir has no entries if (cw->entries != NULL) { cloudfs_free_dir_list(cw->entries); cw->was_deleted = true; cw->cached = time(NULL); debugf(DBG_LEVEL_EXT, "caching_list_directory(%s) "KYEL"[CACHE-EXPIRED]", path); } else { debugf(DBG_LEVEL_EXT, "got NULL on caching_list_directory(%s) "KYEL"[CACHE-EXPIRED w NULL]", path); pthread_mutex_unlock(&dcachemut); return 0; } } else { debugf(DBG_LEVEL_EXT, "caching_list_directory(%s) "KGRN"[CACHE-DIR-HIT]", path); *list = cw->entries; } //adding new dir file list to global cache, now this dir becomes visible in cache cw->entries = *list; pthread_mutex_unlock(&dcachemut); debugf(DBG_LEVEL_EXT, "exit 2: caching_list_directory(%s)", path); return 1; }