[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;


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/