summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src')
-rw-r--r--libglusterfs/src/Makefile.am15
-rw-r--r--libglusterfs/src/call-stub.c67
-rw-r--r--libglusterfs/src/call-stub.h16
-rw-r--r--libglusterfs/src/circ-buff.c30
-rw-r--r--libglusterfs/src/circ-buff.h5
-rw-r--r--libglusterfs/src/client_t.c193
-rw-r--r--libglusterfs/src/client_t.h77
-rw-r--r--libglusterfs/src/common-utils.c107
-rw-r--r--libglusterfs/src/common-utils.h4
-rw-r--r--libglusterfs/src/defaults.c33
-rw-r--r--libglusterfs/src/defaults.h18
-rw-r--r--libglusterfs/src/dict.c32
-rw-r--r--libglusterfs/src/event-history.c6
-rw-r--r--libglusterfs/src/event-history.h3
-rw-r--r--libglusterfs/src/gidcache.c15
-rw-r--r--libglusterfs/src/gidcache.h1
-rw-r--r--libglusterfs/src/globals.c58
-rw-r--r--libglusterfs/src/globals.h4
-rw-r--r--libglusterfs/src/glusterfs-acl.h81
-rw-r--r--libglusterfs/src/glusterfs.h50
-rw-r--r--libglusterfs/src/graph.c185
-rw-r--r--libglusterfs/src/graph.l4
-rw-r--r--libglusterfs/src/graph.y84
-rw-r--r--libglusterfs/src/inode.c222
-rw-r--r--libglusterfs/src/inode.h62
-rw-r--r--libglusterfs/src/list.h28
-rw-r--r--libglusterfs/src/lock-table.c133
-rw-r--r--libglusterfs/src/lock-table.h54
-rw-r--r--libglusterfs/src/logging.h4
-rw-r--r--libglusterfs/src/mem-pool.h2
-rw-r--r--libglusterfs/src/mem-types.h7
-rw-r--r--libglusterfs/src/run.c2
-rw-r--r--libglusterfs/src/stack.h9
-rw-r--r--libglusterfs/src/store.c33
-rw-r--r--libglusterfs/src/syncop.c191
-rw-r--r--libglusterfs/src/syncop.h80
-rw-r--r--libglusterfs/src/timer.c27
-rw-r--r--libglusterfs/src/timer.h4
-rw-r--r--libglusterfs/src/timespec.c68
-rw-r--r--libglusterfs/src/timespec.h24
-rw-r--r--libglusterfs/src/xlator.c67
-rw-r--r--libglusterfs/src/xlator.h36
42 files changed, 1592 insertions, 549 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index fc54f49a3..907399ae6 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -15,7 +15,7 @@ CONTRIB_BUILDDIR = $(top_builddir)/contrib
libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
hashfn.c defaults.c common-utils.c timer.c inode.c call-stub.c \
compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c \
- iobuf.c globals.c statedump.c stack.c checksum.c daemon.c \
+ iobuf.c globals.c statedump.c stack.c checksum.c daemon.c timespec.c \
$(CONTRIBDIR)/rbtree/rb.c rbthash.c store.c latency.c \
graph.c $(CONTRIBDIR)/uuid/clear.c $(CONTRIBDIR)/uuid/copy.c \
$(CONTRIBDIR)/uuid/gen_uuid.c $(CONTRIBDIR)/uuid/pack.c \
@@ -23,17 +23,16 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
$(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c \
$(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c \
graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c \
- event-history.c gidcache.c ctx.c client_t.c lock-table.c \
+ event-history.c gidcache.c ctx.c client_t.c event-poll.c event-epoll.c \
$(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c \
- $(CONTRIBDIR)/stdlib/gf_mkostemp.c \
- event-poll.c event-epoll.c
+ $(CONTRIBDIR)/stdlib/gf_mkostemp.c
nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c gf-error-codes.h
BUILT_SOURCES = graph.lex.c
-noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h \
+noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h timespec.h \
logging.h xlator.h stack.h timer.h list.h inode.h call-stub.h compat.h \
fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h \
gf-dirent.h locking.h syscall.h iobuf.h globals.h statedump.h \
@@ -42,16 +41,16 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h \
$(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \
$(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h \
run.h options.h lkowner.h fd-lk.h circ-buff.h event-history.h \
- gidcache.h client_t.h lock-table.h
+ gidcache.h client_t.h glusterfs-acl.h
EXTRA_DIST = graph.l graph.y
graph.lex.c: graph.l y.tab.h
- $(LEX) -t $(srcdir)/graph.l > $@
+ $(LEX) -Pgraphyy -t $(srcdir)/graph.l > $@
y.tab.c: y.tab.h
y.tab.h: graph.y
- $(YACC) -d $(srcdir)/graph.y
+ $(YACC) -p graphyy -d $(srcdir)/graph.y
CLEANFILES = graph.lex.c y.tab.c y.tab.h
CONFIG_CLEAN_FILES = $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c
index 2f07a0074..ac79cf071 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -2241,6 +2241,62 @@ out:
}
+call_stub_t *
+fop_zerofill_cbk_stub(call_frame_t *frame, fop_zerofill_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn_cbk.zerofill = fn;
+
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+
+ if (statpre)
+ stub->args_cbk.prestat = *statpre;
+ if (statpost)
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ return stub;
+}
+
+call_stub_t *
+fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+
+ stub = stub_new (frame, 1, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn.zerofill = fn;
+
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+
+ stub->args.offset = offset;
+ stub->args.size = len;
+
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ return stub;
+
+}
+
+
static void
call_resume_wind (call_stub_t *stub)
{
@@ -2468,6 +2524,12 @@ call_resume_wind (call_stub_t *stub)
stub->args.fd, stub->args.offset,
stub->args.size, stub->args.xdata);
break;
+ case GF_FOP_ZEROFILL:
+ stub->fn.zerofill(stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.offset,
+ stub->args.size, stub->args.xdata);
+ break;
+
default:
gf_log_callingfn ("call-stub", GF_LOG_ERROR,
"Invalid value of FOP (%d)",
@@ -2670,6 +2732,11 @@ call_resume_unwind (call_stub_t *stub)
STUB_UNWIND(stub, discard, &stub->args_cbk.prestat,
&stub->args_cbk.poststat, stub->args_cbk.xdata);
break;
+ case GF_FOP_ZEROFILL:
+ STUB_UNWIND(stub, zerofill, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+
default:
gf_log_callingfn ("call-stub", GF_LOG_ERROR,
"Invalid value of FOP (%d)",
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
index f0872b121..45bef8044 100644
--- a/libglusterfs/src/call-stub.h
+++ b/libglusterfs/src/call-stub.h
@@ -71,6 +71,7 @@ typedef struct {
fop_fsetattr_t fsetattr;
fop_fallocate_t fallocate;
fop_discard_t discard;
+ fop_zerofill_t zerofill;
} fn;
union {
@@ -117,6 +118,7 @@ typedef struct {
fop_fsetattr_cbk_t fsetattr;
fop_fallocate_cbk_t fallocate;
fop_discard_cbk_t discard;
+ fop_zerofill_cbk_t zerofill;
} fn_cbk;
struct {
@@ -745,6 +747,20 @@ fop_discard_cbk_stub(call_frame_t *frame,
struct iatt *statpre, struct iatt *statpost,
dict_t *xdata);
+call_stub_t *
+fop_zerofill_stub(call_frame_t *frame,
+ fop_zerofill_t fn,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
+call_stub_t *
+fop_zerofill_cbk_stub(call_frame_t *frame,
+ fop_zerofill_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata);
+
void call_resume (call_stub_t *stub);
void call_stub_destroy (call_stub_t *stub);
void call_unwind_error (call_stub_t *stub, int op_ret, int op_errno);
diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c
index a48c92879..484ce7dc9 100644
--- a/libglusterfs/src/circ-buff.c
+++ b/libglusterfs/src/circ-buff.c
@@ -10,6 +10,17 @@
#include "circ-buff.h"
+void
+cb_destroy_data (circular_buffer_t *cb,
+ void (*destroy_buffer_data) (void *data))
+{
+ if (destroy_buffer_data)
+ destroy_buffer_data (cb->data);
+ GF_FREE (cb->data);
+ return;
+}
+
+
/* hold lock while calling this function */
int
__cb_add_entry_buffer (buffer_t *buffer, void *item)
@@ -29,7 +40,8 @@ __cb_add_entry_buffer (buffer_t *buffer, void *item)
if (buffer->cb[buffer->w_index]) {
ptr = buffer->cb[buffer->w_index];
if (ptr->data) {
- GF_FREE (ptr->data);
+ cb_destroy_data (ptr,
+ buffer->destroy_buffer_data);
ptr->data = NULL;
GF_FREE (ptr);
}
@@ -131,7 +143,8 @@ cb_buffer_dump (buffer_t *buffer, void *data,
}
buffer_t *
-cb_buffer_new (size_t buffer_size, gf_boolean_t use_once)
+cb_buffer_new (size_t buffer_size, gf_boolean_t use_once,
+ void (*destroy_buffer_data) (void *data))
{
buffer_t *buffer = NULL;
@@ -157,6 +170,7 @@ cb_buffer_new (size_t buffer_size, gf_boolean_t use_once)
buffer->size_buffer = buffer_size;
buffer->use_once = use_once;
buffer->used_len = 0;
+ buffer->destroy_buffer_data = destroy_buffer_data;
pthread_mutex_init (&buffer->lock, NULL);
out:
@@ -166,12 +180,18 @@ out:
void
cb_buffer_destroy (buffer_t *buffer)
{
- int i = 0;
-
+ int i = 0;
+ circular_buffer_t *ptr = NULL;
if (buffer) {
if (buffer->cb) {
for (i = 0; i < buffer->used_len ; i++) {
- GF_FREE (buffer->cb[i]);
+ ptr = buffer->cb[i];
+ if (ptr->data) {
+ cb_destroy_data (ptr,
+ buffer->destroy_buffer_data);
+ ptr->data = NULL;
+ GF_FREE (ptr);
+ }
}
GF_FREE (buffer->cb);
}
diff --git a/libglusterfs/src/circ-buff.h b/libglusterfs/src/circ-buff.h
index 5b5acc387..e3459f5e3 100644
--- a/libglusterfs/src/circ-buff.h
+++ b/libglusterfs/src/circ-buff.h
@@ -38,7 +38,7 @@ struct _buffer {
/* indicates the amount of circular buffer used. */
circular_buffer_t **cb;
-
+ void (*destroy_buffer_data) (void *data);
pthread_mutex_t lock;
};
@@ -51,7 +51,8 @@ void
cb_buffer_show (buffer_t *buffer);
buffer_t *
-cb_buffer_new (size_t buffer_size,gf_boolean_t use_buffer_once);
+cb_buffer_new (size_t buffer_size,gf_boolean_t use_buffer_once,
+ void (*destroy_data) (void *data));
void
cb_buffer_destroy (buffer_t *buffer);
diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c
index f0d66da3a..06447dc5d 100644
--- a/libglusterfs/src/client_t.c
+++ b/libglusterfs/src/client_t.c
@@ -11,9 +11,9 @@
#include "glusterfs.h"
#include "dict.h"
#include "statedump.h"
-#include "lock-table.h"
-#include "rpcsvc.h"
#include "client_t.h"
+#include "list.h"
+#include "rpcsvc.h"
#ifndef _CONFIG_H
@@ -103,7 +103,7 @@ gf_clienttable_alloc (void)
clienttable_t *clienttable = NULL;
clienttable =
- GF_CALLOC (1, sizeof (*clienttable), gf_common_mt_clienttable_t);
+ GF_CALLOC (1, sizeof (clienttable_t), gf_common_mt_clienttable_t);
if (!clienttable)
return NULL;
@@ -116,14 +116,11 @@ gf_clienttable_alloc (void)
void
gf_client_clienttable_destroy (clienttable_t *clienttable)
{
- struct list_head list = {0, };
client_t *client = NULL;
cliententry_t *cliententries = NULL;
uint32_t client_count = 0;
int32_t i = 0;
- INIT_LIST_HEAD (&list);
-
if (!clienttable) {
gf_log_callingfn ("client_t", GF_LOG_WARNING, "!clienttable");
return;
@@ -152,9 +149,8 @@ gf_client_clienttable_destroy (clienttable_t *clienttable)
}
}
-
client_t *
-gf_client_get (xlator_t *this, rpcsvc_auth_data_t *cred, char *client_uid)
+gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid)
{
client_t *client = NULL;
cliententry_t *cliententry = NULL;
@@ -181,13 +177,13 @@ gf_client_get (xlator_t *this, rpcsvc_auth_data_t *cred, char *client_uid)
* look for matching client_uid, _and_
* if auth was used, matching auth flavour and data
*/
- if (strcmp (client_uid, client->server_ctx.client_uid) == 0 &&
+ if (strcmp (client_uid, client->client_uid) == 0 &&
(cred->flavour != AUTH_NONE &&
- (cred->flavour == client->server_ctx.auth.flavour &&
- (size_t) cred->datalen == client->server_ctx.auth.len &&
+ (cred->flavour == client->auth.flavour &&
+ (size_t) cred->datalen == client->auth.len &&
memcmp (cred->authdata,
- client->server_ctx.auth.data,
- client->server_ctx.auth.len) == 0))) {
+ client->auth.data,
+ client->auth.len) == 0))) {
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
__sync_add_and_fetch(&client->ref.bind, 1);
#else
@@ -211,58 +207,49 @@ gf_client_get (xlator_t *this, rpcsvc_auth_data_t *cred, char *client_uid)
}
client->this = this;
- /* client->server_ctx.lk_version = 0; redundant */
- LOCK_INIT (&client->server_ctx.fdtable_lock);
- LOCK_INIT (&client->locks_ctx.ltable_lock);
LOCK_INIT (&client->scratch_ctx.lock);
LOCK_INIT (&client->ref.lock);
- client->server_ctx.client_uid = gf_strdup (client_uid);
- if (client->server_ctx.client_uid == NULL) {
- errno = ENOMEM;
+ client->client_uid = gf_strdup (client_uid);
+ if (client->client_uid == NULL) {
GF_FREE (client);
client = NULL;
- goto unlock;
- }
- client->server_ctx.fdtable = gf_fd_fdtable_alloc ();
- if (client->server_ctx.fdtable == NULL) {
errno = ENOMEM;
- GF_FREE (client->server_ctx.client_uid);
- GF_FREE (client);
- client = NULL;
goto unlock;
}
-
- client->locks_ctx.ltable = gf_lock_table_new ();
- if (client->locks_ctx.ltable == NULL) {
- errno = ENOMEM;
- GF_FREE (client->server_ctx.fdtable);
- GF_FREE (client->server_ctx.client_uid);
+ client->scratch_ctx.count = GF_CLIENTCTX_INITIAL_SIZE;
+ client->scratch_ctx.ctx =
+ GF_CALLOC (GF_CLIENTCTX_INITIAL_SIZE,
+ sizeof (struct client_ctx),
+ gf_common_mt_client_ctx);
+ if (client->scratch_ctx.ctx == NULL) {
+ GF_FREE (client->client_uid);
GF_FREE (client);
client = NULL;
+ errno = ENOMEM;
goto unlock;
}
/* no need to do these atomically here */
client->ref.bind = client->ref.count = 1;
- client->server_ctx.auth.flavour = cred->flavour;
+ client->auth.flavour = cred->flavour;
if (cred->flavour != AUTH_NONE) {
- client->server_ctx.auth.data =
- GF_CALLOC (1, cred->datalen, gf_common_mt_client_t);
- if (client->server_ctx.auth.data == NULL) {
- errno = ENOMEM;
- GF_FREE (client->locks_ctx.ltable);
- GF_FREE (client->server_ctx.fdtable);
- GF_FREE (client->server_ctx.client_uid);
+ client->auth.data =
+ GF_CALLOC (1, cred->datalen,
+ gf_common_mt_client_t);
+ if (client->auth.data == NULL) {
+ GF_FREE (client->scratch_ctx.ctx);
+ GF_FREE (client->client_uid);
GF_FREE (client);
client = NULL;
+ errno = ENOMEM;
goto unlock;
}
- memcpy (client->server_ctx.auth.data, cred->authdata,
+ memcpy (client->auth.data, cred->authdata,
cred->datalen);
- client->server_ctx.auth.len = cred->datalen;
+ client->auth.len = cred->datalen;
}
client->tbl_index = clienttable->first_free;
@@ -301,7 +288,7 @@ gf_client_put (client_t *client, gf_boolean_t *detached)
if (unref) {
gf_log (THIS->name, GF_LOG_INFO, "Shutting down connection %s",
- client->server_ctx.client_uid);
+ client->client_uid);
if (detached)
*detached = _gf_true;
gf_client_unref (client);
@@ -333,7 +320,9 @@ gf_client_ref (client_t *client)
static void
client_destroy (client_t *client)
{
- clienttable_t *clienttable = NULL;
+ clienttable_t *clienttable = NULL;
+ glusterfs_graph_t *gtrav = NULL;
+ xlator_t *xtrav = NULL;
if (client == NULL){
gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid argument");
@@ -342,8 +331,6 @@ client_destroy (client_t *client)
clienttable = client->this->ctx->clienttable;
- LOCK_DESTROY (&client->server_ctx.fdtable_lock);
- LOCK_DESTROY (&client->locks_ctx.ltable_lock);
LOCK_DESTROY (&client->scratch_ctx.lock);
LOCK_DESTROY (&client->ref.lock);
@@ -356,17 +343,44 @@ client_destroy (client_t *client)
}
UNLOCK (&clienttable->lock);
- GF_FREE (client->server_ctx.auth.data);
+ list_for_each_entry (gtrav, &client->this->ctx->graphs, list) {
+ xtrav = gtrav->top;
+ while (xtrav != NULL) {
+ if (xtrav->cbks->client_destroy != NULL)
+ xtrav->cbks->client_destroy (xtrav, client);
+ xtrav = xtrav->next;
+ }
+ }
+ GF_FREE (client->auth.data);
GF_FREE (client->scratch_ctx.ctx);
- GF_FREE (client->locks_ctx.ltable);
- GF_FREE (client->server_ctx.fdtable);
- GF_FREE (client->server_ctx.client_uid);
+ GF_FREE (client->client_uid);
GF_FREE (client);
out:
return;
}
+int
+gf_client_disconnect (client_t *client)
+{
+ int ret = 0;
+ glusterfs_graph_t *gtrav = NULL;
+ xlator_t *xtrav = NULL;
+
+ list_for_each_entry (gtrav, &client->this->ctx->graphs, list) {
+ xtrav = gtrav->top;
+ while (xtrav != NULL) {
+ if (xtrav->cbks->client_disconnect != NULL)
+ if (xtrav->cbks->client_disconnect (xtrav, client) != 0)
+ ret = -1;
+ xtrav = xtrav->next;
+ }
+ }
+
+ return ret;
+}
+
+
void
gf_client_unref (client_t *client)
{
@@ -392,37 +406,33 @@ gf_client_unref (client_t *client)
}
-int
-__client_ctx_set (client_t *client, xlator_t *xlator, uint64_t value)
+static int
+client_ctx_set_int (client_t *client, void *key, void *value)
{
int index = 0;
int ret = 0;
int set_idx = -1;
- if (!client || !xlator)
- return -1;
-
for (index = 0; index < client->scratch_ctx.count; index++) {
- if (!client->scratch_ctx.ctx[index].key) {
+ if (!client->scratch_ctx.ctx[index].ctx_key) {
if (set_idx == -1)
set_idx = index;
/* dont break, to check if key already exists
further on */
}
- if (client->scratch_ctx.ctx[index].xl_key == xlator) {
+ if (client->scratch_ctx.ctx[index].ctx_key == key) {
set_idx = index;
break;
}
}
if (set_idx == -1) {
- gf_log_callingfn ("", GF_LOG_WARNING, "%p %s", client, xlator->name);
ret = -1;
goto out;
}
- client->scratch_ctx.ctx[set_idx].xl_key = xlator;
- client->scratch_ctx.ctx[set_idx].value = value;
+ client->scratch_ctx.ctx[set_idx].ctx_key = key;
+ client->scratch_ctx.ctx[set_idx].ctx_value = value;
out:
return ret;
@@ -430,18 +440,16 @@ out:
int
-client_ctx_set (client_t *client, xlator_t *xlator, uint64_t value)
+client_ctx_set (client_t *client, void *key, void *value)
{
int ret = 0;
- if (!client || !xlator) {
- gf_log_callingfn ("", GF_LOG_WARNING, "%p %p", client, xlator);
+ if (!client || !key)
return -1;
- }
LOCK (&client->scratch_ctx.lock);
{
- ret = __client_ctx_set (client, xlator, value);
+ ret = client_ctx_set_int (client, key, value);
}
UNLOCK (&client->scratch_ctx.lock);
@@ -449,17 +457,14 @@ client_ctx_set (client_t *client, xlator_t *xlator, uint64_t value)
}
-int
-__client_ctx_get (client_t *client, xlator_t *xlator, uint64_t *value)
+static int
+client_ctx_get_int (client_t *client, void *key, void **value)
{
int index = 0;
int ret = 0;
- if (!client || !xlator)
- return -1;
-
for (index = 0; index < client->scratch_ctx.count; index++) {
- if (client->scratch_ctx.ctx[index].xl_key == xlator)
+ if (client->scratch_ctx.ctx[index].ctx_key == key)
break;
}
@@ -469,7 +474,7 @@ __client_ctx_get (client_t *client, xlator_t *xlator, uint64_t *value)
}
if (value)
- *value = client->scratch_ctx.ctx[index].value;
+ *value = client->scratch_ctx.ctx[index].ctx_value;
out:
return ret;
@@ -477,16 +482,16 @@ out:
int
-client_ctx_get (client_t *client, xlator_t *xlator, uint64_t *value)
+client_ctx_get (client_t *client, void *key, void **value)
{
int ret = 0;
- if (!client || !xlator)
+ if (!client || !key)
return -1;
LOCK (&client->scratch_ctx.lock);
{
- ret = __client_ctx_get (client, xlator, value);
+ ret = client_ctx_get_int (client, key, value);
}
UNLOCK (&client->scratch_ctx.lock);
@@ -494,17 +499,14 @@ client_ctx_get (client_t *client, xlator_t *xlator, uint64_t *value)
}
-int
-__client_ctx_del (client_t *client, xlator_t *xlator, uint64_t *value)
+static int
+client_ctx_del_int (client_t *client, void *key, void **value)
{
int index = 0;
int ret = 0;
- if (!client || !xlator)
- return -1;
-
for (index = 0; index < client->scratch_ctx.count; index++) {
- if (client->scratch_ctx.ctx[index].xl_key == xlator)
+ if (client->scratch_ctx.ctx[index].ctx_key == key)
break;
}
@@ -514,10 +516,10 @@ __client_ctx_del (client_t *client, xlator_t *xlator, uint64_t *value)
}
if (value)
- *value = client->scratch_ctx.ctx[index].value;
+ *value = client->scratch_ctx.ctx[index].ctx_value;
- client->scratch_ctx.ctx[index].key = 0;
- client->scratch_ctx.ctx[index].value = 0;
+ client->scratch_ctx.ctx[index].ctx_key = 0;
+ client->scratch_ctx.ctx[index].ctx_value = 0;
out:
return ret;
@@ -525,16 +527,16 @@ out:
int
-client_ctx_del (client_t *client, xlator_t *xlator, uint64_t *value)
+client_ctx_del (client_t *client, void *key, void **value)
{
int ret = 0;
- if (!client || !xlator)
+ if (!client || !key)
return -1;
LOCK (&client->scratch_ctx.lock);
{
- ret = __client_ctx_del (client, xlator, value);
+ ret = client_ctx_del_int (client, key, value);
}
UNLOCK (&client->scratch_ctx.lock);
@@ -659,11 +661,13 @@ out:
int
gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict)
{
- client_t *client = NULL;
clienttable_t *clienttable = NULL;
int count = 0;
int ret = -1;
+#ifdef NOTYET
+ client_t *client = NULL;
char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+#endif
GF_VALIDATE_OR_GOTO (THIS->name, this, out);
GF_VALIDATE_OR_GOTO (this->name, dict, out);
@@ -673,6 +677,7 @@ gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict)
if (!clienttable)
return -1;
+#ifdef NOTYET
ret = TRY_LOCK (&clienttable->lock);
{
if (ret) {
@@ -692,6 +697,7 @@ gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict)
}
}
UNLOCK(&clienttable->lock);
+#endif
ret = dict_set_int32 (dict, "conncount", count);
out:
@@ -729,11 +735,11 @@ gf_client_dump_fdtables (xlator_t *this)
continue;
client = clienttable->cliententries[count].client;
memset(key, 0, sizeof key);
- if (client->server_ctx.client_uid) {
+ if (client->client_uid) {
gf_proc_dump_build_key (key, "conn",
"%d.id", count);
gf_proc_dump_write (key, "%s",
- client->server_ctx.client_uid);
+ client->client_uid);
}
gf_proc_dump_build_key (key, "conn", "%d.ref",
@@ -746,8 +752,10 @@ gf_client_dump_fdtables (xlator_t *this)
client->bound_xl->name);
}
+#ifdef NOTYET
gf_proc_dump_build_key (key, "conn","%d.id", count);
fdtable_dump (client->server_ctx.fdtable, key);
+#endif
}
}
@@ -836,14 +844,14 @@ gf_client_dump_inodes (xlator_t *this)
clienttable = this->ctx->clienttable;
if (!clienttable)
- return -1;
+ goto out;
ret = TRY_LOCK (&clienttable->lock);
{
if (ret) {
gf_log ("client_t", GF_LOG_WARNING,
"Unable to acquire lock");
- return -1;
+ goto out;
}
for ( ; count < clienttable->max_clients; count++) {
@@ -879,3 +887,4 @@ gf_client_dump_inodes (xlator_t *this)
out:
return ret;
}
+
diff --git a/libglusterfs/src/client_t.h b/libglusterfs/src/client_t.h
index 7b3fcf0dd..f7812f8f0 100644
--- a/libglusterfs/src/client_t.h
+++ b/libglusterfs/src/client_t.h
@@ -20,37 +20,13 @@
#include "locking.h" /* for gf_lock_t, not included by glusterfs.h */
struct client_ctx {
- union {
- uint64_t key;
- void *xl_key;
- };
- union {
- uint64_t value;
- void *ptr1;
- };
+ void *ctx_key;
+ void *ctx_value;
};
-struct _client_t {
+typedef struct _client_t {
struct {
- /* ctx for .../xlators/protocol/server */
- gf_lock_t fdtable_lock;
- fdtable_t *fdtable;
- char *client_uid;
- struct _gf_timer *grace_timer;
- uint32_t lk_version;
- struct {
- int flavour;
- size_t len;
- char *data;
- } auth;
- } server_ctx;
- struct {
- /* ctx for .../xlators/features/locks */
- gf_lock_t ltable_lock;
- struct _lock_table *ltable;
- } locks_ctx;
- struct {
- /* e.g. hekafs uidmap can stash stuff here */
+ /* e.g. protocol/server stashes its ctx here */
gf_lock_t lock;
unsigned short count;
struct client_ctx *ctx;
@@ -63,9 +39,15 @@ struct _client_t {
xlator_t *bound_xl;
xlator_t *this;
int tbl_index;
-};
-typedef struct _client_t client_t;
+ char *client_uid;
+ struct {
+ int flavour;
+ size_t len;
+ char *data;
+ } auth;
+} client_t;
+#define GF_CLIENTCTX_INITIAL_SIZE 8
struct client_table_entry {
client_t *client;
@@ -73,14 +55,13 @@ struct client_table_entry {
};
typedef struct client_table_entry cliententry_t;
-
-struct _clienttable {
+struct clienttable {
unsigned int max_clients;
gf_lock_t lock;
cliententry_t *cliententries;
int first_free;
};
-typedef struct _clienttable clienttable_t;
+typedef struct clienttable clienttable_t;
#define GF_CLIENTTABLE_INITIAL_SIZE 32
@@ -92,10 +73,10 @@ typedef struct _clienttable clienttable_t;
*/
#define GF_CLIENTENTRY_ALLOCATED -2
-
+struct rpcsvc_auth_data;
client_t *
-gf_client_get (xlator_t *this, rpcsvc_auth_data_t *cred, char *client_uid);
+gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid);
void
gf_client_put (client_t *client, gf_boolean_t *detached);
@@ -103,15 +84,12 @@ gf_client_put (client_t *client, gf_boolean_t *detached);
clienttable_t *
gf_clienttable_alloc (void);
-
void
gf_client_clienttable_destroy (clienttable_t *clienttable);
-
client_t *
gf_client_ref (client_t *client);
-
void
gf_client_unref (client_t *client);
@@ -128,27 +106,13 @@ int
gf_client_dump_inodes (xlator_t *this);
int
-client_ctx_set (client_t *client, xlator_t *xlator, uint64_t value);
-
-
-int
-client_ctx_get (client_t *client, xlator_t *xlator, uint64_t *value);
-
-
-int
-client_ctx_del (client_t *client, xlator_t *xlator, uint64_t *value);
-
+client_ctx_set (client_t *client, void *key, void *value);
int
-_client_ctx_set (client_t *client, xlator_t *xlator, uint64_t value);
-
+client_ctx_get (client_t *client, void *key, void **value);
int
-_client_ctx_get (client_t *client, xlator_t *xlator, uint64_t *value);
-
-
-int
-_client_ctx_del (client_t *client, xlator_t *xlator, uint64_t *value);
+client_ctx_del (client_t *client, void *key, void **value);
void
client_ctx_dump (client_t *client, char *prefix);
@@ -165,4 +129,7 @@ gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict);
int
gf_client_dump_inodes (xlator_t *this);
+int
+gf_client_disconnect (client_t *client);
+
#endif /* _CLIENT_T_H */
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 6eb886b38..827475282 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1125,7 +1125,7 @@ gf_string2int8 (const char *str, int8_t *n)
if (rv != 0)
return rv;
- if (l >= INT8_MIN && l <= INT8_MAX) {
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
*n = (int8_t) l;
return 0;
}
@@ -1144,7 +1144,7 @@ gf_string2int16 (const char *str, int16_t *n)
if (rv != 0)
return rv;
- if (l >= INT16_MIN && l <= INT16_MAX) {
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
*n = (int16_t) l;
return 0;
}
@@ -1163,7 +1163,7 @@ gf_string2int32 (const char *str, int32_t *n)
if (rv != 0)
return rv;
- if (l >= INT32_MIN && l <= INT32_MAX) {
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
*n = (int32_t) l;
return 0;
}
@@ -1182,7 +1182,7 @@ gf_string2int64 (const char *str, int64_t *n)
if (rv != 0)
return rv;
- if (l >= INT64_MIN && l <= INT64_MAX) {
+ if ((l >= INT64_MIN) && (l <= INT64_MAX)) {
*n = (int64_t) l;
return 0;
}
@@ -1441,6 +1441,11 @@ gf_string2bytesize (const char *str, uint64_t *n)
return -1;
}
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+
*n = (uint64_t) value;
return 0;
@@ -1500,6 +1505,12 @@ gf_string2percent_or_bytesize (const char *str,
return -1;
}
+ /* Error out if we cannot store the value in uint64 */
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+
*n = (uint64_t) value;
return 0;
@@ -2807,3 +2818,91 @@ out:
}
+
+/* Sets log file path from user provided arguments */
+int
+gf_set_log_file_path (cmd_args_t *cmd_args)
+{
+ int i = 0;
+ int j = 0;
+ int ret = 0;
+ char tmp_str[1024] = {0,};
+
+ if (!cmd_args)
+ goto done;
+
+ if (cmd_args->mount_point) {
+ j = 0;
+ i = 0;
+ if (cmd_args->mount_point[0] == '/')
+ i = 1;
+ for (; i < strlen (cmd_args->mount_point); i++,j++) {
+ tmp_str[j] = cmd_args->mount_point[i];
+ if (cmd_args->mount_point[i] == '/')
+ tmp_str[j] = '-';
+ }
+
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log",
+ tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (cmd_args->volfile) {
+ j = 0;
+ i = 0;
+ if (cmd_args->volfile[0] == '/')
+ i = 1;
+ for (; i < strlen (cmd_args->volfile); i++,j++) {
+ tmp_str[j] = cmd_args->volfile[i];
+ if (cmd_args->volfile[i] == '/')
+ tmp_str[j] = '-';
+ }
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log",
+ tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (cmd_args->volfile_server) {
+
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s-%s-%d.log",
+ cmd_args->volfile_server,
+ cmd_args->volfile_id, getpid());
+ if (ret > 0)
+ ret = 0;
+ }
+done:
+ return ret;
+}
+
+int
+gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg)
+{
+ sigset_t set, old;
+ int ret;
+
+ sigemptyset (&set);
+
+ sigfillset (&set);
+ sigdelset (&set, SIGSEGV);
+ sigdelset (&set, SIGBUS);
+ sigdelset (&set, SIGILL);
+ sigdelset (&set, SIGSYS);
+ sigdelset (&set, SIGFPE);
+ sigdelset (&set, SIGABRT);
+
+ pthread_sigmask (SIG_BLOCK, &set, &old);
+
+ ret = pthread_create (thread, attr, start_routine, arg);
+
+ pthread_sigmask (SIG_SETMASK, &old, NULL);
+
+ return ret;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index bf41444d1..3c99a4212 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -112,6 +112,7 @@ in_addr_t gf_resolve_ip (const char *hostname, void **dnscache);
void gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph);
void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx);
+int gf_set_log_file_path (cmd_args_t *cmd_args);
#define VECTORSIZE(count) (count * (sizeof (struct iovec)))
@@ -587,4 +588,7 @@ gf_boolean_t gf_is_local_addr (char *hostname);
gf_boolean_t gf_is_same_address (char *host1, char *host2);
void md5_wrapper(const unsigned char *data, size_t len, char *md5);
+int gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg);
+
#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
index a3c8d97f1..2ebb25150 100644
--- a/libglusterfs/src/defaults.c
+++ b/libglusterfs/src/defaults.c
@@ -473,6 +473,17 @@ default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
}
int32_t
+default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre,
+ post, xdata);
+ return 0;
+}
+
+
+int32_t
default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, char *spec_data)
{
@@ -900,6 +911,17 @@ default_discard_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
+int32_t
+default_zerofill_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND(frame, default_zerofill_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
+ xdata);
+ return 0;
+}
+
+
/* FOPS */
int32_t
@@ -1325,6 +1347,17 @@ default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd,
}
int32_t
+default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
+ xdata);
+ return 0;
+}
+
+
+int32_t
default_forget (xlator_t *this, inode_t *inode)
{
gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not "
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index f3cbb3a4b..0747027bc 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -255,6 +255,13 @@ int32_t default_discard(call_frame_t *frame,
off_t offset,
size_t len, dict_t *xdata);
+int32_t default_zerofill(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
+
/* Resume */
int32_t default_getspec_resume (call_frame_t *frame,
xlator_t *this,
@@ -477,6 +484,13 @@ int32_t default_discard_resume(call_frame_t *frame,
off_t offset,
size_t len, dict_t *xdata);
+int32_t default_zerofill_resume(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
+
/* _cbk */
int32_t
@@ -695,6 +709,10 @@ int32_t default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
struct iatt *post, dict_t *xdata);
+int32_t default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
int32_t
default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, char *spec_data);
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index b017f87e5..3b7ddce5e 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -896,7 +896,7 @@ data_to_int32 (data_t *data)
int16_t
data_to_int16 (data_t *data)
{
- int16_t value = 0;
+ int16_t value = 0;
if (!data) {
gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
@@ -910,16 +910,16 @@ data_to_int16 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- errno = 0;
- value = strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
- if ((SHRT_MAX > value) || (SHRT_MIN < value)) {
- errno = ERANGE;
+ if ((value > SHRT_MAX) || (value < SHRT_MIN)) {
+ errno = ERANGE;
gf_log_callingfn ("dict", GF_LOG_WARNING,
- "Error in data conversion: "
- "detected overflow");
+ "Error in data conversion: "
+ "detected overflow");
return -1;
- }
+ }
return (int16_t)value;
}
@@ -928,7 +928,7 @@ data_to_int16 (data_t *data)
int8_t
data_to_int8 (data_t *data)
{
- int32_t value = 0;
+ int8_t value = 0;
if (!data) {
gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
@@ -942,16 +942,16 @@ data_to_int8 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- errno = 0;
- value = strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
- if ((SCHAR_MAX > value) || (SCHAR_MIN < value)) {
- errno = ERANGE;
+ if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) {
+ errno = ERANGE;
gf_log_callingfn ("dict", GF_LOG_WARNING,
- "Error in data conversion: "
- "detected overflow");
+ "Error in data conversion: "
+ "detected overflow");
return -1;
- }
+ }
return (int8_t)value;
}
diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c
index fe511caeb..82baa521a 100644
--- a/libglusterfs/src/event-history.c
+++ b/libglusterfs/src/event-history.c
@@ -11,7 +11,8 @@
#include "event-history.h"
eh_t *
-eh_new (size_t buffer_size, gf_boolean_t use_buffer_once)
+eh_new (size_t buffer_size, gf_boolean_t use_buffer_once,
+ void (*destroy_buffer_data) (void *data))
{
eh_t *history = NULL;
buffer_t *buffer = NULL;
@@ -22,7 +23,8 @@ eh_new (size_t buffer_size, gf_boolean_t use_buffer_once)
goto out;
}
- buffer = cb_buffer_new (buffer_size, use_buffer_once);
+ buffer = cb_buffer_new (buffer_size, use_buffer_once,
+ destroy_buffer_data);
if (!buffer) {
gf_log ("", GF_LOG_ERROR, "allocating circular buffer failed");
GF_FREE (history);
diff --git a/libglusterfs/src/event-history.h b/libglusterfs/src/event-history.h
index b1750bbae..b64f63b5e 100644
--- a/libglusterfs/src/event-history.h
+++ b/libglusterfs/src/event-history.h
@@ -32,7 +32,8 @@ eh_dump (eh_t *event , void *data,
int (fn) (circular_buffer_t *buffer, void *data));
eh_t *
-eh_new (size_t buffer_size, gf_boolean_t use_buffer_once);
+eh_new (size_t buffer_size, gf_boolean_t use_buffer_once,
+ void (*destroy_data) (void *data));
int
eh_save_history (eh_t *history, void *string);
diff --git a/libglusterfs/src/gidcache.c b/libglusterfs/src/gidcache.c
index c55ed2581..c5bdda925 100644
--- a/libglusterfs/src/gidcache.c
+++ b/libglusterfs/src/gidcache.c
@@ -35,6 +35,21 @@ int gid_cache_init(gid_cache_t *cache, uint32_t timeout)
}
/*
+ * Reconfigure the cache timeout.
+ */
+int gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
+{
+ if (!cache)
+ return -1;
+
+ LOCK(&cache->gc_lock);
+ cache->gc_max_age = timeout;
+ UNLOCK(&cache->gc_lock);
+
+ return 0;
+}
+
+/*
* Look up an ID in the cache. If found, return the actual cache entry to avoid
* an additional allocation and memory copy. The caller should copy the data and
* release (unlock) the cache as soon as possible.
diff --git a/libglusterfs/src/gidcache.h b/libglusterfs/src/gidcache.h
index f904f26eb..9379f8e8b 100644
--- a/libglusterfs/src/gidcache.h
+++ b/libglusterfs/src/gidcache.h
@@ -45,6 +45,7 @@ typedef struct {
} gid_cache_t;
int gid_cache_init(gid_cache_t *, uint32_t);
+int gid_cache_reconf(gid_cache_t *, uint32_t);
const gid_list_t *gid_cache_lookup(gid_cache_t *, uint64_t);
void gid_cache_release(gid_cache_t *, const gid_list_t *);
int gid_cache_add(gid_cache_t *, gid_list_t *);
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index 459291b33..259c5c885 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -19,6 +19,7 @@
#include "globals.h"
#include "xlator.h"
#include "mem-pool.h"
+#include "syncop.h"
const char *gf_fop_list[GF_FOP_MAXVALUE] = {
[GF_FOP_NULL] = "NULL",
@@ -69,6 +70,7 @@ const char *gf_fop_list[GF_FOP_MAXVALUE] = {
[GF_FOP_FREMOVEXATTR]= "FREMOVEXATTR",
[GF_FOP_FALLOCATE] = "FALLOCATE",
[GF_FOP_DISCARD] = "DISCARD",
+ [GF_FOP_ZEROFILL] = "ZEROFILL",
};
/* THIS */
@@ -164,6 +166,54 @@ glusterfs_this_set (xlator_t *this)
return 0;
}
+/* SYNCOPCTX */
+static pthread_key_t syncopctx_key;
+
+static void
+syncopctx_key_destroy (void *ptr)
+{
+ struct syncopctx *opctx = ptr;
+
+ if (opctx) {
+ if (opctx->groups)
+ GF_FREE (opctx->groups);
+
+ GF_FREE (opctx);
+ }
+
+ return;
+}
+
+void *
+syncopctx_getctx ()
+{
+ void *opctx = NULL;
+
+ opctx = pthread_getspecific (syncopctx_key);
+
+ return opctx;
+}
+
+int
+syncopctx_setctx (void *ctx)
+{
+ int ret = 0;
+
+ ret = pthread_setspecific (syncopctx_key, ctx);
+
+ return ret;
+}
+
+static int
+syncopctx_init (void)
+{
+ int ret;
+
+ ret = pthread_key_create (&syncopctx_key, syncopctx_key_destroy);
+
+ return ret;
+}
+
/* SYNCTASK */
int
@@ -176,7 +226,6 @@ synctask_init ()
return ret;
}
-
void *
synctask_get ()
{
@@ -300,6 +349,13 @@ glusterfs_globals_init (glusterfs_ctx_t *ctx)
"ERROR: glusterfs synctask init failed");
goto out;
}
+
+ ret = syncopctx_init ();
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "ERROR: glusterfs syncopctx init failed");
+ goto out;
+ }
out:
return ret;
}
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index 857965bb4..3085db21c 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -41,6 +41,10 @@ xlator_t **__glusterfs_this_location ();
xlator_t *glusterfs_this_get ();
int glusterfs_this_set (xlator_t *);
+/* syncopctx */
+void *syncopctx_getctx ();
+int syncopctx_setctx (void *ctx);
+
/* task */
void *synctask_get ();
int synctask_set (void *);
diff --git a/libglusterfs/src/glusterfs-acl.h b/libglusterfs/src/glusterfs-acl.h
new file mode 100644
index 000000000..b7de1cdb4
--- /dev/null
+++ b/libglusterfs/src/glusterfs-acl.h
@@ -0,0 +1,81 @@
+/*
+ Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _GLUSTERFS_ACL_H
+#define _GLUSTERFS_ACL_H
+
+#include <stdint.h>
+#include <sys/types.h> /* For uid_t */
+
+#include "locking.h" /* For gf_lock_t in struct posix_acl_conf */
+
+#define ACL_PROGRAM 100227
+#define ACLV3_VERSION 3
+
+#define POSIX_ACL_MINIMAL_ACE_COUNT 3
+
+#define POSIX_ACL_READ (0x04)
+#define POSIX_ACL_WRITE (0x02)
+#define POSIX_ACL_EXECUTE (0x01)
+
+#define POSIX_ACL_UNDEFINED_TAG (0x00)
+#define POSIX_ACL_USER_OBJ (0x01)
+#define POSIX_ACL_USER (0x02)
+#define POSIX_ACL_GROUP_OBJ (0x04)
+#define POSIX_ACL_GROUP (0x08)
+#define POSIX_ACL_MASK (0x10)
+#define POSIX_ACL_OTHER (0x20)
+
+#define POSIX_ACL_UNDEFINED_ID (-1)
+
+#define POSIX_ACL_VERSION (0x02)
+
+#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
+#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
+
+struct posix_acl_xattr_entry {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+struct posix_acl_xattr_header {
+ uint32_t version;
+ struct posix_acl_xattr_entry entries[];
+};
+
+struct posix_ace {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+
+struct posix_acl {
+ int refcnt;
+ int count;
+ struct posix_ace entries[];
+};
+
+struct posix_acl_ctx {
+ uid_t uid;
+ gid_t gid;
+ mode_t perm;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+};
+
+struct posix_acl_conf {
+ gf_lock_t acl_lock;
+ uid_t super_uid;
+ struct posix_acl *minimal_acl;
+};
+
+#endif /* _GLUSTERFS_ACL_H */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index ede208b38..2f1e12ee7 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -70,6 +70,7 @@
#define FNM_EXTMATCH 0
#endif
+#define GLUSTERD_MAX_SNAP_NAME 256
#define ZR_MOUNTPOINT_OPT "mountpoint"
#define ZR_ATTR_TIMEOUT_OPT "attribute-timeout"
#define ZR_ENTRY_TIMEOUT_OPT "entry-timeout"
@@ -88,6 +89,8 @@
#define GF_READDIR_SKIP_DIRS "readdir-filter-directories"
+#define BD_XATTR_KEY "user.glusterfs"
+
#define XATTR_IS_PATHINFO(x) (strncmp (x, GF_XATTR_PATHINFO_KEY, \
strlen (GF_XATTR_PATHINFO_KEY)) == 0)
#define XATTR_IS_NODE_UUID(x) (strncmp (x, GF_XATTR_NODE_UUID_KEY, \
@@ -95,6 +98,8 @@
#define XATTR_IS_LOCKINFO(x) (strncmp (x, GF_XATTR_LOCKINFO_KEY, \
strlen (GF_XATTR_LOCKINFO_KEY)) == 0)
+#define XATTR_IS_BD(x) (strncmp (x, BD_XATTR_KEY, strlen (BD_XATTR_KEY)) == 0)
+
#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
#define GFID_XATTR_KEY "trusted.gfid"
#define VIRTUAL_GFID_XATTR_KEY_STR "glusterfs.gfid.string"
@@ -119,6 +124,7 @@
/* Index xlator related */
#define GF_XATTROP_INDEX_GFID "glusterfs.xattrop_index_gfid"
+#define GF_BASE_INDICES_HOLDER_GFID "glusterfs.base_indicies_holder_gfid"
#define GF_GFIDLESS_LOOKUP "gfidless-lookup"
/* replace-brick and pump related internal xattrs */
@@ -128,9 +134,6 @@
#define RB_PUMP_CMD_ABORT "glusterfs.pump.abort"
#define RB_PUMP_CMD_STATUS "glusterfs.pump.status"
-#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
-#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
-
#define GLUSTERFS_RDMA_INLINE_THRESHOLD (2048)
#define GLUSTERFS_RDMA_MAX_HEADER_SIZE (228) /* (sizeof (rdma_header_t) \
+ RDMA_MAX_SEGMENTS \
@@ -159,6 +162,11 @@
#define UUID_CANONICAL_FORM_LEN 36
+/* Adding this here instead of any glusterd*.h files as it is also required by
+ * cli
+ */
+#define DEFAULT_GLUSTERD_SOCKFILE DATADIR "/run/glusterd.socket"
+
/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
typedef enum {
GF_FOP_NULL = 0,
@@ -209,6 +217,7 @@ typedef enum {
GF_FOP_FREMOVEXATTR,
GF_FOP_FALLOCATE,
GF_FOP_DISCARD,
+ GF_FOP_ZEROFILL,
GF_FOP_MAXVALUE,
} glusterfs_fop_t;
@@ -294,6 +303,11 @@ struct _xlator_cmdline_option {
};
typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
+struct _server_cmdline {
+ struct list_head list;
+ char *volfile_server;
+};
+typedef struct _server_cmdline server_cmdline_t;
#define GF_OPTION_ENABLE _gf_true
#define GF_OPTION_DISABLE _gf_false
@@ -301,9 +315,12 @@ typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
struct _cmd_args {
/* basic options */
- char *volfile_server;
- char *volfile;
- char *log_server;
+ char *volfile_server;
+ server_cmdline_t *curr_server;
+ /* List of backup volfile servers, including original */
+ struct list_head volfile_servers;
+ char *volfile;
+ char *log_server;
gf_loglevel_t log_level;
char *log_file;
int32_t max_connect_attempts;
@@ -322,14 +339,14 @@ struct _cmd_args {
int enable_ino32;
int worm;
int mac_compat;
- int fopen_keep_cache;
- int gid_timeout;
+ int fopen_keep_cache;
+ int gid_timeout;
int aux_gfid_mount;
- struct list_head xlator_options; /* list of xlator_option_t */
+ struct list_head xlator_options; /* list of xlator_option_t */
- /* fuse options */
- int fuse_direct_io_mode;
- char *use_readdirp;
+ /* fuse options */
+ int fuse_direct_io_mode;
+ char *use_readdirp;
int volfile_check;
double fuse_entry_timeout;
double fuse_negative_timeout;
@@ -343,7 +360,7 @@ struct _cmd_args {
unsigned uid_map_root;
int background_qlen;
int congestion_threshold;
- char *fuse_mountopts;
+ char *fuse_mountopts;
/* key args */
char *mount_point;
@@ -353,7 +370,6 @@ struct _cmd_args {
int brick_port;
char *brick_name;
int brick_port2;
-
};
typedef struct _cmd_args cmd_args_t;
@@ -382,7 +398,7 @@ struct _glusterfs_ctx {
char fin;
void *timer;
void *ib;
- void *pool;
+ struct call_pool *pool;
void *event_pool;
void *iobuf_pool;
pthread_mutex_t lock;
@@ -420,7 +436,8 @@ struct _glusterfs_ctx {
int daemon_pipe[2];
- struct _clienttable *clienttable;
+ struct client_disconnect *client_disconnect;
+ struct clienttable *clienttable;
};
typedef struct _glusterfs_ctx glusterfs_ctx_t;
@@ -444,6 +461,7 @@ typedef enum {
GF_EVENT_AUTH_FAILED,
GF_EVENT_VOLUME_DEFRAG,
GF_EVENT_PARENT_DOWN,
+ GF_EVENT_VOLUME_BARRIER_OP,
GF_EVENT_MAXVAL,
} glusterfs_event_t;
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
index 1dba63fc0..e76df1ca5 100644
--- a/libglusterfs/src/graph.c
+++ b/libglusterfs/src/graph.c
@@ -537,6 +537,184 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
int
+xlator_equal_rec (xlator_t *xl1, xlator_t *xl2)
+{
+ xlator_list_t *trav1 = NULL;
+ xlator_list_t *trav2 = NULL;
+ int ret = 0;
+
+ if (xl1 == NULL || xl2 == NULL) {
+ gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
+ return -1;
+ }
+
+ trav1 = xl1->children;
+ trav2 = xl2->children;
+
+ while (trav1 && trav2) {
+ ret = xlator_equal_rec (trav1->xlator, trav2->xlator);
+ if (ret) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "xlators children not equal");
+ goto out;
+ }
+
+ trav1 = trav1->next;
+ trav2 = trav2->next;
+ }
+
+ if (trav1 || trav2) {
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp (xl1->name, xl2->name)) {
+ ret = -1;
+ goto out;
+ }
+
+ /* type could have changed even if xlator names match,
+ e.g cluster/distrubte and cluster/nufa share the same
+ xlator name
+ */
+ if (strcmp (xl1->type, xl2->type)) {
+ ret = -1;
+ goto out;
+ }
+out :
+ return ret;
+}
+
+
+gf_boolean_t
+is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2)
+{
+ xlator_t *trav1 = NULL;
+ xlator_t *trav2 = NULL;
+ gf_boolean_t ret = _gf_true;
+
+ trav1 = graph1->first;
+ trav2 = graph2->first;
+
+ ret = xlator_equal_rec (trav1, trav2);
+
+ if (ret) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "graphs are not equal");
+ ret = _gf_false;
+ goto out;
+ }
+
+ ret = _gf_true;
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "graphs are equal");
+
+out:
+ return ret;
+}
+
+
+/* Function has 3types of return value 0, -ve , 1
+ * return 0 =======> reconfiguration of options has succeeded
+ * return 1 =======> the graph has to be reconstructed and all the xlators should be inited
+ * return -1(or -ve) =======> Some Internal Error occurred during the operation
+ */
+int
+glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
+ glusterfs_ctx_t *ctx, const char *oldvolfile)
+{
+ glusterfs_graph_t *oldvolfile_graph = NULL;
+ glusterfs_graph_t *newvolfile_graph = NULL;
+ FILE *oldvolfile_fp = NULL;
+ gf_boolean_t active_graph_found = _gf_true;
+
+ int ret = -1;
+
+ if (!oldvollen) {
+ ret = 1; // Has to call INIT for the whole graph
+ goto out;
+ }
+
+ if (!ctx) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
+ "ctx is NULL");
+ goto out;
+ }
+
+ oldvolfile_graph = ctx->active;
+ if (!oldvolfile_graph) {
+ active_graph_found = _gf_false;
+ gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
+ "glusterfs_ctx->active is NULL");
+
+ oldvolfile_fp = tmpfile ();
+ if (!oldvolfile_fp) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, "Unable to "
+ "create temporary volfile: (%s)",
+ strerror (errno));
+ goto out;
+ }
+
+ fwrite (oldvolfile, oldvollen, 1, oldvolfile_fp);
+ fflush (oldvolfile_fp);
+ if (ferror (oldvolfile_fp)) {
+ goto out;
+ }
+
+ oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp);
+ if (!oldvolfile_graph)
+ goto out;
+ }
+
+ newvolfile_graph = glusterfs_graph_construct (newvolfile_fp);
+ if (!newvolfile_graph) {
+ goto out;
+ }
+
+ if (!is_graph_topology_equal (oldvolfile_graph,
+ newvolfile_graph)) {
+
+ ret = 1;
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "Graph topology not equal(should call INIT)");
+ goto out;
+ }
+
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "Only options have changed in the new "
+ "graph");
+
+ /* */
+ ret = glusterfs_graph_reconfigure (oldvolfile_graph,
+ newvolfile_graph);
+ if (ret) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "Could not reconfigure new options in old graph");
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (oldvolfile_fp)
+ fclose (oldvolfile_fp);
+
+ /* Do not simply destroy the old graph here. If the oldgraph
+ is constructed here in this function itself instead of getting
+ it from ctx->active (which happens only of ctx->active is NULL),
+ then destroy the old graph. If some i/o is still happening in
+ the old graph and the old graph is obtained from ctx->active,
+ then destroying the graph will cause problems.
+ */
+ if (!active_graph_found && oldvolfile_graph)
+ glusterfs_graph_destroy (oldvolfile_graph);
+ if (newvolfile_graph)
+ glusterfs_graph_destroy (newvolfile_graph);
+
+ return ret;
+}
+
+
+int
glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
glusterfs_graph_t *newgraph)
{
@@ -562,5 +740,12 @@ glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
int
glusterfs_graph_destroy (glusterfs_graph_t *graph)
{
+ xlator_tree_free (graph->first);
+
+ if (graph) {
+ list_del_init (&graph->list);
+ GF_FREE (graph);
+ }
+
return 0;
}
diff --git a/libglusterfs/src/graph.l b/libglusterfs/src/graph.l
index ff34f6ef1..e4eba9cbe 100644
--- a/libglusterfs/src/graph.l
+++ b/libglusterfs/src/graph.l
@@ -70,10 +70,10 @@ TYPE [t][y][p][e]
yyunput (0, NULL);
}
BEGIN (INITIAL);
- yylval = text;
+ graphyylval = text;
return STRING_TOK;
}
}
-[^ \t\r\n\"\\]+ { yylval = gf_strdup (yytext) ; return ID; }
+[^ \t\r\n\"\\]+ { graphyylval = gf_strdup (yytext) ; return ID; }
[ \t\r\n]+ ;
%%
diff --git a/libglusterfs/src/graph.y b/libglusterfs/src/graph.y
index e2f16ff71..a220abeb9 100644
--- a/libglusterfs/src/graph.y
+++ b/libglusterfs/src/graph.y
@@ -18,6 +18,7 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <pthread.h>
#define RELAX_POISONING
@@ -37,8 +38,8 @@ static void option_error (void);
#define YYSTYPE char *
#define GF_CMD_BUFFER_LEN (8 * GF_UNIT_KB)
-int yyerror (const char *);
-int yylex ();
+int graphyyerror (const char *);
+int graphyylex ();
%}
@@ -78,11 +79,11 @@ glusterfs_graph_t *construct;
static void
type_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
gf_log ("parser", GF_LOG_ERROR,
"Volume %s, before line %d: Please specify volume type",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -90,11 +91,11 @@ type_error (void)
static void
sub_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
gf_log ("parser", GF_LOG_ERROR,
"Volume %s, before line %d: Please specify subvolumes",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -102,12 +103,12 @@ sub_error (void)
static void
option_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
gf_log ("parser", GF_LOG_ERROR,
"Volume %s, before line %d: Please specify "
"option <key> <value>",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -115,7 +116,7 @@ option_error (void)
static int
new_volume (char *name)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
@@ -129,7 +130,7 @@ new_volume (char *name)
if (curr) {
gf_log ("parser", GF_LOG_ERROR,
"new volume (%s) defintion in line %d unexpected",
- name, yylineno);
+ name, graphyylineno);
ret = -1;
goto out;
}
@@ -149,7 +150,7 @@ new_volume (char *name)
if (!strcmp (name, trav->name)) {
gf_log ("parser", GF_LOG_ERROR,
"Line %d: volume '%s' defined again",
- yylineno, name);
+ graphyylineno, name);
ret = -1;
goto out;
}
@@ -194,7 +195,7 @@ out:
static int
volume_type (char *type)
{
- extern int yylineno;
+ extern int graphyylineno;
int32_t ret = 0;
if (!type) {
@@ -208,7 +209,7 @@ volume_type (char *type)
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: type '%s' is not valid or "
"not found on this machine",
- curr->name, yylineno, type);
+ curr->name, graphyylineno, type);
ret = -1;
goto out;
}
@@ -225,7 +226,7 @@ out:
static int
volume_option (char *key, char *value)
{
- extern int yylineno;
+ extern int graphyylineno;
int ret = 0;
char *set_value = NULL;
@@ -242,7 +243,7 @@ volume_option (char *key, char *value)
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: duplicate entry "
"('option %s') present",
- curr->name, yylineno, key);
+ curr->name, graphyylineno, key);
ret = -1;
goto out;
}
@@ -261,7 +262,7 @@ out:
static int
volume_sub (char *sub)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
@@ -283,7 +284,7 @@ volume_sub (char *sub)
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: subvolume '%s' is not defined "
"prior to usage",
- curr->name, yylineno, sub);
+ curr->name, graphyylineno, sub);
ret = -1;
goto out;
}
@@ -291,7 +292,7 @@ volume_sub (char *sub)
if (trav == curr) {
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: has '%s' itself as subvolume",
- curr->name, yylineno, sub);
+ curr->name, graphyylineno, sub);
ret = -1;
goto out;
}
@@ -328,46 +329,46 @@ volume_end (void)
int
-yywrap ()
+graphyywrap ()
{
return 1;
}
int
-yyerror (const char *str)
+graphyyerror (const char *str)
{
- extern char *yytext;
- extern int yylineno;
+ extern char *graphyytext;
+ extern int graphyylineno;
- if (curr && curr->name && yytext) {
- if (!strcmp (yytext, "volume")) {
+ if (curr && curr->name && graphyytext) {
+ if (!strcmp (graphyytext, "volume")) {
gf_log ("parser", GF_LOG_ERROR,
"'end-volume' not defined for volume '%s'",
curr->name);
- } else if (!strcmp (yytext, "type")) {
+ } else if (!strcmp (graphyytext, "type")) {
gf_log ("parser", GF_LOG_ERROR,
"line %d: duplicate 'type' defined for "
"volume '%s'",
- yylineno, curr->name);
- } else if (!strcmp (yytext, "subvolumes")) {
+ graphyylineno, curr->name);
+ } else if (!strcmp (graphyytext, "subvolumes")) {
gf_log ("parser", GF_LOG_ERROR,
"line %d: duplicate 'subvolumes' defined for "
"volume '%s'",
- yylineno, curr->name);
+ graphyylineno, curr->name);
} else if (curr) {
gf_log ("parser", GF_LOG_ERROR,
"syntax error: line %d (volume '%s'): \"%s\""
"\nallowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume'()",
- yylineno, curr->name,
- yytext);
+ graphyylineno, curr->name,
+ graphyytext);
} else {
gf_log ("parser", GF_LOG_ERROR,
"syntax error: line %d (just after volume "
"'%s'): \"%s\"\n(%s)",
- yylineno, curr->name,
- yytext,
+ graphyylineno, curr->name,
+ graphyytext,
"allowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume'");
}
@@ -376,7 +377,7 @@ yyerror (const char *str)
"syntax error in line %d: \"%s\" \n"
"(allowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume')\n",
- yylineno, yytext);
+ graphyylineno, graphyytext);
}
return -1;
@@ -481,6 +482,7 @@ preprocess (FILE *srcfp, FILE *dstfp)
cmd_buf_size *= 2;
cmd = GF_REALLOC (cmd, cmd_buf_size);
if (cmd == NULL) {
+ GF_FREE (result);
return -1;
}
@@ -522,6 +524,7 @@ preprocess (FILE *srcfp, FILE *dstfp)
out:
fseek (srcfp, 0L, SEEK_SET);
fseek (dstfp, 0L, SEEK_SET);
+
GF_FREE (cmd);
GF_FREE (result);
@@ -529,7 +532,7 @@ out:
}
-extern FILE *yyin;
+extern FILE *graphyyin;
glusterfs_graph_t *
glusterfs_graph_new ()
@@ -557,6 +560,7 @@ glusterfs_graph_construct (FILE *fp)
glusterfs_graph_t *graph = NULL;
FILE *tmp_file = NULL;
char template[PATH_MAX] = {0};
+ static pthread_mutex_t graph_mutex = PTHREAD_MUTEX_INITIALIZER;
graph = glusterfs_graph_new ();
if (!graph)
@@ -583,10 +587,14 @@ glusterfs_graph_construct (FILE *fp)
goto err;
}
- yyin = tmp_file;
- construct = graph;
- ret = yyparse ();
- construct = NULL;
+ pthread_mutex_lock (&graph_mutex);
+ {
+ graphyyin = tmp_file;
+ construct = graph;
+ ret = yyparse ();
+ construct = NULL;
+ }
+ pthread_mutex_unlock (&graph_mutex);
if (ret == 1) {
gf_log ("parser", GF_LOG_DEBUG,
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index add686fd2..15e0ccf78 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1493,6 +1493,18 @@ out:
return ret;
}
+int
+__inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+{
+ return __inode_ctx_set2 (inode, xlator, value1_p, NULL);
+}
+
+int
+__inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+{
+ return __inode_ctx_set2 (inode, xlator, NULL, value2_p);
+}
+
int
inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
@@ -1512,34 +1524,97 @@ inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
return ret;
}
+int
+inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_set1 (inode, xlator, value2_p);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+int
+inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_set0 (inode, xlator, value1_p);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
int
__inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2)
{
int index = 0;
- int ret = 0;
+ int ret = -1;
if (!inode || !xlator)
- return -1;
+ goto out;
for (index = 0; index < inode->table->ctxcount; index++) {
if (inode->_ctx[index].xl_key == xlator)
break;
}
- if (index == inode->table->ctxcount) {
- ret = -1;
+ if (index == inode->table->ctxcount)
goto out;
+
+ if (inode->_ctx[index].value1) {
+ if (value1)
+ *value1 = inode->_ctx[index].value1;
+ ret = 0;
}
+ if (inode->_ctx[index].value2) {
+ if (value2)
+ *value2 = inode->_ctx[index].value2;
+ ret = 0;
+ }
+out:
+ return ret;
+}
- if (value1)
- *value1 = inode->_ctx[index].value1;
- if (value2)
- *value2 = inode->_ctx[index].value2;
-out:
+int
+__inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1)
+{
+ uint64_t tmp_value = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_get2 (inode, xlator, &tmp_value, NULL);
+ if (!ret)
+ *value1 = tmp_value;
+
+ return ret;
+}
+
+int
+__inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2)
+{
+ uint64_t tmp_value = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_get2 (inode, xlator, NULL, &tmp_value);
+ if (!ret)
+ *value2 = tmp_value;
+
return ret;
}
@@ -1562,6 +1637,40 @@ inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
return ret;
}
+int
+inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get1 (inode, xlator, value2);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
+int
+inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get0 (inode, xlator, value1);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
int
inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
@@ -1586,9 +1695,9 @@ inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
goto unlock;
}
- if (value1)
+ if (inode->_ctx[index].value1 && value1)
*value1 = inode->_ctx[index].value1;
- if (value2)
+ if (inode->_ctx[index].value2 && value2)
*value2 = inode->_ctx[index].value2;
inode->_ctx[index].key = 0;
@@ -1601,6 +1710,97 @@ unlock:
return ret;
}
+/* function behavior:
+ - if value1 is set, value1 in ctx is reset to 0 with current value passed
+ back in value1 address.
+ - if value2 is set, value2 in ctx is reset to 0 with current value passed
+ back in value2 address.
+ - if both are set, both fields are reset.
+*/
+static int
+__inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2)
+{
+ int index = 0;
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ for (index = 0; index < inode->table->ctxcount;
+ index++) {
+ if (inode->_ctx[index].xl_key == xlator)
+ break;
+ }
+
+ if (index == inode->table->ctxcount) {
+ ret = -1;
+ goto unlock;
+ }
+
+ if (inode->_ctx[index].value1 && value1) {
+ *value1 = inode->_ctx[index].value1;
+ inode->_ctx[index].value1 = 0;
+ }
+ if (inode->_ctx[index].value2 && value2) {
+ *value2 = inode->_ctx[index].value2;
+ inode->_ctx[index].value2 = 0;
+ }
+ }
+unlock:
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
+int
+inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
+{
+ uint64_t tmp_value1 = 0;
+ uint64_t tmp_value2 = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_reset2 (inode, xlator, &tmp_value1, &tmp_value2);
+ if (!ret) {
+ if (value1_p)
+ *value1_p = tmp_value1;
+ if (value2_p)
+ *value2_p = tmp_value2;
+ }
+ return ret;
+}
+
+int
+inode_ctx_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+{
+ uint64_t tmp_value2 = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_reset2 (inode, xlator, NULL, &tmp_value2);
+
+ if (!ret && value2_p)
+ *value2_p = tmp_value2;
+
+ return ret;
+
+}
+int
+inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+{
+ uint64_t tmp_value1 = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_reset2 (inode, xlator, &tmp_value1, NULL);
+
+ if (!ret && value1_p)
+ *value1_p = tmp_value1;
+
+ return ret;
+}
+
void
inode_dump (inode_t *inode, char *prefix)
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index cf766a31b..a88976265 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -73,10 +73,12 @@ struct _inode_ctx {
uint64_t key;
xlator_t *xl_key;
};
+ /* if value1 is 0, then field is not set.. */
union {
uint64_t value1;
void *ptr1;
};
+ /* if value2 is 0, then field is not set.. */
union {
uint64_t value2;
void *ptr2;
@@ -159,6 +161,11 @@ __inode_path (inode_t *inode, const char *name, char **bufp);
inode_t *
inode_from_path (inode_table_t *table, const char *path);
+inode_t *
+inode_resolve (inode_table_t *table, char *path);
+
+/* deal with inode ctx's both values */
+
int
inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
@@ -177,29 +184,66 @@ int
inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
-inode_t *
-inode_resolve (inode_table_t *table, char *path);
+int
+inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
+
+/* deal with inode ctx's 1st value */
+
+int
+inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+__inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+int
+__inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+/* deal with inode ctx's 2st value */
+
+int
+inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+__inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+int
+__inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+inode_ctx_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
-#define __inode_ctx_set(i,x,v_p) __inode_ctx_set2(i,x,v_p,0)
-#define inode_ctx_set(i,x,v_p) inode_ctx_set2(i,x,v_p,0)
static inline int
__inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
{
- return __inode_ctx_set2 (inode, this, &v, 0);
+ return __inode_ctx_set0 (inode, this, &v);
}
static inline int
inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
{
- return inode_ctx_set2(inode, this, &v, 0);
+ return inode_ctx_set0 (inode, this, &v);
}
-#define __inode_ctx_get(i,x,v) __inode_ctx_get2(i,x,v,0)
-#define inode_ctx_get(i,x,v) inode_ctx_get2(i,x,v,0)
+#define __inode_ctx_set(i,x,v_p) __inode_ctx_set0(i,x,v_p)
-#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
+#define inode_ctx_set(i,x,v_p) inode_ctx_set0(i,x,v_p)
+#define inode_ctx_reset(i,x,v) inode_ctx_reset0(i,x,v)
+
+#define __inode_ctx_get(i,x,v) __inode_ctx_get0(i,x,v)
+
+#define inode_ctx_get(i,x,v) inode_ctx_get0(i,x,v)
+
+#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
gf_boolean_t
__is_root_gfid (uuid_t gfid);
diff --git a/libglusterfs/src/list.h b/libglusterfs/src/list.h
index 7f3712b51..392c22ceb 100644
--- a/libglusterfs/src/list.h
+++ b/libglusterfs/src/list.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2014 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
@@ -11,7 +11,6 @@
#ifndef _LLIST_H
#define _LLIST_H
-
struct list_head {
struct list_head *next;
struct list_head *prev;
@@ -45,6 +44,31 @@ list_add_tail (struct list_head *new, struct list_head *head)
}
+/* This function will insert the element to the list in a order.
+ Order will be based on the compare function provided as a input.
+ If element to be inserted in ascending order compare should return:
+ 0: if both the arguments are equal
+ >0: if first argument is greater than second argument
+ <0: if first argument is less than second argument */
+static inline void
+list_add_order (struct list_head *new, struct list_head *head,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ struct list_head *pos = head->prev;
+
+ while ( pos != head ) {
+ if (compare(new, pos) >= 0)
+ break;
+
+ /* Iterate the list in the reverse order. This will have
+ better efficiency if the elements are inserted in the
+ ascending order */
+ pos = pos->prev;
+ }
+
+ list_add (new, pos);
+}
+
static inline void
list_del (struct list_head *old)
{
diff --git a/libglusterfs/src/lock-table.c b/libglusterfs/src/lock-table.c
deleted file mode 100644
index 42b7ed8a7..000000000
--- a/libglusterfs/src/lock-table.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#include "lock-table.h"
-#include "common-utils.h"
-
-
-struct _lock_table *
-gf_lock_table_new (void)
-{
- struct _lock_table *new = NULL;
-
- new = GF_CALLOC (1, sizeof (struct _lock_table), gf_common_mt_lock_table);
- if (new == NULL) {
- goto out;
- }
- INIT_LIST_HEAD (&new->entrylk_lockers);
- INIT_LIST_HEAD (&new->inodelk_lockers);
- LOCK_INIT (&new->lock);
-out:
- return new;
-}
-
-
-int
-gf_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc, fd_t *fd, pid_t pid, gf_lkowner_t *owner,
- glusterfs_fop_t type)
-{
- int32_t ret = -1;
- struct _locker *new = NULL;
-
- GF_VALIDATE_OR_GOTO ("lock-table", table, out);
- GF_VALIDATE_OR_GOTO ("lock-table", volume, out);
-
- new = GF_CALLOC (1, sizeof (struct _locker), gf_common_mt_locker);
- if (new == NULL) {
- goto out;
- }
- INIT_LIST_HEAD (&new->lockers);
-
- new->volume = gf_strdup (volume);
-
- if (fd == NULL) {
- loc_copy (&new->loc, loc);
- } else {
- new->fd = fd_ref (fd);
- }
-
- new->pid = pid;
- new->owner = *owner;
-
- LOCK (&table->lock);
- {
- if (type == GF_FOP_ENTRYLK)
- list_add_tail (&new->lockers, &table->entrylk_lockers);
- else
- list_add_tail (&new->lockers, &table->inodelk_lockers);
- }
- UNLOCK (&table->lock);
-out:
- return ret;
-}
-
-int
-gf_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc, fd_t *fd, gf_lkowner_t *owner, glusterfs_fop_t type)
-{
- struct _locker *locker = NULL;
- struct _locker *tmp = NULL;
- int32_t ret = -1;
- struct list_head *head = NULL;
- struct list_head del;
-
- GF_VALIDATE_OR_GOTO ("lock-table", table, out);
- GF_VALIDATE_OR_GOTO ("lock-table", volume, out);
-
- INIT_LIST_HEAD (&del);
-
- LOCK (&table->lock);
- {
- if (type == GF_FOP_ENTRYLK) {
- head = &table->entrylk_lockers;
- } else {
- head = &table->inodelk_lockers;
- }
-
- list_for_each_entry_safe (locker, tmp, head, lockers) {
- if (!is_same_lkowner (&locker->owner, owner) ||
- strcmp (locker->volume, volume))
- continue;
-
- /*
- * It is possible for inodelk lock to come on anon-fd
- * and inodelk unlock to come on normal fd in case of
- * client re-opens. So don't check for fds to be equal.
- */
- if (locker->fd && fd)
- list_move_tail (&locker->lockers, &del);
- else if (locker->loc.inode && loc &&
- (locker->loc.inode == loc->inode))
- list_move_tail (&locker->lockers, &del);
- }
- }
- UNLOCK (&table->lock);
-
- tmp = NULL;
- locker = NULL;
-
- list_for_each_entry_safe (locker, tmp, &del, lockers) {
- list_del_init (&locker->lockers);
- if (locker->fd)
- fd_unref (locker->fd);
- else
- loc_wipe (&locker->loc);
-
- GF_FREE (locker->volume);
- GF_FREE (locker);
- }
-
- ret = 0;
-out:
- return ret;
-
-}
-
diff --git a/libglusterfs/src/lock-table.h b/libglusterfs/src/lock-table.h
deleted file mode 100644
index 4a9083873..000000000
--- a/libglusterfs/src/lock-table.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef _LOCK_TABLE_H
-#define _LOCK_TABLE_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-
-struct _locker {
- struct list_head lockers;
- char *volume;
- loc_t loc;
- fd_t *fd;
- gf_lkowner_t owner;
- pid_t pid;
-};
-
-struct _lock_table {
- struct list_head inodelk_lockers;
- struct list_head entrylk_lockers;
- gf_lock_t lock;
-};
-
-int32_t
-gf_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid,
- gf_lkowner_t *owner,
- glusterfs_fop_t type);
-
-int32_t
-gf_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- gf_lkowner_t *owner,
- glusterfs_fop_t type);
-
-struct _lock_table *
-gf_lock_table_new (void);
-
-#endif /* _LOCK_TABLE_H */
diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h
index 9da1379e7..cc806a767 100644
--- a/libglusterfs/src/logging.h
+++ b/libglusterfs/src/logging.h
@@ -35,6 +35,7 @@
#define GF_PRI_BLKSIZE PRId32
#define GF_PRI_SIZET "zu"
+
#if 0
/* Syslog definitions :-) */
#define LOG_EMERG 0 /* system is unusable */
@@ -60,6 +61,9 @@ typedef enum {
GF_LOG_TRACE, /* full trace of operation */
} gf_loglevel_t;
+#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define DEFAULT_LOG_LEVEL GF_LOG_INFO
+
typedef struct gf_log_handle_ {
pthread_mutex_t logfile_mutex;
uint8_t logrotate;
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index 939b4f2a7..31f49f75c 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -148,7 +148,7 @@ char * gf_strdup (const char *src)
}
static inline void *
-gf_memdup (const void *src, void *dst, size_t size)
+gf_memdup (const void *src, size_t size)
{
void *dup_mem = NULL;
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
index 7dcbfb3dc..666bd120a 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -115,6 +115,11 @@ enum gf_common_mem_types_ {
gf_common_mt_client_ctx = 99,
gf_common_mt_lock_table = 100,
gf_common_mt_locker = 101,
- gf_common_mt_end = 102
+ gf_common_mt_auxgids = 102,
+ gf_common_mt_syncopctx = 103,
+ gf_common_mt_uuid_t = 104,
+ gf_common_mt_mgmt_v3_lock_obj_t = 105,
+ gf_common_mt_txn_opinfo_obj_t = 106,
+ gf_common_mt_end = 107
};
#endif
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
index ebe7f3962..4fd2a3a0d 100644
--- a/libglusterfs/src/run.c
+++ b/libglusterfs/src/run.c
@@ -187,7 +187,7 @@ runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
if (len > 0)
buf[len - 1] = '\0';
- gf_log (dom, lvl, "%s: %s", msg, buf);
+ gf_log_callingfn (dom, lvl, "%s: %s", msg, buf);
GF_FREE (buf);
}
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index 0e8b705bd..f2d2ef950 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -25,8 +25,8 @@ struct _call_stack_t;
typedef struct _call_stack_t call_stack_t;
struct _call_frame_t;
typedef struct _call_frame_t call_frame_t;
-struct _call_pool_t;
-typedef struct _call_pool_t call_pool_t;
+struct call_pool;
+typedef struct call_pool call_pool_t;
#include <sys/time.h>
@@ -36,6 +36,7 @@ typedef struct _call_pool_t call_pool_t;
#include "common-utils.h"
#include "globals.h"
#include "lkowner.h"
+#include "client_t.h"
#define NFS_PID 1
#define LOW_PRIO_PROC_PID -1
@@ -46,7 +47,7 @@ typedef int32_t (*ret_fn_t) (call_frame_t *frame,
int32_t op_errno,
...);
-struct _call_pool_t {
+struct call_pool {
union {
struct list_head all_frames;
struct {
@@ -94,7 +95,7 @@ struct _call_stack_t {
};
call_pool_t *pool;
gf_lock_t stack_lock;
- void *trans;
+ client_t *client;
uint64_t unique;
void *state; /* pointer to request state */
uid_t uid;
diff --git a/libglusterfs/src/store.c b/libglusterfs/src/store.c
index 48c79ee02..1e6601837 100644
--- a/libglusterfs/src/store.c
+++ b/libglusterfs/src/store.c
@@ -168,10 +168,12 @@ int
gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key,
char **iter_val, gf_store_op_errno_t *store_errno)
{
- int32_t ret = -1;
- char *savetok = NULL;
- char *key = NULL;
- char *value = NULL;
+ int32_t ret = -1;
+ char *savetok = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char *temp = NULL;
+ size_t str_len = 0;
GF_ASSERT (file);
GF_ASSERT (str);
@@ -179,13 +181,17 @@ gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key,
GF_ASSERT (iter_val);
GF_ASSERT (store_errno);
- ret = fscanf (file, "%s", str);
- if (ret <= 0 || feof (file)) {
+ temp = fgets (str, PATH_MAX, file);
+ if (temp == NULL || feof (file)) {
ret = -1;
*store_errno = GD_STORE_EOF;
goto out;
}
+ str_len = strlen(str);
+ str[str_len - 1] = '\0';
+ /* Truncate the "\n", as fgets stores "\n" in str */
+
key = strtok_r (str, "=", &savetok);
if (!key) {
ret = -1;
@@ -253,8 +259,13 @@ gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value)
goto out;
}
- scan_str = GF_CALLOC (1, st.st_size,
+ /* "st.st_size + 1" is used as we are fetching each
+ * line of a file using fgets, fgets will append "\0"
+ * to the end of the string
+ */
+ scan_str = GF_CALLOC (1, st.st_size + 1,
gf_common_mt_char);
+
if (scan_str == NULL) {
ret = -1;
store_errno = GD_STORE_ENOMEM;
@@ -532,7 +543,11 @@ gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value,
goto out;
}
- scan_str = GF_CALLOC (1, st.st_size,
+ /* "st.st_size + 1" is used as we are fetching each
+ * line of a file using fgets, fgets will append "\0"
+ * to the end of the string
+ */
+ scan_str = GF_CALLOC (1, st.st_size + 1,
gf_common_mt_char);
if (!scan_str) {
ret = -1;
@@ -596,7 +611,9 @@ gf_store_iter_get_matching (gf_store_iter_t *iter, char *key, char **value)
goto out;
}
GF_FREE (tmp_key);
+ tmp_key = NULL;
GF_FREE (tmp_value);
+ tmp_value = NULL;
ret = gf_store_iter_get_next (iter, &tmp_key, &tmp_value,
NULL);
}
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index d2c8381a3..c1620bb70 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -15,6 +15,160 @@
#include "syncop.h"
+int
+syncopctx_setfsuid (void *uid)
+{
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (!uid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx ();
+
+ /* alloc for this thread the first time */
+ if (!opctx) {
+ opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
+ if (!opctx) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncopctx_setctx (opctx);
+ if (ret != 0) {
+ GF_FREE (opctx);
+ opctx = NULL;
+ goto out;
+ }
+ }
+
+out:
+ if (opctx && uid) {
+ opctx->uid = *(uid_t *)uid;
+ opctx->valid |= SYNCOPCTX_UID;
+ }
+
+ return ret;
+}
+
+int
+syncopctx_setfsgid (void *gid)
+{
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (!gid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx ();
+
+ /* alloc for this thread the first time */
+ if (!opctx) {
+ opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
+ if (!opctx) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncopctx_setctx (opctx);
+ if (ret != 0) {
+ GF_FREE (opctx);
+ opctx = NULL;
+ goto out;
+ }
+ }
+
+out:
+ if (opctx && gid) {
+ opctx->gid = *(gid_t *)gid;
+ opctx->valid |= SYNCOPCTX_GID;
+ }
+
+ return ret;
+}
+
+int
+syncopctx_setfsgroups (int count, const void *groups)
+{
+ struct syncopctx *opctx = NULL;
+ gid_t *tmpgroups = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (count != 0 && !groups) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx ();
+
+ /* alloc for this thread the first time */
+ if (!opctx) {
+ opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
+ if (!opctx) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncopctx_setctx (opctx);
+ if (ret != 0) {
+ GF_FREE (opctx);
+ opctx = NULL;
+ goto out;
+ }
+ }
+
+ /* resize internal groups as required */
+ if (count && opctx->grpsize < count) {
+ if (opctx->groups) {
+ tmpgroups = GF_REALLOC (opctx->groups,
+ (sizeof (gid_t) * count));
+ /* NOTE: Not really required to zero the reallocation,
+ * as ngrps controls the validity of data,
+ * making a note irrespective */
+ if (tmpgroups == NULL) {
+ opctx->grpsize = 0;
+ GF_FREE (opctx->groups);
+ opctx->groups = NULL;
+ ret = -1;
+ goto out;
+ }
+ }
+ else {
+ tmpgroups = GF_CALLOC (count, sizeof (gid_t),
+ gf_common_mt_syncopctx);
+ if (tmpgroups == NULL) {
+ opctx->grpsize = 0;
+ ret = -1;
+ goto out;
+ }
+ }
+
+ opctx->groups = tmpgroups;
+ opctx->grpsize = count;
+ }
+
+ /* copy out the groups passed */
+ if (count)
+ memcpy (opctx->groups, groups, (sizeof (gid_t) * count));
+
+ /* set/reset the ngrps, this is where reset of groups is handled */
+ opctx->ngrps = count;
+ opctx->valid |= SYNCOPCTX_GROUPS;
+
+out:
+ return ret;
+}
+
static void
__run (struct synctask *task)
{
@@ -453,8 +607,8 @@ syncenv_scale (struct syncenv *env)
}
env->proc[i].env = env;
- ret = pthread_create (&env->proc[i].processor, NULL,
- syncenv_processor, &env->proc[i]);
+ ret = gf_thread_create (&env->proc[i].processor, NULL,
+ syncenv_processor, &env->proc[i]);
if (ret)
break;
env->procs++;
@@ -507,8 +661,8 @@ syncenv_new (size_t stacksize, int procmin, int procmax)
for (i = 0; i < newenv->procmin; i++) {
newenv->proc[i].env = newenv;
- ret = pthread_create (&newenv->proc[i].processor, NULL,
- syncenv_processor, &newenv->proc[i]);
+ ret = gf_thread_create (&newenv->proc[i].processor, NULL,
+ syncenv_processor, &newenv->proc[i]);
if (ret)
break;
newenv->procs++;
@@ -2019,6 +2173,35 @@ syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len)
return args.op_ret;
}
+int
+syncop_zerofill_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, size_t len)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_zerofill_cbk, subvol->fops->zerofill,
+ fd, offset, len, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
int
syncop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 64350030e..f790981f0 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -25,6 +25,13 @@
#define SYNCENV_PROC_MIN 2
#define SYNCPROC_IDLE_TIME 600
+/*
+ * Flags for syncopctx valid elements
+ */
+#define SYNCOPCTX_UID 0x00000001
+#define SYNCOPCTX_GID 0x00000002
+#define SYNCOPCTX_GROUPS 0x00000004
+
struct synctask;
struct syncproc;
struct syncenv;
@@ -150,6 +157,14 @@ struct syncargs {
int done;
};
+struct syncopctx {
+ unsigned int valid; /* valid flags for elements that are set */
+ uid_t uid;
+ gid_t gid;
+ int grpsize;
+ int ngrps;
+ gid_t *groups;
+};
#define __yawn(args) do { \
args->task = synctask_get (); \
@@ -242,34 +257,63 @@ void synctask_waitfor (struct synctask *task, int count);
int synctask_setid (struct synctask *task, uid_t uid, gid_t gid);
#define SYNCTASK_SETID(uid, gid) synctask_setid (synctask_get(), uid, gid);
+int syncopctx_setfsuid (void *uid);
+int syncopctx_setfsgid (void *gid);
+int syncopctx_setfsgroups (int count, const void *groups);
static inline call_frame_t *
syncop_create_frame (xlator_t *this)
{
- call_frame_t *frame = NULL;
- int ngrps = -1;
+ call_frame_t *frame = NULL;
+ int ngrps = -1;
+ struct syncopctx *opctx = NULL;
frame = create_frame (this, this->ctx->pool);
if (!frame)
return NULL;
- frame->root->pid = getpid();
- frame->root->uid = geteuid ();
- frame->root->gid = getegid ();
- ngrps = getgroups (0, 0);
- if (ngrps < 0) {
- STACK_DESTROY (frame->root);
- return NULL;
- }
+ frame->root->pid = getpid ();
- if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
- STACK_DESTROY (frame->root);
- return NULL;
- }
+ opctx = syncopctx_getctx ();
+ if (opctx && (opctx->valid & SYNCOPCTX_UID))
+ frame->root->uid = opctx->uid;
+ else
+ frame->root->uid = geteuid ();
- if (getgroups (ngrps, frame->root->groups) < 0) {
- STACK_DESTROY (frame->root);
- return NULL;
+ if (opctx && (opctx->valid & SYNCOPCTX_GID))
+ frame->root->gid = opctx->gid;
+ else
+ frame->root->gid = getegid ();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_GROUPS)) {
+ ngrps = opctx->ngrps;
+
+ if (ngrps != 0 && opctx->groups != NULL) {
+ if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+
+ memcpy (frame->root->groups, opctx->groups,
+ (sizeof (gid_t) * ngrps));
+ }
+ }
+ else {
+ ngrps = getgroups (0, 0);
+ if (ngrps < 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+
+ if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+
+ if (getgroups (ngrps, frame->root->groups) < 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
}
return frame;
@@ -359,6 +403,8 @@ int syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset
size_t len);
int syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len);
+int syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, size_t len);
+
int syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc);
int syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock);
diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c
index ae40142ad..a059cc212 100644
--- a/libglusterfs/src/timer.c
+++ b/libglusterfs/src/timer.c
@@ -17,19 +17,18 @@
#include "logging.h"
#include "common-utils.h"
#include "globals.h"
-
-#define TS(tv) ((((unsigned long long) tv.tv_sec) * 1000000) + (tv.tv_usec))
+#include "timespec.h"
gf_timer_t *
gf_timer_call_after (glusterfs_ctx_t *ctx,
- struct timeval delta,
+ struct timespec delta,
gf_timer_cbk_t callbk,
void *data)
{
gf_timer_registry_t *reg = NULL;
gf_timer_t *event = NULL;
gf_timer_t *trav = NULL;
- unsigned long long at = 0L;
+ uint64_t at = 0;
if (ctx == NULL)
{
@@ -48,10 +47,8 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,
if (!event) {
return NULL;
}
- gettimeofday (&event->at, NULL);
- event->at.tv_usec = ((event->at.tv_usec + delta.tv_usec) % 1000000);
- event->at.tv_sec += ((event->at.tv_usec + delta.tv_usec) / 1000000);
- event->at.tv_sec += delta.tv_sec;
+ timespec_now (&event->at);
+ timespec_adjust_delta (&event->at, delta);
at = TS (event->at);
event->callbk = callbk;
event->data = data;
@@ -127,7 +124,7 @@ void *
gf_timer_proc (void *ctx)
{
gf_timer_registry_t *reg = NULL;
- const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
+ const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
if (ctx == NULL)
{
@@ -142,14 +139,14 @@ gf_timer_proc (void *ctx)
}
while (!reg->fin) {
- unsigned long long now;
- struct timeval now_tv;
+ uint64_t now;
+ struct timespec now_ts;
gf_timer_t *event = NULL;
- gettimeofday (&now_tv, NULL);
- now = TS (now_tv);
+ timespec_now (&now_ts);
+ now = TS (now_ts);
while (1) {
- unsigned long long at;
+ uint64_t at;
char need_cbk = 0;
pthread_mutex_lock (&reg->lock);
@@ -213,7 +210,7 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx)
reg->stale.prev = &reg->stale;
ctx->timer = reg;
- pthread_create (&reg->th, NULL, gf_timer_proc, ctx);
+ gf_thread_create (&reg->th, NULL, gf_timer_proc, ctx);
}
out:
return ctx->timer;
diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h
index 2954f6aff..2f963adbf 100644
--- a/libglusterfs/src/timer.h
+++ b/libglusterfs/src/timer.h
@@ -25,7 +25,7 @@ typedef void (*gf_timer_cbk_t) (void *);
struct _gf_timer {
struct _gf_timer *next, *prev;
- struct timeval at;
+ struct timespec at;
gf_timer_cbk_t callbk;
void *data;
xlator_t *xl;
@@ -44,7 +44,7 @@ typedef struct _gf_timer_registry gf_timer_registry_t;
gf_timer_t *
gf_timer_call_after (glusterfs_ctx_t *ctx,
- struct timeval delta,
+ struct timespec delta,
gf_timer_cbk_t cbk,
void *data);
diff --git a/libglusterfs/src/timespec.c b/libglusterfs/src/timespec.c
new file mode 100644
index 000000000..a0c281a1e
--- /dev/null
+++ b/libglusterfs/src/timespec.c
@@ -0,0 +1,68 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#include <stdio.h>
+#include <inttypes.h>
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || defined GF_BSD_HOST_OS
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#if defined GF_DARWIN_HOST_OS
+#include <mach/mach_time.h>
+#endif
+
+#include "logging.h"
+#include "time.h"
+
+
+void tv2ts (struct timeval tv, struct timespec *ts)
+{
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec * 1000;
+}
+
+void timespec_now (struct timespec *ts)
+{
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || defined GF_BSD_HOST_OS
+
+ if (0 == clock_gettime(CLOCK_MONOTONIC, ts))
+ return;
+ else {
+ struct timeval tv;
+ if (0 == gettimeofday(&tv, NULL))
+ tv2ts(tv, ts);
+ }
+#elif defined GF_DARWIN_HOST_OS
+ mach_timebase_info_data_t tb = { 0 };
+ static double timebase = 0.0;
+ uint64_t time = 0;
+ mach_timebase_info (&tb);
+
+ timebase *= info.numer;
+ timebase /= info.denom;
+
+ time = mach_absolute_time();
+ time *= timebase;
+
+ ts->tv_sec = (time * NANO);
+ ts->tv_nsec = (time - (ts.tv_sec * GIGA));
+
+#endif /* Platform verification */
+ gf_log_callingfn ("timer", GF_LOG_DEBUG, "%"PRIu64".%09"PRIu64,
+ ts->tv_sec, ts->tv_nsec);
+}
+
+void timespec_adjust_delta (struct timespec *ts, struct timespec delta)
+{
+ ts->tv_nsec = ((ts->tv_nsec + delta.tv_nsec) % 1000000000);
+ ts->tv_sec += ((ts->tv_nsec + delta.tv_nsec) / 1000000000);
+ ts->tv_sec += delta.tv_sec;
+}
diff --git a/libglusterfs/src/timespec.h b/libglusterfs/src/timespec.h
new file mode 100644
index 000000000..490255df9
--- /dev/null
+++ b/libglusterfs/src/timespec.h
@@ -0,0 +1,24 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef __INCLUDE_TIMESPEC_H__
+#define __INCLUDE_TIMESPEC_H__
+
+#include <stdint.h>
+
+#define TS(ts) ((ts.tv_sec * 1000000000LL) + ts.tv_nsec)
+#define NANO (+1.0E-9)
+#define GIGA UINT64_C(1000000000)
+
+void tv2ts (struct timeval tv, struct timespec *ts);
+void timespec_now (struct timespec *ts);
+void timespec_adjust_delta (struct timespec *ts, struct timespec delta);
+
+#endif /* __INCLUDE_TIMESPEC_H__ */
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index a7caedf02..a277c58a8 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -81,6 +81,7 @@ fill_defaults (xlator_t *xl)
SET_DEFAULT_FOP (fsetattr);
SET_DEFAULT_FOP (fallocate);
SET_DEFAULT_FOP (discard);
+ SET_DEFAULT_FOP (zerofill);
SET_DEFAULT_FOP (getspec);
@@ -361,29 +362,6 @@ out:
return search;
}
-xlator_t *
-xlator_search_by_xl_type (xlator_t *any, const char *type)
-{
- xlator_t *search = NULL;
-
- GF_VALIDATE_OR_GOTO ("xlator", any, out);
- GF_VALIDATE_OR_GOTO ("xlator", type, out);
-
- search = any;
-
- while (search->prev)
- search = search->prev;
-
- while (search) {
- if (!strcmp (search->type, type))
- break;
- search = search->next;
- }
-
-out:
- return search;
-}
-
static int
__xlator_init(xlator_t *xl)
{
@@ -538,10 +516,26 @@ out:
return;
}
+int
+xlator_list_destroy (xlator_list_t *list)
+{
+ xlator_list_t *next = NULL;
+
+ while (list) {
+ next = list->next;
+ GF_FREE (list);
+ list = next;
+ }
+
+ return 0;
+}
+
int
xlator_tree_free (xlator_t *tree)
{
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp = NULL;
xlator_t *trav = tree;
xlator_t *prev = tree;
@@ -552,9 +546,19 @@ xlator_tree_free (xlator_t *tree)
while (prev) {
trav = prev->next;
- dict_destroy (prev->options);
+ if (prev->dlhandle)
+ dlclose (prev->dlhandle);
+ dict_unref (prev->options);
GF_FREE (prev->name);
GF_FREE (prev->type);
+ xlator_list_destroy (prev->children);
+ xlator_list_destroy (prev->parents);
+
+ list_for_each_entry_safe (vol_opt, tmp, &prev->volume_options,
+ list) {
+ list_del_init (&vol_opt->list);
+ GF_FREE (vol_opt);
+ }
GF_FREE (prev);
prev = trav;
}
@@ -696,21 +700,6 @@ loc_is_root (loc_t *loc)
}
int
-xlator_list_destroy (xlator_list_t *list)
-{
- xlator_list_t *next = NULL;
-
- while (list) {
- next = list->next;
- GF_FREE (list);
- list = next;
- }
-
- return 0;
-}
-
-
-int
xlator_destroy (xlator_t *xl)
{
volume_opt_list_t *vol_opt = NULL;
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index d23ee0c25..b57e5873e 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -66,6 +66,7 @@ typedef int32_t (*event_notify_fn_t) (xlator_t *this, int32_t event, void *data,
#include "globals.h"
#include "iatt.h"
#include "options.h"
+#include "client_t.h"
struct _loc {
@@ -433,6 +434,14 @@ typedef int32_t (*fop_discard_cbk_t) (call_frame_t *frame,
struct iatt *preop_stbuf,
struct iatt *postop_stbuf, dict_t *xdata);
+typedef int32_t (*fop_zerofill_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
typedef int32_t (*fop_lookup_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
@@ -664,6 +673,12 @@ typedef int32_t (*fop_discard_t) (call_frame_t *frame,
off_t offset,
size_t len,
dict_t *xdata);
+typedef int32_t (*fop_zerofill_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len,
+ dict_t *xdata);
struct xlator_fops {
fop_lookup_t lookup;
@@ -710,6 +725,7 @@ struct xlator_fops {
fop_getspec_t getspec;
fop_fallocate_t fallocate;
fop_discard_t discard;
+ fop_zerofill_t zerofill;
/* these entries are used for a typechecking hack in STACK_WIND _only_ */
fop_lookup_cbk_t lookup_cbk;
@@ -756,6 +772,7 @@ struct xlator_fops {
fop_getspec_cbk_t getspec_cbk;
fop_fallocate_cbk_t fallocate_cbk;
fop_discard_cbk_t discard_cbk;
+ fop_zerofill_cbk_t zerofill_cbk;
};
typedef int32_t (*cbk_forget_t) (xlator_t *this,
@@ -766,11 +783,15 @@ typedef int32_t (*cbk_release_t) (xlator_t *this,
typedef int32_t (*cbk_invalidate_t)(xlator_t *this, inode_t *inode);
+typedef int32_t (*cbk_client_t)(xlator_t *this, client_t *client);
+
struct xlator_cbks {
- cbk_forget_t forget;
- cbk_release_t release;
- cbk_release_t releasedir;
- cbk_invalidate_t invalidate;
+ cbk_forget_t forget;
+ cbk_release_t release;
+ cbk_release_t releasedir;
+ cbk_invalidate_t invalidate;
+ cbk_client_t client_destroy;
+ cbk_client_t client_disconnect;
};
typedef int32_t (*dumpop_priv_t) (xlator_t *this);
@@ -912,7 +933,6 @@ void xlator_foreach_depth_first (xlator_t *this,
void *data);
xlator_t *xlator_search_by_name (xlator_t *any, const char *name);
-xlator_t *xlator_search_by_xl_type (xlator_t *any, const char *type);
void inode_destroy_notify (inode_t *inode, const char *xlname);
@@ -932,5 +952,9 @@ enum gf_hdsk_event_notify_op {
GF_EN_DEFRAG_STATUS,
GF_EN_MAX,
};
-
+gf_boolean_t
+is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2);
+int
+glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
+ glusterfs_ctx_t *ctx, const char *oldvolfile);
#endif /* _XLATOR_H */