[vhffs-dev] [934] autotoolized quota, rewrote quota stuff, wrote quota cache backend but it is not used yet |
[ Thread Index |
Date Index
| More vhffs.org/vhffs-dev Archives
]
Revision: 934
Author: gradator
Date: 2007-09-21 12:20:48 +0000 (Fri, 21 Sep 2007)
Log Message:
-----------
autotoolized quota, rewrote quota stuff, wrote quota cache backend but it is not used yet
Modified Paths:
--------------
trunk/vhffs-fs/config.h.in
trunk/vhffs-fs/configure.ac
trunk/vhffs-fs/vhffsfs.c
Modified: trunk/vhffs-fs/config.h.in
===================================================================
--- trunk/vhffs-fs/config.h.in 2007-09-20 23:21:24 UTC (rev 933)
+++ trunk/vhffs-fs/config.h.in 2007-09-21 12:20:48 UTC (rev 934)
@@ -176,12 +176,33 @@
/* ??? */
#undef VHFFSFS_CACHE_QUERY_TIMEOUT
+/* ??? */
+#undef VHFFSFS_CHECKQUOTA_CACHE_REFRESH
+
+/* ??? */
+#undef VHFFSFS_CHECKQUOTA_CACHE_TIMEOUT
+
/* VHFFS-fs config file */
#undef VHFFSFS_CONFIG
-/* Enable caching facilities */
+/* Enable queries cache facility */
#undef WITH_CACHE
+/* Enable queries cache facility debugging */
+#undef WITH_CACHE_DEBUG
+
+/* Enable quota check */
+#undef WITH_CHECKQUOTA
+
+/* Enable quota cache */
+#undef WITH_CHECKQUOTA_CACHE
+
+/* Enable quota cache debugging */
+#undef WITH_CHECKQUOTA_CACHE_DEBUG
+
+/* Enable quota through RPC */
+#undef WITH_CHECKQUOTA_RPC
+
/* Required for fuse to works correctly */
#undef _FILE_OFFSET_BITS
Modified: trunk/vhffs-fs/configure.ac
===================================================================
--- trunk/vhffs-fs/configure.ac 2007-09-20 23:21:24 UTC (rev 933)
+++ trunk/vhffs-fs/configure.ac 2007-09-21 12:20:48 UTC (rev 934)
@@ -13,14 +13,22 @@
# Checks for programs.
AC_PROG_CC
-AC_ARG_ENABLE(cache,
- AC_HELP_STRING([--enable-cache],
- [Enable caching (see --with-cache-query-timeout and --with-cache-query-flush)
- [default=yes]]), enable_cache=$enableval, enable_cache=yes)
+# Cache stuff
+AC_ARG_ENABLE(cache-query,
+ AC_HELP_STRING([--enable-cache-query],
+ [Enable caching of SQL queries (see --with-cache-query-timeout , --with-cache-query-flush and --enable-cache-query-debug)
+ [default=yes]]), enable_cache_query=$enableval, enable_cache_query=yes)
-# Cache stuff
-if test "$enable_cache" = yes ; then
- AC_DEFINE([WITH_CACHE], [1], [Enable caching facilities])
+AC_ARG_ENABLE(cache-query-debug,
+ AC_HELP_STRING([--enable-cache-query-debug],
+ [Enable debug of queries cache
+ [default=no]]), enable_cache_query_debug=$enableval, enable_cache_query_debug=no)
+
+if test "$enable_cache_query" = yes ; then
+ AC_DEFINE([WITH_CACHE], [1], [Enable queries cache facility])
+ if test "$enable_cache_query_debug" = yes ; then
+ AC_DEFINE([WITH_CACHE_DEBUG], [1], [Enable queries cache facility debugging])
+ fi
AC_ARG_WITH([--with-cache-query-timeout],
AC_HELP_STRING([--with-cache-query-timeout],
[???? [default=600]]),
@@ -33,6 +41,52 @@
AC_DEFINE([VHFFSFS_CACHE_QUERY_FLUSH_EVERY], 1800, [???]))
fi
+
+# Check quota stuff
+AC_ARG_ENABLE(check-quota,
+ AC_HELP_STRING([--enable-check-quota],
+ [Enable check of quota (see --enable-check-quota-rpc and --enable-check-quota-cache)
+ [default=yes]]), enable_checkquota=$enableval, enable_checkquota=yes)
+
+AC_ARG_ENABLE(check-quota-rpc,
+ AC_HELP_STRING([--enable-check-quota-rpc],
+ [Enable check of quota through RPC
+ [default=yes]]), enable_checkquota_rpc=$enableval, enable_checkquota_rpc=yes)
+
+AC_ARG_ENABLE(check-quota-cache,
+ AC_HELP_STRING([--enable-check-quota-cache],
+ [Enable quota cache (see --enable-check-quota-cache-debug , --with-check-quota-cache-timeout , --with-check-quota-cache-flush )
+ [default=yes]]), enable_checkquota_cache=$enableval, enable_checkquota_cache=yes)
+
+AC_ARG_ENABLE(check-quota-cache-debug,
+ AC_HELP_STRING([--enable-check-quota-cache-debug],
+ [Enable quota cache debugging
+ [default=no]]), enable_checkquota_cache_debug=$enableval, enable_checkquota_cache_debug=no)
+
+if test "$enable_checkquota" = yes ; then
+ AC_DEFINE([WITH_CHECKQUOTA], [1], [Enable quota check])
+ if test "$enable_checkquota_rpc" = yes ; then
+ AC_DEFINE([WITH_CHECKQUOTA_RPC], [1], [Enable quota through RPC])
+ fi
+ if test "$enable_checkquota_cache" = yes ; then
+ AC_DEFINE([WITH_CHECKQUOTA_CACHE], [1], [Enable quota cache])
+ if test "$check-quota-cache-debug" = yes ; then
+ AC_DEFINE([WITH_CHECKQUOTA_CACHE_DEBUG], [1], [Enable quota cache debugging])
+ fi
+ AC_ARG_WITH([check-quota-cache-timeout],
+ AC_HELP_STRING([--with-check-quota-cache-timeout],
+ [???? [default=10]]),
+ AC_DEFINE([VHFFSFS_CHECKQUOTA_CACHE_TIMEOUT], $withval, [???]),
+ AC_DEFINE([VHFFSFS_CHECKQUOTA_CACHE_TIMEOUT], 30, [???]))
+ AC_ARG_WITH([check-quota-cache-flush],
+ AC_HELP_STRING([--with-check-quota-cache-flush],
+ [???? [default=1800]]),
+ AC_DEFINE([VHFFSFS_CHECKQUOTA_CACHE_REFRESH], $withval, [???]),
+ AC_DEFINE([VHFFSFS_CHECKQUOTA_CACHE_REFRESH], 1800, [???]))
+ fi
+fi
+
+
# fuse stuff
AC_ARG_WITH(fuse-version,
AC_HELP_STRING([--with-fuse-version],
@@ -78,7 +132,7 @@
AC_CHECK_HEADERS(fuse.h,,, [#define _FILE_OFFSET_BITS 64])
AC_CHECK_HEADERS([fcntl.h inttypes.h postgresql/libpq-fe.h pthread.h signal.h stdint.h stdio.h unistd.h],
[], [AC_MSG_ERROR([Missing headers, bailing out])])
-if test "$enable_cache" = yes ; then
+if test "$enable_cache_query" = yes || test "$enable_checkquota_cache" = yes ; then
PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= 2.0.2])
CFLAGS="$CFLAGS $GLIB2_CFLAGS"
LIBS="$LIBS $GLIB2_LIBS"
Modified: trunk/vhffs-fs/vhffsfs.c
===================================================================
--- trunk/vhffs-fs/vhffsfs.c 2007-09-20 23:21:24 UTC (rev 933)
+++ trunk/vhffs-fs/vhffsfs.c 2007-09-21 12:20:48 UTC (rev 934)
@@ -9,11 +9,6 @@
#define VHFFSFS_MAXCONNDB 5
#define VHFFSFS_EMPTYDIR "/tmp/emptydir"
-#define WITH_CACHE_DEBUG 1
-
-#define WITH_CHECKQUOTA 1
-#define WITH_CHECKQUOTA_RPC 1
-
#define _GNU_SOURCE
#if HAVE_CONFIG_H
@@ -49,7 +44,7 @@
#include <pthread.h>
#include <signal.h>
-#ifdef WITH_CACHE
+#if defined(WITH_CACHE) || defined(WITH_CHECKQUOTA_CACHE)
#include <glib.h>
#endif
@@ -66,7 +61,6 @@
#include "md5.h"
#ifdef WITH_CACHE
-
typedef struct {
char *query;
PGresult *result;
@@ -75,6 +69,15 @@
} vhffsfs_cache_query;
#endif
+#ifdef WITH_CHECKQUOTA_CACHE
+typedef struct {
+ gid_t gid;
+ struct dqblk *dq;
+ time_t arrival;
+ int ref;
+} vhffsfs_cache_quota;
+#endif
+
struct vhffsfs {
pthread_mutex_t pg_lock[VHFFSFS_MAXCONNDB];
PGconn *pg_conn[VHFFSFS_MAXCONNDB];
@@ -107,12 +110,18 @@
char *repositoriesrpcserver;
char *repositoriesrpcpath;
#endif
+#ifdef WITH_CHECKQUOTA_CACHE
+ GHashTable *quotacacheused;
+ GPtrArray* quotacachekeys;
+ pthread_mutex_t quotacachelock;
+ int quotacachethreadstarted;
#endif
+#endif
};
static struct vhffsfs vhffsfs;
-#ifdef WITH_CACHE
+#if defined(WITH_CACHE) || defined(WITH_CHECKQUOTA_CACHE)
time_t vhffsfs_cache_arrival() {
struct timeval tv;
gettimeofday(&tv, NULL);
@@ -125,7 +134,9 @@
if(tv.tv_sec - arrival >= timeout) return 1;
return 0;
}
+#endif
+#ifdef WITH_CACHE
static inline void vhffsfs_cache_lock() {
pthread_mutex_lock(&vhffsfs.cachelock);
}
@@ -221,51 +232,51 @@
static void *vhffsfs_cache_flush(void *data_)
{
- (void) data_;
+ (void) data_;
- while(1) {
- GPtrArray *keys;
- int i;
+ while(1) {
+ GPtrArray *keys;
+ int i;
- sleep(VHFFSFS_CACHE_QUERY_FLUSH_EVERY);
+ sleep(VHFFSFS_CACHE_QUERY_FLUSH_EVERY);
- keys = g_ptr_array_sized_new(4096);
+ keys = g_ptr_array_sized_new(4096);
- //printf("FLUSH CACHE\n");
+ //printf("FLUSH CACHE\n");
- // copy keys
- vhffsfs_cache_lock();
- for(i = 0 ; i < vhffsfs.cachekeys->len ; i++) {
- g_ptr_array_add(keys, strdup(vhffsfs.cachekeys->pdata[i]));
- }
- vhffsfs_cache_unlock();
+ // copy keys
+ vhffsfs_cache_lock();
+ for(i = 0 ; i < vhffsfs.cachekeys->len ; i++) {
+ g_ptr_array_add(keys, strdup(vhffsfs.cachekeys->pdata[i]));
+ }
+ vhffsfs_cache_unlock();
- // sleep a bit to not lock the cache too much
- sleep(1);
+ // sleep a bit to not lock the cache too much
+ sleep(1);
- for(i = 0 ; i < keys->len ; i++) {
- char *query = keys->pdata[i];
- vhffsfs_cache_query *vcq;
+ for(i = 0 ; i < keys->len ; i++) {
+ char *query = keys->pdata[i];
+ vhffsfs_cache_query *vcq;
- vhffsfs_cache_lock();
- vcq = g_hash_table_lookup(vhffsfs.cachequeries, query);
- if(vcq && vhffsfs_cache_timeout(vcq->arrival, VHFFSFS_CACHE_QUERY_TIMEOUT)) {
+ vhffsfs_cache_lock();
+ vcq = g_hash_table_lookup(vhffsfs.cachequeries, query);
+ if(vcq && vhffsfs_cache_timeout(vcq->arrival, VHFFSFS_CACHE_QUERY_TIMEOUT)) {
#ifdef WITH_CACHE_DEBUG
- fprintf(stdout, "CACHE: TIMEOUT: '%s'\n", query);
+ fprintf(stdout, "CACHE: TIMEOUT: '%s'\n", query);
#endif
- vhffsfs_cache_unlock();
- vhffsfs_cache_del(query);
+ vhffsfs_cache_unlock();
+ vhffsfs_cache_del(query);
+ }
+ else vhffsfs_cache_unlock();
+
+ free(query);
+ //sleep a bit to not lock the cache too much
+ usleep(100000);
}
- else vhffsfs_cache_unlock();
- free(query);
- //sleep a bit to not lock the cache too much
- usleep(100000);
+ g_ptr_array_free(keys, TRUE);
}
-
- g_ptr_array_free(keys, TRUE);
- }
- return NULL;
+ return NULL;
}
@@ -747,27 +758,206 @@
#ifdef WITH_CHECKQUOTA
-/* return 0 if the gid is not over quota, 1 if over quota, else return -errno value */
-int vhffsfs_checkquotagid_blockdev(char *blockdev, int gid) {
+#ifdef WITH_CHECKQUOTA_CACHE
+static inline void vhffsfs_checkquota_cache_lock() {
+ pthread_mutex_lock(&vhffsfs.quotacachelock);
+}
- struct dqblk dq;
- if(!blockdev || !gid) return -EINVAL;
+static inline void vhffsfs_checkquota_cache_unlock() {
+ pthread_mutex_unlock(&vhffsfs.quotacachelock);
+}
- if(quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), blockdev, gid, (caddr_t)&dq)) {
- return -errno;
- } else {
- if(dq.dqb_curspace >> 10 > dq.dqb_bhardlimit || dq.dqb_curinodes > dq.dqb_ihardlimit) return 1;
+struct dqblk *vhffsfs_checkquota_cache_add(gid_t gid, struct dqblk *dq) {
+ vhffsfs_cache_quota *vcq;
+ vhffsfs_checkquota_cache_lock();
+ vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ if(vcq) {
+ vcq->ref++;
+ vhffsfs_checkquota_cache_unlock();
+ free(dq);
+ return vcq->dq;
}
+#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
+ printf("QUOTACACHE: ADDING: %d\n", gid);
+#endif
+ vcq = malloc(sizeof(vhffsfs_cache_quota));
+ vcq->gid = gid;
+ 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));
+ vhffsfs_checkquota_cache_unlock();
+ return vcq->dq;
+}
+
+void vhffsfs_checkquota_cache_del(gid_t gid) {
+ vhffsfs_cache_quota *vcq;
+ vhffsfs_checkquota_cache_lock();
+ vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ // 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);
+#endif
+ g_ptr_array_remove_fast(vhffsfs.quotacachekeys, GINT_TO_POINTER(vcq->gid));
+ g_hash_table_remove(vhffsfs.quotacacheused, GINT_TO_POINTER(vcq->gid));
+ free(vcq->dq);
+ free(vcq);
+ vhffsfs_checkquota_cache_unlock();
+}
+
+struct dqblk *vhffsfs_checkquota_cache_lookup(gid_t gid) {
+ vhffsfs_checkquota_cache_lock();
+ vhffsfs_cache_quota *vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ 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);
+#endif
+ vhffsfs_checkquota_cache_unlock();
+ vhffsfs_checkquota_cache_del(gid);
+ return NULL;
+ }
+ // cache hit
+#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
+ fprintf(stdout, "CACHE: HIT: %d\n", gid);
+#endif
+ vcq->ref++;
+ vhffsfs_checkquota_cache_unlock();
+ return vcq->dq;
+ }
+ // cache miss
+#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
+ fprintf(stdout, "CACHE: MISS: %d\n", gid);
+#endif
+ vhffsfs_checkquota_cache_unlock();
+ return NULL;
+}
+
+void vhffsfs_checkquota_cache_unref(gid_t gid) {
+ vhffsfs_checkquota_cache_lock();
+ vhffsfs_cache_quota *vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ 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);
+ }
+ vhffsfs_checkquota_cache_unlock();
+}
+
+
+static void *vhffsfs_checkquota_cache_flush(void *data_)
+{
+ (void) data_;
+
+ while(1) {
+ GPtrArray *keys;
+ int i;
+
+ sleep(VHFFSFS_CHECKQUOTA_CACHE_REFRESH);
+
+ keys = g_ptr_array_sized_new(4096);
+
+ //printf("FLUSH CACHE\n");
+
+ // copy keys
+ vhffsfs_checkquota_cache_lock();
+ for(i = 0 ; i < vhffsfs.quotacachekeys->len ; i++) {
+ g_ptr_array_add(keys, vhffsfs.quotacachekeys->pdata[i]);
+ }
+ vhffsfs_checkquota_cache_unlock();
+
+ // sleep a bit to not lock the cache too much
+ sleep(1);
+
+ for(i = 0 ; i < keys->len ; i++) {
+ gid_t gid = GPOINTER_TO_INT(keys->pdata[i]);
+ vhffsfs_cache_quota *vcq;
+
+ vhffsfs_checkquota_cache_lock();
+ vcq = g_hash_table_lookup(vhffsfs.quotacacheused, GINT_TO_POINTER(gid));
+ if(vcq && vhffsfs_cache_timeout(vcq->arrival, VHFFSFS_CHECKQUOTA_CACHE_TIMEOUT)) {
+#ifdef WITH_CHECKQUOTA_CACHE_DEBUG
+ fprintf(stdout, "CACHE: TIMEOUT: %d\n", gid);
+#endif
+ vhffsfs_checkquota_cache_unlock();
+ vhffsfs_checkquota_cache_del(gid);
+ }
+ else vhffsfs_checkquota_cache_unlock();
+
+ //sleep a bit to not lock the cache too much
+ usleep(100000);
+ }
+
+ g_ptr_array_free(keys, TRUE);
+ }
+ return NULL;
+}
+
+
+static int vhffsfs_checkquota_start_cache_flush_thread(void)
+{
+ int err;
+ pthread_t thread_id;
+ sigset_t oldset;
+ sigset_t newset;
+
+ if(vhffsfs.quotacachethreadstarted) return 0;
+
+ sigemptyset(&newset);
+ sigaddset(&newset, SIGTERM);
+ sigaddset(&newset, SIGINT);
+ sigaddset(&newset, SIGHUP);
+ sigaddset(&newset, SIGQUIT);
+ pthread_sigmask(SIG_BLOCK, &newset, &oldset);
+ err = pthread_create(&thread_id, NULL, vhffsfs_checkquota_cache_flush, NULL);
+ if(err) {
+ fprintf(stderr, "Failed to create thread: %s\n", strerror(err));
+ return -EIO;
+ }
+ pthread_detach(thread_id);
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ vhffsfs.quotacachethreadstarted = 1;
return 0;
}
+#endif
+
+/* return an allocated dqblk struct or NULL if something failed (errno is set) */
+struct dqblk *vhffsfs_checkquotagid_blockdev(char *blockdev, int gid) {
+
+ struct dqblk *dq;
+ if(!blockdev || !gid) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ dq = malloc(sizeof(struct dqblk));
+ if( quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), blockdev, gid, (caddr_t)dq) ) {
+ free(dq);
+ return NULL;
+ }
+ dq.dqb_curspace >>= 10;
+ return dq;
+}
+
+
#ifdef WITH_CHECKQUOTA_RPC
-/* return 0 if the gid is not over quota */
+/* return an allocated dqblk struct or NULL if something failed (errno is set) */
int vhffsfs_checkquotagid_rpc(char *rpcserver, char *path, int gid) {
CLIENT *clnt;
+ struct dqblk *dq;
- if(!rpcserver || !path || !gid) return -EINVAL;
+ if(!rpcserver || !path || !gid) {
+ errno = EINVAL;
+ return NULL;
+ }
if( (clnt = clnt_create(rpcserver, RQUOTAPROG, EXT_RQUOTAVERS, "udp")) != NULL) {
@@ -797,27 +987,41 @@
if(res == RPC_SUCCESS && clnt_res.status == Q_OK) {
struct rquota *n = &clnt_res.getquota_rslt_u.gqr_rquota;
- if(!n) return -EIO;
+ if(!n) {
+ errno = EIO;
+ return NULL;
+ }
/* printf("QUOTA -> GID: %d, HARDB: %d, SOFTB: %d, CURB: %d\n", gid, n->rq_bhardlimit, n->rq_bsoftlimit, n->rq_curblocks );
* printf("QUOTA -> GID: %d, HARDF: %d, SOFTF: %d, CURF: %d\n", gid, n->rq_fhardlimit, n->rq_fsoftlimit, n->rq_curfiles );
*/
- if(n->rq_curblocks > n->rq_bhardlimit || n->rq_curfiles > n->rq_fhardlimit) return 1;
-
- /* printf("QUOTA -> OK !\n"); */
+ dq = malloc(sizeof(struct dqblk));
+ dq->dqb_bhardlimit = n->rq_bhardlimit;
+ dq->dqb_bsoftlimit = n->rq_bsoftlimit;
+ dq->dqb_curspace = n->rq_curblocks;
+ dq->dqb_ihardlimit = n->rq_fhardlimit;
+ dq->dqb_isoftlimit = n->rq_fsoftlimit;
+ dq->dqb_curinodes = n->rq_curfiles;
+ dq->dqb_btime = n->rq_btimeleft;
+ dq->dqb_itime = n->rq_ftimeleft;
+ dq->dqb_valid = 0;
+ return dq;
}
- else return -EIO;
+
+ errno = EIO;
+ return NULL;
}
- else return -EIO;
- return 0;
+
+ errno = EIO;
+ return NULL;
}
#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 mode = 0; /* 0 = do nothing, 1 = data, 2 = repository */
- int res = 0;
+ struct dqblk *dq = NULL;
if(!realpath) return -EINVAL;
if(!vhffsfs.dataprefixpath) return 0;
@@ -844,41 +1048,36 @@
}
}
- /*
- printf("DAIBEUG, realpath = %s\n", realpath);
- printf("DAIBEUG, dataprefixpath = %s\n", vhffsfs.dataprefixpath);
- printf("DAIBEUG, repositoriesprefixpath = %s\n", vhffsfs.repositoriesprefixpath);
- printf("DAIBEUG, mode = %d\n", mode);
- */
-
/* data */
if(mode == 1) {
if(vhffsfs.datablockdev) {
- res = vhffsfs_checkquotagid_blockdev(vhffsfs.datablockdev, gid);
+ dq = vhffsfs_checkquotagid_blockdev(vhffsfs.datablockdev, gid);
}
#ifdef WITH_CHECKQUOTA_RPC
else if(vhffsfs.datarpcserver && vhffsfs.datarpcpath) {
- res = vhffsfs_checkquotagid_rpc(vhffsfs.datarpcserver, vhffsfs.datarpcpath, gid);
+ dq = vhffsfs_checkquotagid_rpc(vhffsfs.datarpcserver, vhffsfs.datarpcpath, gid);
}
#endif
}
/* repository */
else if(mode == 2 ) {
if(vhffsfs.repositoriesblockdev) {
- res = vhffsfs_checkquotagid_blockdev(vhffsfs.repositoriesblockdev, gid);
+ dq = vhffsfs_checkquotagid_blockdev(vhffsfs.repositoriesblockdev, gid);
}
#ifdef WITH_CHECKQUOTA_RPC
else if(vhffsfs.repositoriesrpcserver && vhffsfs.repositoriesrpcpath) {
- res = vhffsfs_checkquotagid_rpc(vhffsfs.repositoriesrpcserver, vhffsfs.repositoriesrpcpath, gid);
+ dq = vhffsfs_checkquotagid_rpc(vhffsfs.repositoriesrpcserver, vhffsfs.repositoriesrpcpath, gid);
}
#endif
}
- if(res < 0) {
- printf("vhffsfs: quota: %s\n", strerror(-res));
- res = 0;
+ if(!dq) {
+ printf("vhffsfs: quota: %s\n", strerror(errno));
+ return 0;
}
- return res;
+
+ if(dq.dqb_curspace > dq.dqb_bhardlimit || dq.dqb_curinodes > dq.dqb_ihardlimit) return 1;
+ return 0;
}
#endif
@@ -889,6 +1088,10 @@
// create cache flush thread
vhffsfs_start_cache_flush_thread();
#endif
+#ifdef WITH_CHECKQUOTA_CACHE
+ // create cache flush thread for quota
+ vhffsfs_checkquota_start_cache_flush_thread();
+#endif
return NULL;
}
@@ -1648,7 +1851,12 @@
pthread_mutex_init(&vhffsfs.cachelock, NULL);
vhffsfs.cachethreadstarted = 0;
#endif
-
+#ifdef WITH_CHECKQUOTA_CACHE
+ vhffsfs.quotacacheused = g_hash_table_new(g_int_hash, g_int_equal);
+ vhffsfs.quotacachekeys = g_ptr_array_sized_new(4096);
+ pthread_mutex_init(&vhffsfs.quotacachelock, NULL);
+ vhffsfs.quotacachethreadstarted = 0;
+#endif
vhffsfs_readconfig(VHFFSFS_CONFIG);
// generate dbconninfo
- Messages sorted by: [ date | thread ]
- Prev by Date:
[vhffs-dev] [933] well, if 2 threads do a cache miss, they both send the query to the db server (everything is right here), then the both try to add the query in the cache, the first success, the second failed but it is not aware about that.
- Next by Date:
[vhffs-dev] [935] repeat after me "always compile the code before commiting, it may not compile"
- Previous by thread:
[vhffs-dev] [933] well, if 2 threads do a cache miss, they both send the query to the db server (everything is right here), then the both try to add the query in the cache, the first success, the second failed but it is not aware about that.
- Next by thread:
[vhffs-dev] [935] repeat after me "always compile the code before commiting, it may not compile"