diff options
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h | 1 | ||||
-rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.c | 199 | ||||
-rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.h | 6 |
3 files changed, 174 insertions, 32 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h b/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h index 504b8ab3635..fbb69ce7ea8 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h @@ -30,6 +30,7 @@ enum br_mem_types { gf_br_mt_br_fsscan_entry_t, gf_br_stub_mt_br_stub_fd_t, gf_br_stub_mt_br_scanner_freq_t, + gf_br_stub_mt_sigstub_t, gf_br_stub_mt_end, }; diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index 524c235b549..1827f48c1c9 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -21,6 +21,7 @@ #include "logging.h" #include "changelog.h" #include "compat-errno.h" +#include "call-stub.h" #include "bit-rot-stub.h" #include "bit-rot-stub-mem-types.h" @@ -29,6 +30,16 @@ #define BR_STUB_REQUEST_COOKIE 0x1 +void *br_stub_signth (void *); + +struct br_stub_signentry { + unsigned long v; + + call_stub_t *stub; + + struct list_head list; +}; + int32_t mem_acct_init (xlator_t *this) { @@ -51,6 +62,7 @@ mem_acct_init (xlator_t *this) int32_t init (xlator_t *this) { + int32_t ret = 0; char *tmp = NULL; struct timeval tv = {0,}; br_stub_private_t *priv = NULL; @@ -79,10 +91,22 @@ init (xlator_t *this) priv->boot[0] = htonl (tv.tv_sec); priv->boot[1] = htonl (tv.tv_usec); + pthread_mutex_init (&priv->lock, NULL); + pthread_cond_init (&priv->cond, NULL); + INIT_LIST_HEAD (&priv->squeue); + + ret = gf_thread_create (&priv->signth, NULL, br_stub_signth, priv); + if (ret != 0) + goto cleanup_lock; + gf_log (this->name, GF_LOG_DEBUG, "bit-rot stub loaded"); this->private = priv; + return 0; + cleanup_lock: + pthread_cond_destroy (&priv->cond); + pthread_mutex_destroy (&priv->lock); free_mempool: mem_pool_destroy (priv->local_pool); free_priv: @@ -94,13 +118,36 @@ init (xlator_t *this) void fini (xlator_t *this) { + int32_t ret = 0; br_stub_private_t *priv = this->private; + struct br_stub_signentry *sigstub = NULL; if (!priv) return; + + ret = gf_thread_cleanup_xint (priv->signth); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Could not cancel sign serializer thread"); + goto out; + } + + while (!list_empty (&priv->squeue)) { + sigstub = list_first_entry (&priv->squeue, + struct br_stub_signentry, list); + list_del_init (&sigstub->list); + + call_stub_destroy (sigstub->stub); + GF_FREE (sigstub); + } + + pthread_mutex_destroy (&priv->lock); + pthread_cond_destroy (&priv->cond); + this->private = NULL; GF_FREE (priv); + out: return; } @@ -567,13 +614,66 @@ br_stub_perform_incversioning (xlator_t *this, /* fsetxattr() */ +int32_t +br_stub_perform_objsign (call_frame_t *frame, xlator_t *this, + fd_t *fd, dict_t *dict, int flags, dict_t *xdata) +{ + STACK_WIND (frame, default_setxattr_cbk, + FIRST_CHILD (this), FIRST_CHILD (this)->fops->fsetxattr, fd, + dict, flags, xdata); + + dict_unref (xdata); + return 0; +} + +void * +br_stub_signth (void *arg) +{ + br_stub_private_t *priv = arg; + struct br_stub_signentry *sigstub = NULL; + + while (1) { + pthread_mutex_lock (&priv->lock); + { + while (list_empty (&priv->squeue)) + pthread_cond_wait (&priv->cond, &priv->lock); + + sigstub = list_first_entry + (&priv->squeue, struct br_stub_signentry, list); + list_del_init (&sigstub->list); + } + pthread_mutex_unlock (&priv->lock); + + call_resume (sigstub->stub); + + GF_FREE (sigstub); + } + + return NULL; +} + +int +orderq (struct list_head *elem1, struct list_head *elem2) +{ + struct br_stub_signentry *s1 = NULL; + struct br_stub_signentry *s2 = NULL; + + s1 = list_entry (elem1, struct br_stub_signentry, list); + s2 = list_entry (elem2, struct br_stub_signentry, list); + + return (s1->v > s2->v); +} + static inline int -br_stub_compare_sign_version (xlator_t *this, inode_t *inode, - br_signature_t *sbuf, dict_t *dict) +br_stub_compare_sign_version (xlator_t *this, + inode_t *inode, + br_signature_t *sbuf, + dict_t *dict, int *fakesuccess) { - int32_t ret = -1; - br_stub_inode_ctx_t *ctx = NULL; - uint64_t tmp_ctx = 0; + int32_t ret = -1; + uint64_t tmp_ctx = 0; + gf_boolean_t invalid = _gf_false; + br_stub_inode_ctx_t *ctx = NULL; GF_VALIDATE_OR_GOTO ("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO (this->name, inode, out); @@ -586,28 +686,36 @@ br_stub_compare_sign_version (xlator_t *this, inode_t *inode, goto out; } - ret = -1; ctx = (br_stub_inode_ctx_t *)(long)tmp_ctx; LOCK (&inode->lock); { - if (ctx->currentversion == sbuf->signedversion) - ret = 0; - else - gf_log (this->name, GF_LOG_WARNING, "current version " - "%lu and version of the signature %lu are not " - "same", ctx->currentversion, - sbuf->signedversion); + if (ctx->currentversion < sbuf->signedversion) { + invalid = _gf_true; + } else if (ctx->currentversion > sbuf->signedversion) { + gf_log (this->name, GF_LOG_DEBUG, "\"Signing version\" " + "(%lu) lower than \"Current version \" (%lu)", + ctx->currentversion, sbuf->signedversion); + *fakesuccess = 1; + } } UNLOCK (&inode->lock); -out: + if (invalid) { + ret = -1; + gf_log (this->name, GF_LOG_WARNING, + "Signing version exceeds current version [%lu > %lu]", + sbuf->signedversion, ctx->currentversion); + } + + out: return ret; } static inline int -br_stub_prepare_signature (xlator_t *this, dict_t *dict, - inode_t *inode, br_isignature_t *sign) +br_stub_prepare_signature (xlator_t *this, + dict_t *dict, inode_t *inode, + br_isignature_t *sign, int *fakesuccess) { int32_t ret = 0; size_t signaturelen = 0; @@ -624,7 +732,8 @@ br_stub_prepare_signature (xlator_t *this, dict_t *dict, if (ret) goto dealloc_versions; - ret = br_stub_compare_sign_version (this, inode, sbuf, dict); + ret = br_stub_compare_sign_version (this, inode, + sbuf, dict, fakesuccess); if (ret) goto dealloc_versions; @@ -641,15 +750,27 @@ br_stub_handle_object_signature (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, br_isignature_t *sign, dict_t *xdata) { - int32_t ret = -1; - gf_boolean_t xref = _gf_false; + int32_t ret = -1; + int32_t op_ret = -1; + int32_t op_errno = EINVAL; + int fakesuccess = 0; + br_stub_private_t *priv = NULL; + struct br_stub_signentry *sigstub = NULL; + + priv = this->private; if (frame->root->pid != GF_CLIENT_PID_BITD) goto dofop; - ret = br_stub_prepare_signature (this, dict, fd->inode, sign); + ret = br_stub_prepare_signature (this, dict, + fd->inode, sign, &fakesuccess); if (ret) goto dofop; + if (fakesuccess) { + op_ret = op_errno = 0; + goto dofop; + } + dict_del (dict, GLUSTERFS_SET_OBJECT_SIGNATURE); ret = -1; @@ -661,23 +782,37 @@ br_stub_handle_object_signature (call_frame_t *frame, dict_ref (xdata); } - xref = _gf_true; ret = dict_set_int32 (xdata, GLUSTERFS_DURABLE_OP, 0); - - dofop: if (ret) - STACK_UNWIND_STRICT (fsetxattr, frame, -1, EINVAL, NULL); - else { - gf_log (this->name, GF_LOG_DEBUG, "SIGNED VERSION: %lu", - sign->signedversion); + goto unref_dict; + + /* prepare dispatch stub to order object signing */ + sigstub = GF_CALLOC (1, sizeof (*sigstub), gf_br_stub_mt_sigstub_t); + if (!sigstub) + goto unref_dict; + + INIT_LIST_HEAD (&sigstub->list); + sigstub->v = ntohl (sign->signedversion); + sigstub->stub = fop_fsetxattr_stub (frame, br_stub_perform_objsign, + fd, dict, 0, xdata); + if (!sigstub->stub) + goto cleanup_stub; - STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->fsetxattr, fd, dict, 0, - xdata); + pthread_mutex_lock (&priv->lock); + { + list_add_order (&sigstub->list, &priv->squeue, orderq); + pthread_cond_signal (&priv->cond); } + pthread_mutex_unlock (&priv->lock); - if (xref) - dict_unref (xdata); + return; + + cleanup_stub: + GF_FREE (sigstub); + unref_dict: + dict_unref (xdata); + dofop: + STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, NULL); } int32_t diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.h b/xlators/features/bit-rot/src/stub/bit-rot-stub.h index e1e7b383f42..9304ef80c51 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.h +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.h @@ -75,6 +75,12 @@ typedef struct br_stub_private { uint32_t boot[2]; char export[PATH_MAX]; + pthread_mutex_t lock; + pthread_cond_t cond; + + struct list_head squeue; /* ordered signing queue */ + pthread_t signth; + struct mem_pool *local_pool; } br_stub_private_t; |