Skip to content

Commit

Permalink
Merge pull request #6 from jmmv/cache-options
Browse files Browse the repository at this point in the history
Make cache parameters configurable
  • Loading branch information
Nikratio committed Feb 16, 2016
2 parents e812e29 + 391f676 commit 451f207
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 22 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Draft notes for upcoming release

* Integrated osxfuse's copy of sshfs, which means that sshfs now works
on OS X out of the box.
* Added -o cache_max_size=N option to let users tune the maximum size of
the cache in number of entries.
* Added -o cache_clean_interval=N and -o cache_min_clean_interval=N
options to let users tune the cleaning behavior of the cache.

Release 2.7 (2015-01-28)
------------------------
Expand Down
55 changes: 33 additions & 22 deletions cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@
#include <glib.h>
#include <pthread.h>

#define DEFAULT_CACHE_TIMEOUT 20
#define MAX_CACHE_SIZE 10000
#define MIN_CACHE_CLEAN_INTERVAL 5
#define CACHE_CLEAN_INTERVAL 60
#define DEFAULT_CACHE_TIMEOUT_SECS 20
#define DEFAULT_MAX_CACHE_SIZE 10000
#define DEFAULT_CACHE_CLEAN_INTERVAL_SECS 60
#define DEFAULT_MIN_CACHE_CLEAN_INTERVAL_SECS 5

struct cache {
int on;
unsigned stat_timeout;
unsigned dir_timeout;
unsigned link_timeout;
unsigned int stat_timeout_secs;
unsigned int dir_timeout_secs;
unsigned int link_timeout_secs;
unsigned int max_size;
unsigned int clean_interval_secs;
unsigned int min_clean_interval_secs;
struct fuse_cache_operations *next_oper;
GHashTable *table;
pthread_mutex_t lock;
Expand Down Expand Up @@ -70,9 +73,9 @@ static int cache_clean_entry(void *key_, struct node *node, time_t *now)
static void cache_clean(void)
{
time_t now = time(NULL);
if (now > cache.last_cleaned + MIN_CACHE_CLEAN_INTERVAL &&
(g_hash_table_size(cache.table) > MAX_CACHE_SIZE ||
now > cache.last_cleaned + CACHE_CLEAN_INTERVAL)) {
if (now > cache.last_cleaned + cache.min_clean_interval_secs &&
(g_hash_table_size(cache.table) > cache.max_size ||
now > cache.last_cleaned + cache.clean_interval_secs)) {
g_hash_table_foreach_remove(cache.table,
(GHRFunc) cache_clean_entry, &now);
cache.last_cleaned = now;
Expand Down Expand Up @@ -172,7 +175,7 @@ void cache_add_attr(const char *path, const struct stat *stbuf, uint64_t wrctr)
if (wrctr == cache.write_ctr) {
node = cache_get(path);
node->stat = *stbuf;
node->stat_valid = time(NULL) + cache.stat_timeout;
node->stat_valid = time(NULL) + cache.stat_timeout_secs;
if (node->stat_valid > node->valid)
node->valid = node->stat_valid;
cache_clean();
Expand All @@ -188,7 +191,7 @@ static void cache_add_dir(const char *path, char **dir)
node = cache_get(path);
g_strfreev(node->dir);
node->dir = dir;
node->dir_valid = time(NULL) + cache.dir_timeout;
node->dir_valid = time(NULL) + cache.dir_timeout_secs;
if (node->dir_valid > node->valid)
node->valid = node->dir_valid;
cache_clean();
Expand All @@ -210,7 +213,7 @@ static void cache_add_link(const char *path, const char *link, size_t size)
node = cache_get(path);
g_free(node->link);
node->link = g_strndup(link, my_strnlen(link, size-1));
node->link_valid = time(NULL) + cache.link_timeout;
node->link_valid = time(NULL) + cache.link_timeout_secs;
if (node->link_valid > node->valid)
node->valid = node->link_valid;
cache_clean();
Expand Down Expand Up @@ -570,20 +573,28 @@ struct fuse_operations *cache_init(struct fuse_cache_operations *oper)
static const struct fuse_opt cache_opts[] = {
{ "cache=yes", offsetof(struct cache, on), 1 },
{ "cache=no", offsetof(struct cache, on), 0 },
{ "cache_timeout=%u", offsetof(struct cache, stat_timeout), 0 },
{ "cache_timeout=%u", offsetof(struct cache, dir_timeout), 0 },
{ "cache_timeout=%u", offsetof(struct cache, link_timeout), 0 },
{ "cache_stat_timeout=%u", offsetof(struct cache, stat_timeout), 0 },
{ "cache_dir_timeout=%u", offsetof(struct cache, dir_timeout), 0 },
{ "cache_link_timeout=%u", offsetof(struct cache, link_timeout), 0 },
{ "cache_timeout=%u", offsetof(struct cache, stat_timeout_secs), 0 },
{ "cache_timeout=%u", offsetof(struct cache, dir_timeout_secs), 0 },
{ "cache_timeout=%u", offsetof(struct cache, link_timeout_secs), 0 },
{ "cache_stat_timeout=%u", offsetof(struct cache, stat_timeout_secs), 0 },
{ "cache_dir_timeout=%u", offsetof(struct cache, dir_timeout_secs), 0 },
{ "cache_link_timeout=%u", offsetof(struct cache, link_timeout_secs), 0 },
{ "cache_max_size=%u", offsetof(struct cache, max_size), 0 },
{ "cache_clean_interval=%u", offsetof(struct cache,
clean_interval_secs), 0 },
{ "cache_min_clean_interval=%u", offsetof(struct cache,
min_clean_interval_secs), 0 },
FUSE_OPT_END
};

int cache_parse_options(struct fuse_args *args)
{
cache.stat_timeout = DEFAULT_CACHE_TIMEOUT;
cache.dir_timeout = DEFAULT_CACHE_TIMEOUT;
cache.link_timeout = DEFAULT_CACHE_TIMEOUT;
cache.stat_timeout_secs = DEFAULT_CACHE_TIMEOUT_SECS;
cache.dir_timeout_secs = DEFAULT_CACHE_TIMEOUT_SECS;
cache.link_timeout_secs = DEFAULT_CACHE_TIMEOUT_SECS;
cache.max_size = DEFAULT_MAX_CACHE_SIZE;
cache.clean_interval_secs = DEFAULT_CACHE_CLEAN_INTERVAL_SECS;
cache.min_clean_interval_secs = DEFAULT_MIN_CACHE_CLEAN_INTERVAL_SECS;
cache.on = 1;

return fuse_opt_parse(args, &cache, cache_opts, NULL);
Expand Down
7 changes: 7 additions & 0 deletions sshfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3377,8 +3377,15 @@ static void usage(const char *progname)
" -o sync_readdir synchronous readdir\n"
" -o sshfs_debug print some debugging information\n"
" -o cache=BOOL enable caching {yes,no} (default: yes)\n"
" -o cache_max_size=N sets the maximum size of the cache (default: 10000)\n"
" -o cache_timeout=N sets timeout for caches in seconds (default: 20)\n"
" -o cache_X_timeout=N sets timeout for {stat,dir,link} cache\n"
" -o cache_clean_interval=N\n"
" sets the interval for automatic cleaning of the\n"
" cache (default: 60)\n"
" -o cache_min_clean_interval=N\n"
" sets the interval for forced cleaning of the\n"
" cache if full (default: 5)\n"
" -o workaround=LIST colon separated list of workarounds\n"
" none no workarounds enabled\n"
" all all workarounds enabled\n"
Expand Down

0 comments on commit 451f207

Please sign in to comment.