diff options
Diffstat (limited to 'libglusterfs/src')
41 files changed, 1564 insertions, 535 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 068b307e1..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; @@ -389,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; @@ -427,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; @@ -451,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 282cee381..a220abeb9 100644 --- a/libglusterfs/src/graph.y +++ b/libglusterfs/src/graph.y @@ -38,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 (); %} @@ -79,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; } @@ -91,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; } @@ -103,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; } @@ -116,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; @@ -130,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; } @@ -150,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; } @@ -195,7 +195,7 @@ out: static int volume_type (char *type) { - extern int yylineno; + extern int graphyylineno; int32_t ret = 0; if (!type) { @@ -209,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; } @@ -226,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; @@ -243,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; } @@ -262,7 +262,7 @@ out: static int volume_sub (char *sub) { - extern int yylineno; + extern int graphyylineno; xlator_t *trav = NULL; int ret = 0; @@ -284,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; } @@ -292,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; } @@ -329,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'"); } @@ -377,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; @@ -482,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; } @@ -523,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); @@ -530,7 +532,7 @@ out: } -extern FILE *yyin; +extern FILE *graphyyin; glusterfs_graph_t * glusterfs_graph_new () @@ -587,7 +589,7 @@ glusterfs_graph_construct (FILE *fp) pthread_mutex_lock (&graph_mutex); { - yyin = tmp_file; + graphyyin = tmp_file; construct = graph; ret = yyparse (); construct = NULL; 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-types.h b/libglusterfs/src/mem-types.h index 3b0f7d276..666bd120a 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -115,7 +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_auxgids = 102, - gf_common_mt_end = 103 + 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 (®->lock); @@ -213,7 +210,7 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx) reg->stale.prev = ®->stale; ctx->timer = reg; - pthread_create (®->th, NULL, gf_timer_proc, ctx); + gf_thread_create (®->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 */ |
