Exemple #1
0
static gfarm_error_t
gfs_stat_cache_enter_internal(const char *path, const struct gfs_stat *st,
	const struct timeval *nowp)
{
	gfarm_error_t e;
	struct gfarm_hash_entry *entry;
	struct stat_cache_data *data;
	int created;

	if (stat_cache == NULL) {
		if ((e = gfs_stat_cache_init()) != GFARM_ERR_NO_ERROR)
			return (e);
	}
	gfs_stat_cache_expire_internal(nowp);

	if (stat_cache_count >= gfarm_attr_cache_limit) {
		/* remove the head of the list (i.e. oldest entry) */
		data = stat_cache_list_head.next;
		data->prev->next = data->next;
		data->next->prev = data->prev;
		gfs_stat_free(&data->st);
		entry = data->entry;
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
		--stat_cache_count;
	}

	entry = gfarm_hash_enter(stat_cache, path, strlen(path) + 1,
	    sizeof(*data), &created);
	if (entry == NULL)
		return (GFARM_ERR_NO_MEMORY);

	data = gfarm_hash_entry_data(entry);
	if (created) {
		++stat_cache_count;
		data->entry = entry;
	} else {
		/* remove from the list, to move this to the end of the list */
		data->prev->next = data->next;
		data->next->prev = data->prev;

		gfs_stat_free(&data->st);
	}
	e = gfs_stat_copy(&data->st, st);
	if (e != GFARM_ERR_NO_ERROR) {
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
		--stat_cache_count;
		return (e);
	}
	data->expiration = *nowp;
	gfarm_timeval_add(&data->expiration, &stat_cache_lifespan);
	/* add to the end of the cache list, i.e. assumes monotonic time */
	data->next = &stat_cache_list_head;
	data->prev = stat_cache_list_head.prev;
	stat_cache_list_head.prev->next = data;
	stat_cache_list_head.prev = data;
	return (GFARM_ERR_NO_ERROR);
		
}
Exemple #2
0
static void
cache_path_info_free()
{
	struct gfarm_hash_iterator iterator;
	struct gfarm_hash_entry *he;
	struct path_info_cache *pic;
#ifdef DEBUG
	char *key;
	char path[PATH_MAX];
#endif
	gfarm_hash_iterator_begin(cache_table, &iterator);
	while (1) {
		he = gfarm_hash_iterator_access(&iterator);
		if (he == NULL)
		        break;
		pic = gfarm_hash_entry_data(he);
#ifdef DEBUG
		key = gfarm_hash_entry_key(he);
		memset(path, 0, PATH_MAX);
		memcpy(path, key, gfarm_hash_entry_key_length(he));
		_debug("! free path_info cache: %d: %s\n", pic->noent, path);
#endif
		if (pic->noent == CACHE_SET)
			gfarm_path_info_free(&pic->info);
		gfarm_hash_iterator_next(&iterator);
	}
	/* ?? gfarm_hash_iterator_purge(&iterator); */

	gfarm_hash_table_free(cache_table);
	prepare_cache_table = 0;
}
Exemple #3
0
void
gfp_conn_hash_purge(struct gfarm_hash_table *hashtab,
	struct gfarm_hash_entry *entry)
{
	void *key = gfarm_hash_entry_key(entry);
	int keylen = gfarm_hash_entry_key_length(entry);
	struct gfp_conn_hash_id *idp = key;
	struct gfp_conn_hash_id id = *idp;

	gfarm_hash_purge(hashtab, key, keylen);
	free(id.hostname);
	free(id.username);
}
Exemple #4
0
void
gfs_stat_cache_clear(void)
{
	struct stat_cache_data *p, *q;
	struct gfarm_hash_entry *entry;

	for (p = stat_cache_list_head.next; p != &stat_cache_list_head; p = q) {
		q = p->next;
		gfs_stat_free(&p->st);

		entry = p->entry;
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
	}
	stat_cache_list_head.next = stat_cache_list_head.prev =
	    &stat_cache_list_head;
	stat_cache_count = 0;
}
Exemple #5
0
char *
gfs_readdir(GFS_Dir dir, struct gfs_dirent **entry)
{
	struct gfarm_hash_entry *he;
	struct node *n;

	if (dir->index == 0) {
		n = dir->dir;
		dir->buffer.d_namlen = 1;
		dir->buffer.d_name[0] = '.';
		dir->index++;
	} else if (dir->index == 1) {
		n = dir->dir->parent;
		dir->buffer.d_namlen = 2;
		dir->buffer.d_name[0] = dir->buffer.d_name[1] = '.';
		dir->index++;
	} else {
		for (;;) {
			he = gfarm_hash_iterator_access(&dir->iterator);
			if (he == NULL) {
				*entry = NULL;
				return (NULL);
			}
			n = gfarm_hash_entry_data(he);
			gfarm_hash_iterator_next(&dir->iterator);
			dir->index++;
			if ((n->flags & NODE_FLAG_PURGED) == 0)
				break;
		}
		dir->buffer.d_namlen = gfarm_hash_entry_key_length(he);
		memcpy(dir->buffer.d_name, gfarm_hash_entry_key(he),
		    dir->buffer.d_namlen);
	}
	dir->buffer.d_name[dir->buffer.d_namlen] = '\0';
	dir->buffer.d_type = (n->flags & NODE_FLAG_IS_DIR) ?
	    GFS_DT_DIR : GFS_DT_REG;
	dir->buffer.d_reclen = 0x100; /* XXX */
	dir->buffer.d_fileno = INUMBER(n);
	*entry = &dir->buffer;
	return (NULL);
}
Exemple #6
0
static void
gfs_stat_cache_expire_internal(const struct timeval *nowp)
{
	struct stat_cache_data *p, *q;
	struct gfarm_hash_entry *entry;

	for (p = stat_cache_list_head.next; p != &stat_cache_list_head; p = q) {
		/* assumes monotonic time */
		if (gfarm_timeval_cmp(&p->expiration, nowp) > 0)
			break;

		q = p->next;
		gfs_stat_free(&p->st);

		entry = p->entry;
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
		--stat_cache_count;
	}
	stat_cache_list_head.next = p;
	p->prev = &stat_cache_list_head;
}