summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/glusterfs
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/glusterfs')
-rw-r--r--libglusterfs/src/glusterfs/common-utils.h118
-rw-r--r--libglusterfs/src/glusterfs/dict.h10
-rw-r--r--libglusterfs/src/glusterfs/fd.h3
-rw-r--r--libglusterfs/src/glusterfs/gf-event.h4
-rw-r--r--libglusterfs/src/glusterfs/globals.h4
-rw-r--r--libglusterfs/src/glusterfs/glusterfs-acl.h2
-rw-r--r--libglusterfs/src/glusterfs/glusterfs.h17
-rw-r--r--libglusterfs/src/glusterfs/latency.h22
-rw-r--r--libglusterfs/src/glusterfs/mem-pool.h32
-rw-r--r--libglusterfs/src/glusterfs/mem-types.h1
-rw-r--r--libglusterfs/src/glusterfs/stack.h14
-rw-r--r--libglusterfs/src/glusterfs/statedump.h2
-rw-r--r--libglusterfs/src/glusterfs/store.h2
-rw-r--r--libglusterfs/src/glusterfs/syncop.h73
-rw-r--r--libglusterfs/src/glusterfs/syscall.h9
-rw-r--r--libglusterfs/src/glusterfs/xlator.h6
16 files changed, 267 insertions, 52 deletions
diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h
index 13e413c3632..f297fdab5c9 100644
--- a/libglusterfs/src/glusterfs/common-utils.h
+++ b/libglusterfs/src/glusterfs/common-utils.h
@@ -18,6 +18,7 @@
#include <string.h>
#include <assert.h>
#include <pthread.h>
+#include <unistd.h>
#include <openssl/md5.h>
#ifndef GF_BSD_HOST_OS
#include <alloca.h>
@@ -26,6 +27,11 @@
#include <fnmatch.h>
#include <uuid/uuid.h>
+/* FreeBSD, etc. */
+#ifndef __BITS_PER_LONG
+#define __BITS_PER_LONG (CHAR_BIT * (sizeof(long)))
+#endif
+
#ifndef ffsll
#define ffsll(x) __builtin_ffsll(x)
#endif
@@ -148,6 +154,9 @@ trap(void);
#define GF_THREAD_NAME_LIMIT 16
#define GF_THREAD_NAME_PREFIX "glfs_"
+/* Advisory buffer size for formatted timestamps (see gf_time_fmt) */
+#define GF_TIMESTR_SIZE 256
+
/*
* we could have initialized these as +ve values and treated
* them as negative while comparing etc.. (which would have
@@ -180,6 +189,12 @@ enum _gf_xlator_ipc_targets {
typedef enum _gf_special_pid gf_special_pid_t;
typedef enum _gf_xlator_ipc_targets _gf_xlator_ipc_targets_t;
+/* Array to hold custom xattr keys */
+extern char *xattrs_to_heal[];
+
+char **
+get_xattrs_to_heal();
+
/* The DHT file rename operation is not a straightforward rename.
* It involves creating linkto and linkfiles, and can unlink or rename the
* source file depending on the hashed and cached subvols for the source
@@ -240,6 +255,8 @@ list_node_del(struct list_node *node);
struct dnscache *
gf_dnscache_init(time_t ttl);
+void
+gf_dnscache_deinit(struct dnscache *cache);
struct dnscache_entry *
gf_dnscache_entry_init(void);
void
@@ -438,6 +455,15 @@ BIT_VALUE(unsigned char *array, unsigned int index)
} while (0)
#endif
+/* Compile-time assert, borrowed from Linux kernel. */
+#ifdef HAVE_STATIC_ASSERT
+#define GF_STATIC_ASSERT(expr, ...) \
+ __gf_static_assert(expr, ##__VA_ARGS__, #expr)
+#define __gf_static_assert(expr, msg, ...) _Static_assert(expr, msg)
+#else
+#define GF_STATIC_ASSERT(expr, ...)
+#endif
+
#define GF_ABORT(msg...) \
do { \
gf_msg_callingfn("", GF_LOG_CRITICAL, 0, LG_MSG_ASSERTION_FAILED, \
@@ -468,18 +494,15 @@ union gf_sock_union {
#define IOV_MIN(n) min(IOV_MAX, n)
-#define GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scr) \
- do { \
- entry = NULL; \
- if (dir) { \
- entry = sys_readdir(dir, scr); \
- while (entry && (!strcmp(entry->d_name, ".") || \
- !fnmatch("*.tmp", entry->d_name, 0) || \
- !strcmp(entry->d_name, ".."))) { \
- entry = sys_readdir(dir, scr); \
- } \
- } \
- } while (0)
+static inline gf_boolean_t
+gf_irrelevant_entry(struct dirent *entry)
+{
+ GF_ASSERT(entry);
+
+ return (!strcmp(entry->d_name, ".") ||
+ !fnmatch("*.tmp", entry->d_name, 0) ||
+ !strcmp(entry->d_name, ".."));
+}
static inline void
iov_free(struct iovec *vector, int count)
@@ -790,7 +813,7 @@ typedef enum {
} gf_timefmts;
static inline char *
-gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
+gf_time_fmt_tv(char *dst, size_t sz_dst, struct timeval *tv, unsigned int fmt)
{
extern void _gf_timestuff(const char ***, const char ***);
static gf_timefmts timefmt_last = (gf_timefmts)-1;
@@ -798,6 +821,8 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
static const char **zeros;
struct tm tm, *res;
int localtime = 0;
+ int len = 0;
+ int pos = 0;
if (timefmt_last == ((gf_timefmts)-1)) {
_gf_timestuff(&fmts, &zeros);
@@ -807,15 +832,35 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
fmt = gf_timefmt_default;
}
localtime = gf_log_get_localtime();
- res = localtime ? localtime_r(&utime, &tm) : gmtime_r(&utime, &tm);
- if (utime && (res != NULL)) {
- strftime(dst, sz_dst, fmts[fmt], &tm);
+ res = localtime ? localtime_r(&tv->tv_sec, &tm)
+ : gmtime_r(&tv->tv_sec, &tm);
+ if (tv->tv_sec && (res != NULL)) {
+ len = strftime(dst, sz_dst, fmts[fmt], &tm);
+ if (len == 0)
+ return dst;
+ pos += len;
+ if (tv->tv_usec >= 0) {
+ len = snprintf(dst + pos, sz_dst - pos, ".%" GF_PRI_SUSECONDS,
+ tv->tv_usec);
+ if (len >= sz_dst - pos)
+ return dst;
+ pos += len;
+ }
+ strftime(dst + pos, sz_dst - pos, " %z", &tm);
} else {
strncpy(dst, "N/A", sz_dst);
}
return dst;
}
+static inline char *
+gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
+{
+ struct timeval tv = {utime, -1};
+
+ return gf_time_fmt_tv(dst, sz_dst, &tv, fmt);
+}
+
/* This function helps us use gfid (unique identity) to generate inode's unique
* number in glusterfs.
*/
@@ -1165,6 +1210,47 @@ int
gf_d_type_from_ia_type(ia_type_t type);
int
+gf_syncfs(int fd);
+
+int
gf_nanosleep(uint64_t nsec);
+static inline time_t
+gf_time(void)
+{
+ return time(NULL);
+}
+
+/* Return delta value in microseconds. */
+
+static inline double
+gf_tvdiff(struct timeval *start, struct timeval *end)
+{
+ struct timeval t;
+
+ if (start->tv_usec > end->tv_usec)
+ t.tv_sec = end->tv_sec - 1, t.tv_usec = end->tv_usec + 1000000;
+ else
+ t.tv_sec = end->tv_sec, t.tv_usec = end->tv_usec;
+
+ return (double)(t.tv_sec - start->tv_sec) * 1e6 +
+ (double)(t.tv_usec - start->tv_usec);
+}
+
+/* Return delta value in nanoseconds. */
+
+static inline double
+gf_tsdiff(struct timespec *start, struct timespec *end)
+{
+ struct timespec t;
+
+ if (start->tv_nsec > end->tv_nsec)
+ t.tv_sec = end->tv_sec - 1, t.tv_nsec = end->tv_nsec + 1000000000;
+ else
+ t.tv_sec = end->tv_sec, t.tv_nsec = end->tv_nsec;
+
+ return (double)(t.tv_sec - start->tv_sec) * 1e9 +
+ (double)(t.tv_nsec - start->tv_nsec);
+}
+
#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h
index ce1c2100276..d0467c6dfb6 100644
--- a/libglusterfs/src/glusterfs/dict.h
+++ b/libglusterfs/src/glusterfs/dict.h
@@ -25,9 +25,6 @@ typedef struct _data_pair data_pair_t;
#define dict_add_sizen(this, key, value) dict_addn(this, key, SLEN(key), value)
-#define dict_get_with_ref_sizen(this, key, value) \
- dict_get_with_refn(this, key, SLEN(key), value)
-
#define dict_get_sizen(this, key) dict_getn(this, key, SLEN(key))
#define dict_del_sizen(this, key) dict_deln(this, key, SLEN(key))
@@ -98,7 +95,7 @@ struct _data {
char *data;
gf_atomic_t refcount;
gf_dict_data_type_t data_type;
- int32_t len;
+ uint32_t len;
gf_boolean_t is_static;
};
@@ -122,6 +119,8 @@ struct _dict {
gf_lock_t lock;
data_pair_t *members_internal;
data_pair_t free_pair;
+ /* Variable to store total keylen + value->len */
+ uint32_t totkvlen;
};
typedef gf_boolean_t (*dict_match_t)(dict_t *d, char *k, data_t *v, void *data);
@@ -136,6 +135,7 @@ int32_t
dict_set(dict_t *this, char *key, data_t *value);
int32_t
dict_setn(dict_t *this, char *key, const int keylen, data_t *value);
+
/* function to set a new key/value pair (without checking for duplicate) */
int32_t
dict_add(dict_t *this, char *key, data_t *value);
@@ -143,8 +143,6 @@ int32_t
dict_addn(dict_t *this, char *key, const int keylen, data_t *value);
int
dict_get_with_ref(dict_t *this, char *key, data_t **data);
-int
-dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data);
data_t *
dict_get(dict_t *this, char *key);
data_t *
diff --git a/libglusterfs/src/glusterfs/fd.h b/libglusterfs/src/glusterfs/fd.h
index 28906d34e4d..3ffaaa60504 100644
--- a/libglusterfs/src/glusterfs/fd.h
+++ b/libglusterfs/src/glusterfs/fd.h
@@ -106,6 +106,9 @@ fd_ref(fd_t *fd);
void
fd_unref(fd_t *fd);
+void
+fd_close(fd_t *fd);
+
fd_t *
fd_create(struct _inode *inode, pid_t pid);
diff --git a/libglusterfs/src/glusterfs/gf-event.h b/libglusterfs/src/glusterfs/gf-event.h
index c0f05e7c83b..40f8fbdf10a 100644
--- a/libglusterfs/src/glusterfs/gf-event.h
+++ b/libglusterfs/src/glusterfs/gf-event.h
@@ -12,6 +12,7 @@
#define _GF_EVENT_H_
#include <pthread.h>
+#include "common-utils.h"
#include "list.h"
struct event_pool;
@@ -31,6 +32,9 @@ typedef void (*event_handler_t)(int fd, int idx, int gen, void *data,
#define EVENT_EPOLL_SLOTS 1024
#define EVENT_MAX_THREADS 1024
+/* See rpcsvc.h to check why. */
+GF_STATIC_ASSERT(EVENT_MAX_THREADS % __BITS_PER_LONG == 0);
+
struct event_pool {
struct event_ops *ops;
diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h
index e50ee3046af..b22eaae6c2f 100644
--- a/libglusterfs/src/glusterfs/globals.h
+++ b/libglusterfs/src/glusterfs/globals.h
@@ -45,7 +45,7 @@
1 /* MIN is the fresh start op-version, mostly \
should not change */
#define GD_OP_VERSION_MAX \
- GD_OP_VERSION_8_0 /* MAX VERSION is the maximum \
+ GD_OP_VERSION_9_0 /* MAX VERSION is the maximum \
count in VME table, should \
keep changing with \
introduction of newer \
@@ -122,6 +122,8 @@
#define GD_OP_VERSION_8_0 80000 /* Op-version for GlusterFS 8.0 */
+#define GD_OP_VERSION_9_0 90000 /* Op-version for GlusterFS 9.0 */
+
#define GD_OP_VER_PERSISTENT_AFR_XATTRS GD_OP_VERSION_3_6_0
#include "glusterfs/xlator.h"
diff --git a/libglusterfs/src/glusterfs/glusterfs-acl.h b/libglusterfs/src/glusterfs/glusterfs-acl.h
index cae55e8062f..987bf5fab0b 100644
--- a/libglusterfs/src/glusterfs/glusterfs-acl.h
+++ b/libglusterfs/src/glusterfs/glusterfs-acl.h
@@ -143,7 +143,7 @@ gf_posix_acl_get_key(const acl_type_t type)
return acl_key;
}
-static inline const acl_type_t
+static inline acl_type_t
gf_posix_acl_get_type(const char *key)
{
acl_type_t type = 0;
diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h
index 6d6ac36cfd5..e6425618b7f 100644
--- a/libglusterfs/src/glusterfs/glusterfs.h
+++ b/libglusterfs/src/glusterfs/glusterfs.h
@@ -43,6 +43,9 @@
#define GF_YES 1
#define GF_NO 0
+#define IS_ERROR(ret) ((ret) < 0)
+#define IS_SUCCESS(ret) ((ret) >= 0)
+
#ifndef O_LARGEFILE
/* savannah bug #20053, patch for compiling on darwin */
#define O_LARGEFILE 0100000 /* from bits/fcntl.h */
@@ -422,7 +425,7 @@ static const char *const FOP_PRI_STRINGS[] = {"HIGH", "NORMAL", "LOW", "LEAST"};
static inline const char *
fop_pri_to_string(gf_fop_pri_t pri)
{
- if (pri < 0)
+ if (IS_ERROR(pri))
return "UNSPEC";
if (pri >= GF_FOP_PRI_MAX)
@@ -463,6 +466,8 @@ typedef struct _server_cmdline server_cmdline_t;
#define GF_OPTION_DISABLE _gf_false
#define GF_OPTION_DEFERRED 2
+typedef enum { _gf_none, _gf_memcheck, _gf_drd } gf_valgrind_tool;
+
struct _cmd_args {
/* basic options */
char *volfile_server;
@@ -555,7 +560,8 @@ struct _cmd_args {
/* Run this process with valgrind? Might want to prevent calling
* functions that prevent valgrind from working correctly, like
* dlclose(). */
- int valgrind;
+ gf_valgrind_tool vgtool;
+
int localtime_logging;
/* For the subdir mount */
@@ -727,6 +733,13 @@ struct _glusterfs_ctx {
} stats;
struct list_head volfile_list;
+ /* Add members to manage janitor threads for cleanup fd */
+ struct list_head janitor_fds;
+ pthread_cond_t fd_cond;
+ pthread_mutex_t fd_lock;
+ pthread_t janitor;
+ /* The variable is use to save total posix xlator count */
+ uint32_t pxl_count;
char volume_id[GF_UUID_BUF_SIZE]; /* Used only in protocol/client */
};
diff --git a/libglusterfs/src/glusterfs/latency.h b/libglusterfs/src/glusterfs/latency.h
index ed47b1f0cbc..4d601bbcbd6 100644
--- a/libglusterfs/src/glusterfs/latency.h
+++ b/libglusterfs/src/glusterfs/latency.h
@@ -11,13 +11,23 @@
#ifndef __LATENCY_H__
#define __LATENCY_H__
-#include "glusterfs/glusterfs.h"
+#include <inttypes.h>
+#include <time.h>
-typedef struct fop_latency {
- double min; /* min time for the call (microseconds) */
- double max; /* max time for the call (microseconds) */
- double total; /* total time (microseconds) */
+typedef struct _gf_latency {
+ uint64_t min; /* min time for the call (nanoseconds) */
+ uint64_t max; /* max time for the call (nanoseconds) */
+ uint64_t total; /* total time (nanoseconds) */
uint64_t count;
-} fop_latency_t;
+} gf_latency_t;
+gf_latency_t *
+gf_latency_new(size_t n);
+
+void
+gf_latency_reset(gf_latency_t *lat);
+
+void
+gf_latency_update(gf_latency_t *lat, struct timespec *begin,
+ struct timespec *end);
#endif /* __LATENCY_H__ */
diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h
index 90fb8820c74..e5b3276d047 100644
--- a/libglusterfs/src/glusterfs/mem-pool.h
+++ b/libglusterfs/src/glusterfs/mem-pool.h
@@ -202,6 +202,24 @@ out:
return dup_mem;
}
+#ifdef GF_DISABLE_MEMPOOL
+
+/* No-op memory pool enough to fit current API without massive redesign. */
+
+struct mem_pool {
+ unsigned long sizeof_type;
+};
+
+#define mem_pools_init() \
+ do { \
+ } while (0)
+#define mem_pools_fini() \
+ do { \
+ } while (0)
+#define mem_pool_thread_destructor(pool_list) (void)pool_list
+
+#else /* !GF_DISABLE_MEMPOOL */
+
/* kind of 'header' for the actual mem_pool_shared structure, this might make
* it possible to dump some more details in a statedump */
struct mem_pool {
@@ -209,10 +227,11 @@ struct mem_pool {
unsigned long sizeof_type;
unsigned long count; /* requested pool size (unused) */
char *name;
- gf_atomic_t active; /* current allocations */
+ char *xl_name;
+ gf_atomic_t active; /* current allocations */
#ifdef DEBUG
- gf_atomic_t hit; /* number of allocations served from pt_pool */
- gf_atomic_t miss; /* number of std allocs due to miss */
+ gf_atomic_t hit; /* number of allocations served from pt_pool */
+ gf_atomic_t miss; /* number of std allocs due to miss */
#endif
struct list_head owner; /* glusterfs_ctx_t->mempool_list */
glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */
@@ -286,6 +305,10 @@ void
mem_pools_init(void); /* start the pool_sweeper thread */
void
mem_pools_fini(void); /* cleanup memory pools */
+void
+mem_pool_thread_destructor(per_thread_pool_list_t *pool_list);
+
+#endif /* GF_DISABLE_MEMPOOL */
struct mem_pool *
mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
@@ -308,9 +331,6 @@ void
mem_pool_destroy(struct mem_pool *pool);
void
-mem_pool_thread_destructor(per_thread_pool_list_t *pool_list);
-
-void
gf_mem_acct_enable_set(void *ctx);
#endif /* _MEM_POOL_H */
diff --git a/libglusterfs/src/glusterfs/mem-types.h b/libglusterfs/src/glusterfs/mem-types.h
index 36cf7820ad5..d45d5b68c91 100644
--- a/libglusterfs/src/glusterfs/mem-types.h
+++ b/libglusterfs/src/glusterfs/mem-types.h
@@ -133,6 +133,7 @@ enum gf_common_mem_types_ {
gf_common_volfile_t,
gf_common_mt_mgmt_v3_lock_timer_t, /* used only in one location */
gf_common_mt_server_cmdline_t, /* used only in one location */
+ gf_common_mt_latency_t,
gf_common_mt_end
};
#endif
diff --git a/libglusterfs/src/glusterfs/stack.h b/libglusterfs/src/glusterfs/stack.h
index 17585508a22..536a330d38b 100644
--- a/libglusterfs/src/glusterfs/stack.h
+++ b/libglusterfs/src/glusterfs/stack.h
@@ -45,6 +45,9 @@ typedef int32_t (*ret_fn_t)(call_frame_t *frame, call_frame_t *prev_frame,
xlator_t *this, int32_t op_ret, int32_t op_errno,
...);
+void
+gf_frame_latency_update(call_frame_t *frame);
+
struct call_pool {
union {
struct list_head all_frames;
@@ -149,8 +152,6 @@ struct _call_stack {
} while (0);
struct xlator_fops;
-void
-gf_update_latency(call_frame_t *frame);
static inline void
FRAME_DESTROY(call_frame_t *frame)
@@ -158,7 +159,7 @@ FRAME_DESTROY(call_frame_t *frame)
void *local = NULL;
if (frame->root->ctx->measure_latency)
- gf_update_latency(frame);
+ gf_frame_latency_update(frame);
list_del_init(&frame->frames);
if (frame->local) {
@@ -429,6 +430,7 @@ call_stack_alloc_groups(call_stack_t *stack, int ngrps)
if (ngrps <= SMALL_GROUP_COUNT) {
stack->groups = stack->groups_small;
} else {
+ GF_FREE(stack->groups_large);
stack->groups_large = GF_CALLOC(ngrps, sizeof(gid_t),
gf_common_mt_groups_t);
if (!stack->groups_large)
@@ -442,6 +444,12 @@ call_stack_alloc_groups(call_stack_t *stack, int ngrps)
}
static inline int
+call_stack_groups_capacity(call_stack_t *stack)
+{
+ return max(stack->ngrps, SMALL_GROUP_COUNT);
+}
+
+static inline int
call_frames_count(call_stack_t *call_stack)
{
call_frame_t *pos;
diff --git a/libglusterfs/src/glusterfs/statedump.h b/libglusterfs/src/glusterfs/statedump.h
index 89d04f94587..ce082706bdf 100644
--- a/libglusterfs/src/glusterfs/statedump.h
+++ b/libglusterfs/src/glusterfs/statedump.h
@@ -127,4 +127,6 @@ gf_proc_dump_xlator_meminfo(xlator_t *this, strfd_t *strfd);
void
gf_proc_dump_xlator_profile(xlator_t *this, strfd_t *strfd);
+void
+gf_latency_statedump_and_reset(char *key, gf_latency_t *lat);
#endif /* STATEDUMP_H */
diff --git a/libglusterfs/src/glusterfs/store.h b/libglusterfs/src/glusterfs/store.h
index c8be544e164..a1f70c7b840 100644
--- a/libglusterfs/src/glusterfs/store.h
+++ b/libglusterfs/src/glusterfs/store.h
@@ -95,7 +95,7 @@ int32_t
gf_store_iter_get_matching(gf_store_iter_t *iter, char *key, char **value);
int32_t
-gf_store_iter_destroy(gf_store_iter_t *iter);
+gf_store_iter_destroy(gf_store_iter_t **iter);
char *
gf_store_strerror(gf_store_op_errno_t op_errno);
diff --git a/libglusterfs/src/glusterfs/syncop.h b/libglusterfs/src/glusterfs/syncop.h
index bfdec491ba8..4e9241a32fc 100644
--- a/libglusterfs/src/glusterfs/syncop.h
+++ b/libglusterfs/src/glusterfs/syncop.h
@@ -16,6 +16,8 @@
#include <ucontext.h>
#include "glusterfs/dict.h" // for dict_t
#include "glusterfs/stack.h" // for call_frame_t, STACK_DESTROY, STACK_...
+#include "glusterfs/timer.h"
+
#define SYNCENV_PROC_MAX 16
#define SYNCENV_PROC_MIN 2
#define SYNCPROC_IDLE_TIME 600
@@ -29,9 +31,15 @@
#define SYNCOPCTX_PID 0x00000008
#define SYNCOPCTX_LKOWNER 0x00000010
+#ifdef HAVE_TSAN_API
+/* Currently hardcoded within thread context maintained by the sanitizer. */
+#define TSAN_THREAD_NAMELEN 64
+#endif
+
struct synctask;
struct syncproc;
struct syncenv;
+struct synccond;
typedef int (*synctask_cbk_t)(int ret, call_frame_t *frame, void *opaque);
@@ -55,9 +63,12 @@ struct synctask {
call_frame_t *opframe;
synctask_cbk_t synccbk;
synctask_fn_t syncfn;
- synctask_state_t state;
+ struct timespec *delta;
+ gf_timer_t *timer;
+ struct synccond *synccond;
void *opaque;
void *stack;
+ synctask_state_t state;
int woken;
int slept;
int ret;
@@ -65,6 +76,13 @@ struct synctask {
uid_t uid;
gid_t gid;
+#ifdef HAVE_TSAN_API
+ struct {
+ void *fiber;
+ char name[TSAN_THREAD_NAMELEN];
+ } tsan;
+#endif
+
ucontext_t ctx;
struct syncproc *proc;
@@ -77,6 +95,14 @@ struct synctask {
struct syncproc {
pthread_t processor;
+
+#ifdef HAVE_TSAN_API
+ struct {
+ void *fiber;
+ char name[TSAN_THREAD_NAMELEN];
+ } tsan;
+#endif
+
ucontext_t sched;
struct syncenv *env;
struct synctask *current;
@@ -85,19 +111,21 @@ struct syncproc {
/* hosts the scheduler thread and framework for executing synctasks */
struct syncenv {
struct syncproc proc[SYNCENV_PROC_MAX];
- int procs;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
struct list_head runq;
- int runcount;
struct list_head waitq;
- int waitcount;
+
+ int procs;
+ int procs_idle;
+
+ int runcount;
int procmin;
int procmax;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
size_t stacksize;
int destroy; /* FLAG to mark syncenv is in destroy mode
@@ -123,6 +151,13 @@ struct synclock {
};
typedef struct synclock synclock_t;
+struct synccond {
+ pthread_mutex_t pmutex;
+ pthread_cond_t pcond;
+ struct list_head waitq;
+};
+typedef struct synccond synccond_t;
+
struct syncbarrier {
gf_boolean_t initialized; /*Set on successful initialization*/
pthread_mutex_t guard; /* guard the remaining members, pair @cond */
@@ -219,7 +254,7 @@ struct syncopctx {
#define __yield(args) \
do { \
if (args->task) { \
- synctask_yield(args->task); \
+ synctask_yield(args->task, NULL); \
} else { \
pthread_mutex_lock(&args->mutex); \
{ \
@@ -310,7 +345,9 @@ synctask_join(struct synctask *task);
void
synctask_wake(struct synctask *task);
void
-synctask_yield(struct synctask *task);
+synctask_yield(struct synctask *task, struct timespec *delta);
+void
+synctask_sleep(int32_t secs);
void
synctask_waitfor(struct synctask *task, int count);
@@ -408,6 +445,24 @@ synclock_trylock(synclock_t *lock);
int
synclock_unlock(synclock_t *lock);
+int32_t
+synccond_init(synccond_t *cond);
+
+void
+synccond_destroy(synccond_t *cond);
+
+int
+synccond_wait(synccond_t *cond, synclock_t *lock);
+
+int
+synccond_timedwait(synccond_t *cond, synclock_t *lock, struct timespec *delta);
+
+void
+synccond_signal(synccond_t *cond);
+
+void
+synccond_broadcast(synccond_t *cond);
+
int
syncbarrier_init(syncbarrier_t *barrier);
int
diff --git a/libglusterfs/src/glusterfs/syscall.h b/libglusterfs/src/glusterfs/syscall.h
index 91e921aea50..b6d3ab4f2ad 100644
--- a/libglusterfs/src/glusterfs/syscall.h
+++ b/libglusterfs/src/glusterfs/syscall.h
@@ -266,4 +266,13 @@ ssize_t
sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out,
size_t len, unsigned int flags);
+int
+sys_kill(pid_t pid, int sig);
+
+#ifdef __FreeBSD__
+int
+sys_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ const void *newp, size_t newlen);
+#endif
+
#endif /* __SYSCALL_H__ */
diff --git a/libglusterfs/src/glusterfs/xlator.h b/libglusterfs/src/glusterfs/xlator.h
index c94bd75cf1c..4fd3abdaeff 100644
--- a/libglusterfs/src/glusterfs/xlator.h
+++ b/libglusterfs/src/glusterfs/xlator.h
@@ -702,6 +702,8 @@ typedef size_t (*cbk_inodectx_size_t)(xlator_t *this, inode_t *inode);
typedef size_t (*cbk_fdctx_size_t)(xlator_t *this, fd_t *fd);
+typedef void (*cbk_fdclose_t)(xlator_t *this, fd_t *fd);
+
struct xlator_cbks {
cbk_forget_t forget;
cbk_release_t release;
@@ -712,6 +714,8 @@ struct xlator_cbks {
cbk_ictxmerge_t ictxmerge;
cbk_inodectx_size_t ictxsize;
cbk_fdctx_size_t fdctxsize;
+ cbk_fdclose_t fdclose;
+ cbk_fdclose_t fdclosedir;
};
typedef int32_t (*dumpop_priv_t)(xlator_t *this);
@@ -801,7 +805,7 @@ struct _xlator {
struct {
/* for latency measurement */
- fop_latency_t latencies[GF_FOP_MAXVALUE];
+ gf_latency_t latencies[GF_FOP_MAXVALUE];
/* for latency measurement */
fop_metrics_t metrics[GF_FOP_MAXVALUE];