Add setting to refresh directory contents (#114)

Refresh a directory's contents when fs_readdir is called
if it has been more than the number of seconds specified by
--refresh_timeout since the directory was last indexed.
This commit is contained in:
Mike Morrison 2023-03-31 05:26:15 -07:00 committed by GitHub
parent 9a7016f29b
commit a309994b9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 19 deletions

View File

@ -53,6 +53,8 @@ void Config_init(void)
CONFIG.insecure_tls = 0;
CONFIG.refresh_timeout = DEFAULT_REFRESH_TIMEOUT;
/*--------------- Cache related ---------------*/
CONFIG.cache_enabled = 0;

View File

@ -23,6 +23,11 @@
*/
#define DEFAULT_NETWORK_MAX_CONNS 10
/**
* \brief The default refresh_timeout
*/
#define DEFAULT_REFRESH_TIMEOUT 86400
/**
* \brief Operation modes
*/
@ -67,6 +72,8 @@ typedef struct {
int insecure_tls;
/** \brief Server certificate file */
char *cafile;
/** \brief Refresh directory listing after refresh_timeout seconds*/
int refresh_timeout;
/*--------------- Cache related ---------------*/
/** \brief Whether cache mode is enabled */
int cache_enabled;

View File

@ -44,7 +44,7 @@ static int fs_getattr(const char *path, struct stat *stbuf)
if (!link) {
return -ENOENT;
}
struct timespec spec;
struct timespec spec = {0};
spec.tv_sec = link->time;
#if defined(__APPLE__) && defined(__MACH__)
stbuf->st_mtimespec = spec;
@ -138,15 +138,12 @@ fs_readdir(const char *path, void *buf, fuse_fill_dir_t dir_add,
(void) fi;
LinkTable *linktbl;
if (!strcmp(path, "/")) {
linktbl = ROOT_LINK_TBL;
} else {
linktbl = path_to_Link_LinkTable_new(path);
if (!linktbl) {
return -ENOENT;
}
linktbl = path_to_Link_LinkTable_new(path);
if (!linktbl) {
return -ENOENT;
}
/*
* start adding the links
*/

View File

@ -501,11 +501,15 @@ static void LinkTable_invalid_reset(LinkTable *linktbl)
void LinkTable_free(LinkTable *linktbl)
{
for (int i = 0; i < linktbl->num; i++) {
FREE(linktbl->links[i]);
if (linktbl)
{
for (int i = 0; i < linktbl->num; i++) {
LinkTable_free(linktbl->links[i]->next_table);
FREE(linktbl->links[i]);
}
FREE(linktbl->links);
FREE(linktbl);
}
FREE(linktbl->links);
FREE(linktbl);
}
void LinkTable_print(LinkTable *linktbl)
@ -538,6 +542,10 @@ void LinkTable_print(LinkTable *linktbl)
LinkTable *LinkTable_alloc(const char *url)
{
LinkTable *linktbl = CALLOC(1, sizeof(LinkTable));
linktbl->num = 0;
linktbl->index_time = 0;
linktbl->links = NULL;
/*
* populate the base URL
@ -552,6 +560,7 @@ LinkTable *LinkTable_alloc(const char *url)
LinkTable *LinkTable_new(const char *url)
{
LinkTable *linktbl = LinkTable_alloc(url);
linktbl->index_time = time(NULL);
/*
* start downloading the base URL
@ -733,24 +742,50 @@ LinkTable *LinkTable_disk_open(const char *dirn)
LinkTable *path_to_Link_LinkTable_new(const char *path)
{
Link *link = path_to_Link(path);
LinkTable *next_table = link->next_table;
struct Link *link = NULL, *tmp_link = NULL;
struct Link linkcpy = {0};
LinkTable *next_table = NULL;
if (!strcmp(path, "/")) {
next_table = ROOT_LINK_TBL;
linkcpy = *next_table->links[0];
tmp_link = &linkcpy;
} else {
link = path_to_Link(path);
tmp_link = link;
LinkTable *next_table = link->next_table;
}
if (next_table)
{
time_t time_now = time(NULL);
if (time_now - next_table->index_time > CONFIG.refresh_timeout)
{
// refresh directory contents
LinkTable_free(next_table);
next_table = NULL;
if (link)
link->next_table = NULL;
}
}
if (!next_table) {
if (CONFIG.mode == NORMAL) {
next_table = LinkTable_new(link->f_url);
next_table = LinkTable_new(tmp_link->f_url);
} else if (CONFIG.mode == SONIC) {
if (!CONFIG.sonic_id3) {
next_table = sonic_LinkTable_new_index(link->sonic.id);
next_table = sonic_LinkTable_new_index(tmp_link->sonic.id);
} else {
next_table =
sonic_LinkTable_new_id3(link->sonic.depth,
link->sonic.id);
sonic_LinkTable_new_id3(tmp_link->sonic.depth,
tmp_link->sonic.id);
}
} else {
lprintf(fatal, "Invalid CONFIG.mode\n");
}
}
link->next_table = next_table;
if (link)
link->next_table = next_table;
else
ROOT_LINK_TBL = next_table;
return next_table;
}

View File

@ -33,6 +33,7 @@ typedef enum {
*/
struct LinkTable {
int num;
time_t index_time;
Link **links;
};

View File

@ -201,6 +201,7 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
{ "single-file-mode", required_argument, NULL, 'L' }, /* 22 */
{ "cacert", required_argument, NULL, 'L' }, /* 23 */
{ "proxy-cacert", required_argument, NULL, 'L' }, /* 24 */
{ "refresh-timeout", required_argument, NULL, 'L' }, /* 25 */
{ 0, 0, 0, 0 }
};
while ((c =
@ -304,6 +305,9 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
case 24:
CONFIG.proxy_cafile = strdup(optarg);
break;
case 25:
CONFIG.refresh_timeout = atoi(optarg);
break;
default:
fprintf(stderr, "see httpdirfs -h for usage\n");
return 1;
@ -370,6 +374,7 @@ HTTPDirFS options:\n\
to 1TB in size using the default segment size.\n\
--max-conns Set maximum number of network connections that\n\
libcurl is allowed to make. (default: 10)\n\
--refresh-timeout X Refresh directories after X seconds\n\
--retry-wait Set delay in seconds before retrying an HTTP request\n\
after encountering an error. (default: 5)\n\
--user-agent Set user agent string (default: \"HTTPDirFS\")\n\