diff options
Diffstat (limited to 'xlators/cluster/dht/src/dht-helper.c')
-rw-r--r-- | xlators/cluster/dht/src/dht-helper.c | 662 |
1 files changed, 14 insertions, 648 deletions
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c index 0a2abfb697b..6f08f557730 100644 --- a/xlators/cluster/dht/src/dht-helper.c +++ b/xlators/cluster/dht/src/dht-helper.c @@ -12,8 +12,7 @@ #include "glusterfs.h" #include "xlator.h" #include "dht-common.h" -#include "dht-helper.h" - +#include "dht-lock.h" static void dht_free_fd_ctx (dht_fd_ctx_t *fd_ctx) @@ -400,170 +399,11 @@ dht_deitransform (xlator_t *this, uint64_t y, xlator_t **subvol_p) return 0; } -char * -dht_lock_asprintf (dht_lock_t *lock) -{ - char *lk_buf = NULL; - char gfid[GF_UUID_BUF_SIZE] = {0, }; - - if (lock == NULL) - goto out; - - uuid_utoa_r (lock->loc.gfid, gfid); - - gf_asprintf (&lk_buf, "%s:%s", lock->xl->name, gfid); - -out: - return lk_buf; -} - -void -dht_log_lk_array (char *name, gf_loglevel_t log_level, dht_lock_t **lk_array, - int count) -{ - int i = 0; - char *lk_buf = NULL; - - if ((lk_array == NULL) || (count == 0)) - goto out; - - for (i = 0; i < count; i++) { - lk_buf = dht_lock_asprintf (lk_array[i]); - gf_msg (name, log_level, 0, DHT_MSG_LK_ARRAY_INFO, - "%d. %s", i, lk_buf); - GF_FREE (lk_buf); - } - -out: - return; -} - -void -dht_lock_stack_destroy (call_frame_t *lock_frame) -{ - dht_local_t *local = NULL; - - local = lock_frame->local; - - local->lock.locks = NULL; - local->lock.lk_count = 0; - - DHT_STACK_DESTROY (lock_frame); - return; -} - -void -dht_lock_free (dht_lock_t *lock) -{ - if (lock == NULL) - goto out; - - loc_wipe (&lock->loc); - GF_FREE (lock->domain); - mem_put (lock); - -out: - return; -} - -void -dht_lock_array_free (dht_lock_t **lk_array, int count) -{ - int i = 0; - dht_lock_t *lock = NULL; - - if (lk_array == NULL) - goto out; - - for (i = 0; i < count; i++) { - lock = lk_array[i]; - lk_array[i] = NULL; - dht_lock_free (lock); - } - -out: - return; -} - -dht_lock_t * -dht_lock_new (xlator_t *this, xlator_t *xl, loc_t *loc, short type, - const char *domain) -{ - dht_conf_t *conf = NULL; - dht_lock_t *lock = NULL; - - conf = this->private; - - lock = mem_get0 (conf->lock_pool); - if (lock == NULL) - goto out; - - lock->xl = xl; - lock->type = type; - - lock->domain = gf_strdup (domain); - if (lock->domain == NULL) { - dht_lock_free (lock); - lock = NULL; - goto out; - } - - /* Fill only inode and gfid. - posix and protocol/server give preference to pargfid/basename over - gfid/inode for resolution if all the three parameters of loc_t are - present. I want to avoid the following hypothetical situation: - - 1. rebalance did a lookup on a dentry and got a gfid. - 2. rebalance acquires lock on loc_t which was filled with gfid and - path (pargfid/bname) from step 1. - 3. somebody deleted and recreated the same file - 4. rename on the same path acquires lock on loc_t which now points - to a different inode (and hence gets the lock). - 5. rebalance continues to migrate file (note that not all fops done - by rebalance during migration are inode/gfid based Eg., unlink) - 6. rename continues. - */ - lock->loc.inode = inode_ref (loc->inode); - loc_gfid (loc, lock->loc.gfid); - -out: - return lock; -} - -int -dht_local_lock_init (call_frame_t *frame, dht_lock_t **lk_array, - int lk_count, fop_inodelk_cbk_t inodelk_cbk) -{ - int ret = -1; - dht_local_t *local = NULL; - - local = frame->local; - - if (local == NULL) { - local = dht_local_init (frame, NULL, NULL, 0); - } - - if (local == NULL) { - goto out; - } - - local->lock.inodelk_cbk = inodelk_cbk; - local->lock.locks = lk_array; - local->lock.lk_count = lk_count; - - ret = dht_lock_order_requests (local->lock.locks, - local->lock.lk_count); - if (ret < 0) - goto out; - - ret = 0; -out: - return ret; -} - void dht_local_wipe (xlator_t *this, dht_local_t *local) { + int i = 0; + if (!local) return; @@ -612,8 +452,16 @@ dht_local_wipe (xlator_t *this, dht_local_t *local) local->selfheal.refreshed_layout = NULL; } - dht_lock_array_free (local->lock.locks, local->lock.lk_count); - GF_FREE (local->lock.locks); + for (i = 0; i < 2; i++) { + dht_lock_array_free (local->lock[i].ns.parent_layout.locks, + local->lock[i].ns.parent_layout.lk_count); + + GF_FREE (local->lock[i].ns.parent_layout.locks); + + dht_lock_array_free (local->lock[i].ns.directory_ns.locks, + local->lock[i].ns.directory_ns.lk_count); + GF_FREE (local->lock[i].ns.directory_ns.locks); + } GF_FREE (local->key); @@ -657,6 +505,7 @@ dht_local_init (call_frame_t *frame, loc_t *loc, fd_t *fd, glusterfs_fop_t fop) goto out; inode = loc->inode; + local->hashed_subvol = dht_subvol_get_hashed (frame->this, loc); } if (fd) { @@ -1727,22 +1576,6 @@ out: return ret; } -void -dht_set_lkowner (dht_lock_t **lk_array, int count, gf_lkowner_t *lkowner) -{ - int i = 0; - - if (!lk_array || !lkowner) - goto out; - - for (i = 0; i < count; i++) { - lk_array[i]->lk_owner = *lkowner; - } - -out: - return; -} - int dht_subvol_status (dht_conf_t *conf, xlator_t *subvol) { @@ -1756,473 +1589,6 @@ dht_subvol_status (dht_conf_t *conf, xlator_t *subvol) return 0; } -void -dht_inodelk_done (call_frame_t *lock_frame) -{ - fop_inodelk_cbk_t inodelk_cbk = NULL; - call_frame_t *main_frame = NULL; - dht_local_t *local = NULL; - - local = lock_frame->local; - main_frame = local->main_frame; - - local->lock.locks = NULL; - local->lock.lk_count = 0; - - inodelk_cbk = local->lock.inodelk_cbk; - local->lock.inodelk_cbk = NULL; - - inodelk_cbk (main_frame, NULL, main_frame->this, local->lock.op_ret, - local->lock.op_errno, NULL); - - dht_lock_stack_destroy (lock_frame); - return; -} - -int -dht_inodelk_cleanup_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno, - dict_t *xdata) -{ - dht_inodelk_done (frame); - return 0; -} - -int32_t -dht_lock_count (dht_lock_t **lk_array, int lk_count) -{ - int i = 0, locked = 0; - - if ((lk_array == NULL) || (lk_count == 0)) - goto out; - - for (i = 0; i < lk_count; i++) { - if (lk_array[i]->locked) - locked++; - } -out: - return locked; -} - -void -dht_inodelk_cleanup (call_frame_t *lock_frame) -{ - dht_lock_t **lk_array = NULL; - int lk_count = 0, lk_acquired = 0; - dht_local_t *local = NULL; - - local = lock_frame->local; - - lk_array = local->lock.locks; - lk_count = local->lock.lk_count; - - lk_acquired = dht_lock_count (lk_array, lk_count); - if (lk_acquired != 0) { - dht_unlock_inodelk (lock_frame, lk_array, lk_count, - dht_inodelk_cleanup_cbk); - } else { - dht_inodelk_done (lock_frame); - } - - return; -} - -int32_t -dht_unlock_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ - dht_local_t *local = NULL; - int lk_index = 0, call_cnt = 0; - char gfid[GF_UUID_BUF_SIZE] = {0}; - - lk_index = (long) cookie; - - local = frame->local; - if (op_ret < 0) { - uuid_utoa_r (local->lock.locks[lk_index]->loc.gfid, - gfid); - - gf_msg (this->name, GF_LOG_WARNING, op_errno, - DHT_MSG_UNLOCKING_FAILED, - "unlocking failed on %s:%s", - local->lock.locks[lk_index]->xl->name, - gfid); - } else { - local->lock.locks[lk_index]->locked = 0; - } - - call_cnt = dht_frame_return (frame); - if (is_last_call (call_cnt)) { - dht_inodelk_done (frame); - } - - return 0; -} - -call_frame_t * -dht_lock_frame (call_frame_t *parent_frame) -{ - call_frame_t *lock_frame = NULL; - - lock_frame = copy_frame (parent_frame); - if (lock_frame == NULL) - goto out; - - set_lk_owner_from_ptr (&lock_frame->root->lk_owner, parent_frame->root); - -out: - return lock_frame; -} - -int32_t -dht_unlock_inodelk (call_frame_t *frame, dht_lock_t **lk_array, int lk_count, - fop_inodelk_cbk_t inodelk_cbk) -{ - dht_local_t *local = NULL; - struct gf_flock flock = {0,}; - int ret = -1 , i = 0; - call_frame_t *lock_frame = NULL; - int call_cnt = 0; - - GF_VALIDATE_OR_GOTO ("dht-locks", frame, done); - GF_VALIDATE_OR_GOTO (frame->this->name, lk_array, done); - GF_VALIDATE_OR_GOTO (frame->this->name, inodelk_cbk, done); - - call_cnt = dht_lock_count (lk_array, lk_count); - if (call_cnt == 0) { - ret = 0; - goto done; - } - - lock_frame = dht_lock_frame (frame); - if (lock_frame == NULL) { - gf_msg (frame->this->name, GF_LOG_WARNING, 0, - DHT_MSG_UNLOCKING_FAILED, - "cannot allocate a frame, not unlocking following " - "locks:"); - - dht_log_lk_array (frame->this->name, GF_LOG_WARNING, lk_array, - lk_count); - goto done; - } - - ret = dht_local_lock_init (lock_frame, lk_array, lk_count, inodelk_cbk); - if (ret < 0) { - gf_msg (frame->this->name, GF_LOG_WARNING, 0, - DHT_MSG_UNLOCKING_FAILED, - "storing locks in local failed, not unlocking " - "following locks:"); - - dht_log_lk_array (frame->this->name, GF_LOG_WARNING, lk_array, - lk_count); - - goto done; - } - - local = lock_frame->local; - local->main_frame = frame; - local->call_cnt = call_cnt; - - flock.l_type = F_UNLCK; - - for (i = 0; i < local->lock.lk_count; i++) { - if (!local->lock.locks[i]->locked) - continue; - - lock_frame->root->lk_owner = local->lock.locks[i]->lk_owner; - STACK_WIND_COOKIE (lock_frame, dht_unlock_inodelk_cbk, - (void *)(long)i, - local->lock.locks[i]->xl, - local->lock.locks[i]->xl->fops->inodelk, - local->lock.locks[i]->domain, - &local->lock.locks[i]->loc, F_SETLK, - &flock, NULL); - if (!--call_cnt) - break; - } - - return 0; - -done: - if (lock_frame) - dht_lock_stack_destroy (lock_frame); - - /* no locks acquired, invoke inodelk_cbk */ - if (ret == 0) - inodelk_cbk (frame, NULL, frame->this, 0, 0, NULL); - - return ret; -} - -int32_t -dht_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ - dht_local_t *local = NULL; - int lk_index = 0, call_cnt = 0; - char gfid[GF_UUID_BUF_SIZE] = {0}; - - local = frame->local; - lk_index = (long) cookie; - - if (op_ret == -1) { - local->lock.op_ret = -1; - local->lock.op_errno = op_errno; - - if (local && local->lock.locks[lk_index]) { - uuid_utoa_r (local->lock.locks[lk_index]->loc.inode->gfid, - gfid); - - gf_msg_debug (this->name, op_errno, - "inodelk failed on gfid: %s " - "subvolume: %s", gfid, - local->lock.locks[lk_index]->xl->name); - } - - goto out; - } - - local->lock.locks[lk_index]->locked = _gf_true; - -out: - call_cnt = dht_frame_return (frame); - if (is_last_call (call_cnt)) { - if (local->lock.op_ret < 0) { - dht_inodelk_cleanup (frame); - return 0; - } - - dht_inodelk_done (frame); - } - - return 0; -} - -int -dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array, - int lk_count, fop_inodelk_cbk_t inodelk_cbk) -{ - struct gf_flock flock = {0,}; - int i = 0, ret = 0; - dht_local_t *local = NULL; - call_frame_t *lock_frame = NULL; - - GF_VALIDATE_OR_GOTO ("dht-locks", frame, out); - GF_VALIDATE_OR_GOTO (frame->this->name, lk_array, out); - GF_VALIDATE_OR_GOTO (frame->this->name, inodelk_cbk, out); - - lock_frame = dht_lock_frame (frame); - if (lock_frame == NULL) - goto out; - - ret = dht_local_lock_init (lock_frame, lk_array, lk_count, inodelk_cbk); - if (ret < 0) { - goto out; - } - - dht_set_lkowner (lk_array, lk_count, &lock_frame->root->lk_owner); - - local = lock_frame->local; - local->main_frame = frame; - - local->call_cnt = lk_count; - - for (i = 0; i < lk_count; i++) { - flock.l_type = local->lock.locks[i]->type; - - STACK_WIND_COOKIE (lock_frame, dht_nonblocking_inodelk_cbk, - (void *) (long) i, - local->lock.locks[i]->xl, - local->lock.locks[i]->xl->fops->inodelk, - local->lock.locks[i]->domain, - &local->lock.locks[i]->loc, F_SETLK, - &flock, NULL); - } - - return 0; - -out: - if (lock_frame) - dht_lock_stack_destroy (lock_frame); - - return -1; -} - -int32_t -dht_blocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ - int lk_index = 0; - int i = 0; - dht_local_t *local = NULL; - char gfid[GF_UUID_BUF_SIZE] = {0,}; - - lk_index = (long) cookie; - - local = frame->local; - if (op_ret == 0) { - local->lock.locks[lk_index]->locked = _gf_true; - } else { - switch (op_errno) { - case ESTALE: - case ENOENT: - if (local->lock.reaction != IGNORE_ENOENT_ESTALE) { - gf_uuid_unparse (local->lock.locks[lk_index]->loc.gfid, gfid); - local->lock.op_ret = -1; - local->lock.op_errno = op_errno; - gf_msg (this->name, GF_LOG_ERROR, op_errno, - DHT_MSG_INODELK_FAILED, - "inodelk failed on subvol %s. gfid:%s", - local->lock.locks[lk_index]->xl->name, - gfid); - goto cleanup; - } - break; - default: - gf_uuid_unparse (local->lock.locks[lk_index]->loc.gfid, gfid); - local->lock.op_ret = -1; - local->lock.op_errno = op_errno; - gf_msg (this->name, GF_LOG_ERROR, op_errno, - DHT_MSG_INODELK_FAILED, - "inodelk failed on subvol %s, gfid:%s", - local->lock.locks[lk_index]->xl->name, gfid); - goto cleanup; - } - } - - if (lk_index == (local->lock.lk_count - 1)) { - for (i = 0; (i < local->lock.lk_count) && - (!local->lock.locks[i]->locked); i++) - ; - - if (i == local->lock.lk_count) { - local->lock.op_ret = -1; - local->lock.op_errno = op_errno; - } - - dht_inodelk_done (frame); - } else { - dht_blocking_inodelk_rec (frame, ++lk_index); - } - - return 0; - -cleanup: - dht_inodelk_cleanup (frame); - - return 0; -} - -void -dht_blocking_inodelk_rec (call_frame_t *frame, int i) -{ - dht_local_t *local = NULL; - struct gf_flock flock = {0,}; - - local = frame->local; - - flock.l_type = local->lock.locks[i]->type; - - STACK_WIND_COOKIE (frame, dht_blocking_inodelk_cbk, - (void *) (long) i, - local->lock.locks[i]->xl, - local->lock.locks[i]->xl->fops->inodelk, - local->lock.locks[i]->domain, - &local->lock.locks[i]->loc, F_SETLKW, &flock, NULL); - - return; -} - -int -dht_lock_request_cmp (const void *val1, const void *val2) -{ - dht_lock_t *lock1 = NULL; - dht_lock_t *lock2 = NULL; - int ret = 0; - - lock1 = *(dht_lock_t **)val1; - lock2 = *(dht_lock_t **)val2; - - GF_VALIDATE_OR_GOTO ("dht-locks", lock1, out); - GF_VALIDATE_OR_GOTO ("dht-locks", lock2, out); - - ret = strcmp (lock1->xl->name, lock2->xl->name); - - if (ret == 0) { - ret = gf_uuid_compare (lock1->loc.gfid, lock2->loc.gfid); - } - -out: - return ret; -} - -int -dht_lock_order_requests (dht_lock_t **locks, int count) -{ - int ret = -1; - - if (!locks || !count) - goto out; - - qsort (locks, count, sizeof (*locks), dht_lock_request_cmp); - ret = 0; - -out: - return ret; -} - -int -dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array, - int lk_count, dht_reaction_type_t reaction, - fop_inodelk_cbk_t inodelk_cbk) -{ - int ret = -1; - call_frame_t *lock_frame = NULL; - dht_local_t *local = NULL; - dht_local_t *tmp_local = NULL; - char gfid[GF_UUID_BUF_SIZE] = {0,}; - - GF_VALIDATE_OR_GOTO ("dht-locks", frame, out); - GF_VALIDATE_OR_GOTO (frame->this->name, lk_array, out); - GF_VALIDATE_OR_GOTO (frame->this->name, inodelk_cbk, out); - - tmp_local = frame->local; - - lock_frame = dht_lock_frame (frame); - if (lock_frame == NULL) { - gf_uuid_unparse (tmp_local->loc.gfid, gfid); - gf_msg ("dht", GF_LOG_ERROR, ENOMEM, - DHT_MSG_LOCK_FRAME_FAILED, - "memory allocation failed for lock_frame. gfid:%s" - " path:%s", gfid, tmp_local->loc.path); - goto out; - } - - ret = dht_local_lock_init (lock_frame, lk_array, lk_count, inodelk_cbk); - if (ret < 0) { - gf_uuid_unparse (tmp_local->loc.gfid, gfid); - gf_msg ("dht", GF_LOG_ERROR, ENOMEM, - DHT_MSG_LOCAL_LOCK_INIT_FAILED, - "dht_local_lock_init failed, gfid: %s path:%s", gfid, - tmp_local->loc.path); - goto out; - } - - dht_set_lkowner (lk_array, lk_count, &lock_frame->root->lk_owner); - - local = lock_frame->local; - local->lock.reaction = reaction; - local->main_frame = frame; - - dht_blocking_inodelk_rec (lock_frame, 0); - - return 0; -out: - if (lock_frame) - dht_lock_stack_destroy (lock_frame); - - return -1; -} inode_t* dht_heal_path (xlator_t *this, char *path, inode_table_t *itable) { |