static int dircache_callback(int action,const struct menu_item_ex *this_item) { (void)this_item; switch (action) { case ACTION_EXIT_MENUITEM: /* on exit */ if (global_settings.dircache && !dircache_is_enabled()) { if (dircache_build(0) < 0) splash(HZ*2, ID2P(LANG_PLEASE_REBOOT)); } else if (!global_settings.dircache && dircache_is_enabled()) { dircache_disable(); } break; } return action; }
static int dircache_callback(int action,const struct menu_item_ex *this_item) { (void)this_item; switch (action) { case ACTION_EXIT_MENUITEM: /* on exit */ switch (global_settings.dircache) { case true: if (!dircache_is_enabled()) splash(HZ*2, ID2P(LANG_PLEASE_REBOOT)); break; case false: if (dircache_is_enabled()) dircache_disable(); break; } break; } return action; }
/* Test file existence, using dircache of possible */ bool file_exists(const char *file) { int fd; #ifdef DEBUG if (!file || !*file) { DEBUGF("%s(%p): Invalid parameter!\n", __func__, file); return false; } #endif #ifdef HAVE_DIRCACHE if (dircache_is_enabled()) return (dircache_get_entry_ptr(file) != NULL); #endif fd = open(file, O_RDONLY); if (fd < 0) return false; close(fd); return true; }
static int open_internal(const char* pathname, int flags, bool use_cache) { DIR_UNCACHED* dir; struct dirent_uncached* entry; int fd; char pathnamecopy[MAX_PATH]; char* name; struct filedesc* file = NULL; int rc; #ifndef HAVE_DIRCACHE (void)use_cache; #endif LDEBUGF("open(\"%s\",%d)\n",pathname,flags); if ( pathname[0] != '/' ) { DEBUGF("'%s' is not an absolute path.\n",pathname); DEBUGF("Only absolute pathnames supported at the moment\n"); errno = EINVAL; return -1; } /* find a free file descriptor */ for ( fd=0; fd<MAX_OPEN_FILES; fd++ ) if ( !openfiles[fd].busy ) break; if ( fd == MAX_OPEN_FILES ) { DEBUGF("Too many files open\n"); errno = EMFILE; return -2; } file = &openfiles[fd]; memset(file, 0, sizeof(struct filedesc)); if (flags & (O_RDWR | O_WRONLY)) { file->write = true; if (flags & O_TRUNC) file->trunc = true; } file->busy = true; #ifdef HAVE_DIRCACHE if (dircache_is_enabled() && !file->write && use_cache) { const struct dircache_entry *ce; # ifdef HAVE_MULTIVOLUME int volume = strip_volume(pathname, pathnamecopy); # endif ce = dircache_get_entry_ptr(pathname); if (!ce) { errno = ENOENT; file->busy = false; return -7; } fat_open(IF_MV2(volume,) ce->startcluster, &(file->fatfile), NULL); file->size = ce->size; file->attr = ce->attribute; file->cacheoffset = -1; file->fileoffset = 0; return fd; } #endif strlcpy(pathnamecopy, pathname, sizeof(pathnamecopy)); /* locate filename */ name=strrchr(pathnamecopy+1,'/'); if ( name ) { *name = 0; dir = opendir_uncached(pathnamecopy); *name = '/'; name++; } else { dir = opendir_uncached("/"); name = pathnamecopy+1; } if (!dir) { DEBUGF("Failed opening dir\n"); errno = EIO; file->busy = false; return -4; } if(name[0] == 0) { DEBUGF("Empty file name\n"); errno = EINVAL; file->busy = false; closedir_uncached(dir); return -5; } /* scan dir for name */ while ((entry = readdir_uncached(dir))) { if ( !strcasecmp(name, entry->d_name) ) { fat_open(IF_MV2(dir->fatdir.file.volume,) entry->startcluster, &(file->fatfile), &(dir->fatdir)); file->size = file->trunc ? 0 : entry->size; file->attr = entry->attribute; break; } }
static int init_dircache(bool preinit) { #ifdef HAVE_DIRCACHE int result = 0; bool clear = false; if (preinit) dircache_init(); if (!global_settings.dircache) return 0; # ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized && firmware_settings.disk_clean && preinit) { result = dircache_load(); if (result < 0) { firmware_settings.disk_clean = false; if (global_status.dircache_size <= 0) { /* This will be in default language, settings are not applied yet. Not really any easy way to fix that. */ splash(0, str(LANG_SCANNING_DISK)); clear = true; } dircache_build(global_status.dircache_size); } } else # endif { if (preinit) return -1; if (!dircache_is_enabled() && !dircache_is_initializing()) { if (global_status.dircache_size <= 0) { splash(0, str(LANG_SCANNING_DISK)); clear = true; } result = dircache_build(global_status.dircache_size); } if (result < 0) { /* Initialization of dircache failed. Manual action is * necessary to enable dircache again. */ splashf(0, "Dircache failed, disabled. Result: %d", result); global_settings.dircache = false; } } if (clear) { backlight_on(); show_logo(); global_status.dircache_size = dircache_get_cache_size(); status_save(); } return result; #else (void)preinit; return 0; #endif }