[vhffs-dev] [938] finished quota cache, values are not modified during runtime yet |
[ Thread Index |
Date Index
| More vhffs.org/vhffs-dev Archives
]
Revision: 938
Author: gradator
Date: 2007-09-21 15:20:00 +0000 (Fri, 21 Sep 2007)
Log Message:
-----------
finished quota cache, values are not modified during runtime yet
Modified Paths:
--------------
trunk/vhffs-fs/vhffsfs.c
Modified: trunk/vhffs-fs/vhffsfs.c
===================================================================
--- trunk/vhffs-fs/vhffsfs.c 2007-09-21 13:08:57 UTC (rev 937)
+++ trunk/vhffs-fs/vhffsfs.c 2007-09-21 15:20:00 UTC (rev 938)
@@ -14,7 +14,7 @@
#if HAVE_CONFIG_H
#include <config.h>
#else
-#error You've to run configure script before builing the sources
+#error You've to run configure script before building the sources
#endif
#include <fuse.h>
@@ -72,6 +72,7 @@
#ifdef WITH_CHECKQUOTA_CACHE
typedef struct {
gid_t gid;
+ char *path;
struct dqblk *dq;
time_t arrival;
int ref;
@@ -363,8 +364,7 @@
static inline void vhffsfs_PGClear(char *query, PGresult *result) {
#ifdef WITH_CACHE
vhffsfs_cache_unref(query);
-#endif
-#ifndef WITH_CACHE
+#else
PQclear(result);
#endif
}
@@ -767,10 +767,19 @@
pthread_mutex_unlock(&vhffsfs.quotacachelock);
}
-struct dqblk *vhffsfs_checkquota_cache_add(gid_t gid, struct dqblk *dq) {
+char *vhffsfs_checkquota_genkey(gid_t gid, char *path) {
+ int len;
+ if(!path) return NULL;
+ len = strlen(path)+10+1+1; /* path + any 32 bits number + '_' + '\0' */
+ char *key = malloc(len);
+ snprintf(key, len, "%.10u_%s", gid, path);
+ return key;
+}
+
+struct dqblk *vhffsfs_checkquota_cache_add(char *key, gid_t gid, char *path, struct dqblk *dq) {
vhffsfs_cache_quota *vcq;
vhffsfs_checkquota_cache_lock();
- vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ vcq = g_hash_table_lookup(vhffsfs.quotacacheused, key);
if(vcq) {
vcq->ref++;
vhffsfs_checkquota_cache_unlock();
@@ -778,54 +787,55 @@
return vcq->dq;
}
#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
- printf("QUOTACACHE: ADDING: %d\n", gid);
+ printf("QUOTACACHE: ADDING: %s [ %d , %s ]\n", key, gid, path);
#endif
vcq = malloc(sizeof(vhffsfs_cache_quota));
vcq->gid = gid;
+ vcq->path = path;
vcq->dq = dq;
vcq->arrival = vhffsfs_cache_arrival();
vcq->ref = 1;
- g_hash_table_insert(vhffsfs.quotacacheused, GINT_TO_POINTER(vcq->gid), vcq);
- g_ptr_array_add(vhffsfs.quotacachekeys, GINT_TO_POINTER(vcq->gid));
+ g_hash_table_insert(vhffsfs.quotacacheused, key, vcq);
+ g_ptr_array_add(vhffsfs.quotacachekeys, key);
vhffsfs_checkquota_cache_unlock();
return vcq->dq;
}
-void vhffsfs_checkquota_cache_del(gid_t gid) {
+void vhffsfs_checkquota_cache_del(char *key) {
vhffsfs_cache_quota *vcq;
vhffsfs_checkquota_cache_lock();
- vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ vcq = g_hash_table_lookup(vhffsfs.quotacacheused, key);
// non existing or still referenced
if(!vcq || vcq->ref > 0) {
vhffsfs_checkquota_cache_unlock();
return;
}
#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
- printf("CACHE: DELETING: %d\n", gid);
+ printf("CACHE: DELETING: %s\n", key);
#endif
- g_ptr_array_remove_fast(vhffsfs.quotacachekeys, GINT_TO_POINTER(vcq->gid));
- g_hash_table_remove(vhffsfs.quotacacheused, GINT_TO_POINTER(vcq->gid));
+ g_ptr_array_remove_fast(vhffsfs.quotacachekeys, key);
+ g_hash_table_remove(vhffsfs.quotacacheused, key);
free(vcq->dq);
free(vcq);
vhffsfs_checkquota_cache_unlock();
}
-struct dqblk *vhffsfs_checkquota_cache_lookup(gid_t gid) {
+struct dqblk *vhffsfs_checkquota_cache_lookup(char *key) {
vhffsfs_checkquota_cache_lock();
- vhffsfs_cache_quota *vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ vhffsfs_cache_quota *vcq = g_hash_table_lookup(vhffsfs.quotacacheused, key);
if(vcq) {
// timeout
if(vhffsfs_cache_timeout(vcq->arrival, VHFFSFS_CHECKQUOTA_CACHE_TIMEOUT)) {
#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
- fprintf(stdout, "CACHE: TIMEOUT: %d\n", gid);
+ fprintf(stdout, "CACHE: TIMEOUT: %s\n", key);
#endif
vhffsfs_checkquota_cache_unlock();
- vhffsfs_checkquota_cache_del(gid);
+ vhffsfs_checkquota_cache_del(key);
return NULL;
}
// cache hit
#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
- fprintf(stdout, "CACHE: HIT: %d\n", gid);
+ fprintf(stdout, "CACHE: HIT: %s\n", key);
#endif
vcq->ref++;
vhffsfs_checkquota_cache_unlock();
@@ -833,19 +843,19 @@
}
// cache miss
#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
- fprintf(stdout, "CACHE: MISS: %d\n", gid);
+ fprintf(stdout, "CACHE: MISS: %s\n", key);
#endif
vhffsfs_checkquota_cache_unlock();
return NULL;
}
-void vhffsfs_checkquota_cache_unref(gid_t gid) {
+void vhffsfs_checkquota_cache_unref(char *key) {
vhffsfs_checkquota_cache_lock();
- vhffsfs_cache_quota *vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ vhffsfs_cache_quota *vcq = g_hash_table_lookup(vhffsfs.quotacacheused, key);
if(vcq && vcq->ref > 0) vcq->ref--;
else {
- if(!vcq) fprintf(stderr, "CACHE: CORRUPT: '%d': NOT IN TABLE\n", gid);
- else fprintf(stderr, "CACHE: CORRUPT: '%d': REF IS ALREADY SET TO 0\n", gid);
+ if(!vcq) fprintf(stderr, "CACHE: CORRUPT: '%s': NOT IN TABLE\n", key);
+ else fprintf(stderr, "CACHE: CORRUPT: '%s': REF IS ALREADY SET TO 0\n", key);
}
vhffsfs_checkquota_cache_unlock();
}
@@ -876,20 +886,22 @@
sleep(1);
for(i = 0 ; i < keys->len ; i++) {
- gid_t gid = GPOINTER_TO_INT(keys->pdata[i]);
+ char *key = keys->pdata[i];
+
vhffsfs_cache_quota *vcq;
vhffsfs_checkquota_cache_lock();
- vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ vcq = g_hash_table_lookup(vhffsfs.quotacacheused, key);
if(vcq && vhffsfs_cache_timeout(vcq->arrival, VHFFSFS_CHECKQUOTA_CACHE_TIMEOUT)) {
#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
- fprintf(stdout, "CACHE: TIMEOUT: %d\n", gid);
+ fprintf(stdout, "CACHE: TIMEOUT: %d, %s\n", vcq->gid, vcq->path);
#endif
vhffsfs_checkquota_cache_unlock();
- vhffsfs_checkquota_cache_del(gid);
+ vhffsfs_checkquota_cache_del(key);
}
else vhffsfs_checkquota_cache_unlock();
+ free(key);
//sleep a bit to not lock the cache too much
usleep(100000);
}
@@ -929,7 +941,7 @@
/* return an allocated dqblk struct or NULL if something failed (errno is set) */
-struct dqblk *vhffsfs_checkquotagid_blockdev(char *blockdev, int gid) {
+struct dqblk *vhffsfs_checkquotagid_blockdev(char *blockdev, gid_t gid) {
struct dqblk *dq;
if(!blockdev || !gid) {
@@ -949,7 +961,7 @@
#ifdef WITH_CHECKQUOTA_RPC
/* return an allocated dqblk struct or NULL if something failed (errno is set) */
-struct dqblk *vhffsfs_checkquotagid_rpc(char *rpcserver, char *path, int gid) {
+struct dqblk *vhffsfs_checkquotagid_rpc(char *rpcserver, char *path, gid_t gid) {
CLIENT *clnt;
struct dqblk *dq;
@@ -1019,10 +1031,13 @@
#endif
/* return 0 if the gid is not over quota, 1 if over quota, -errno in case of error */
-int vhffsfs_checkquota_gid_with_realpath(char *realpath, int gid) {
+int vhffsfs_checkquota_gid_with_realpath(char *realpath, gid_t gid) {
int mode = 0; /* 0 = do nothing, 1 = data, 2 = repository */
struct dqblk *dq = NULL;
int ret = 0;
+#ifdef WITH_CHECKQUOTA_CACHE
+ char *key = NULL;
+#endif
if(!realpath) return -EINVAL;
if(!vhffsfs.dataprefixpath) return 0;
@@ -1049,8 +1064,29 @@
}
}
+#ifdef WITH_CHECKQUOTA_CACHE
/* data */
if(mode == 1) {
+ key = vhffsfs_checkquota_genkey(gid, vhffsfs.dataprefixpath);
+ }
+ /* repository */
+ else if(mode == 2 ) {
+ key = vhffsfs_checkquota_genkey(gid, vhffsfs.repositoriesprefixpath);
+ }
+
+ // try to fetch quota from cache
+ dq = vhffsfs_checkquota_cache_lookup(key);
+ if(dq) {
+ if(dq->dqb_curspace > dq->dqb_bhardlimit || dq->dqb_curinodes > dq->dqb_ihardlimit) ret = 1;
+ vhffsfs_checkquota_cache_unref(key);
+ free(key);
+ return ret;
+ }
+#endif
+
+
+ /* data */
+ if(mode == 1) {
if(vhffsfs.datablockdev) {
dq = vhffsfs_checkquotagid_blockdev(vhffsfs.datablockdev, gid);
}
@@ -1072,13 +1108,34 @@
#endif
}
+
if(!dq) {
printf("vhffsfs: quota: %s\n", strerror(errno));
}
- else {
+ else {
+#ifdef WITH_CHECKQUOTA_CACHE
+ char *path;
+ /* fill the cache */
+ /* data */
+ if(mode == 1) {
+ path = vhffsfs.dataprefixpath;
+ }
+ /* repository */
+ else if(mode == 2 ) {
+ path = vhffsfs.repositoriesprefixpath;
+ }
+
+ dq = vhffsfs_checkquota_cache_add(key, gid, path, dq);
+#endif
if(dq->dqb_curspace > dq->dqb_bhardlimit || dq->dqb_curinodes > dq->dqb_ihardlimit) ret = 1;
+#ifdef WITH_CHECKQUOTA_CACHE
+ vhffsfs_checkquota_cache_unref(key);
+ free(key);
+#else
free(dq);
+#endif
}
+
return ret;
}
#endif
@@ -1854,7 +1911,7 @@
vhffsfs.cachethreadstarted = 0;
#endif
#ifdef WITH_CHECKQUOTA_CACHE
- vhffsfs.quotacacheused = g_hash_table_new(g_int_hash, g_int_equal);
+ vhffsfs.quotacacheused = g_hash_table_new(g_str_hash, g_str_equal);
vhffsfs.quotacachekeys = g_ptr_array_sized_new(4096);
pthread_mutex_init(&vhffsfs.quotacachelock, NULL);
vhffsfs.quotacachethreadstarted = 0;