From f78d789c6e9ce29f18487bd6d6a3b8f66a30a464 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Sat, 29 Dec 2012 14:03:06 +0530 Subject: protocol/client: Add fdctx back to saved-list after reopen Change-Id: I01caa1b51570359e6e3ffe1ffb7279cbdb0b0c64 BUG: 821056 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/4357 Tested-by: Gluster Build System Reviewed-by: Jeff Darcy --- xlators/protocol/client/src/client-lk.c | 360 -------------------------------- 1 file changed, 360 deletions(-) (limited to 'xlators/protocol/client/src/client-lk.c') diff --git a/xlators/protocol/client/src/client-lk.c b/xlators/protocol/client/src/client-lk.c index 5611c7b83e2..1fd8f0d5029 100644 --- a/xlators/protocol/client/src/client-lk.c +++ b/xlators/protocol/client/src/client-lk.c @@ -16,9 +16,6 @@ static void __insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock); -static int -client_send_recovery_lock (call_frame_t *frame, xlator_t *this, - client_posix_lock_t *lock); static void __dump_client_lock (client_posix_lock_t *lock) { @@ -430,21 +427,6 @@ delete_granted_locks_fd (clnt_fd_ctx_t *fdctx) return ret; } -static void -client_mark_bad_fd (fd_t *fd, clnt_fd_ctx_t *fdctx) -{ - xlator_t *this = NULL; - - this = THIS; - if (fdctx) - fdctx->remote_fd = -1; - - gf_log (this->name, GF_LOG_WARNING, - "marking the file descriptor (%p) bad", fd); - - this_fd_set_ctx (fd, this, NULL, fdctx); -} - int32_t client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd) { @@ -553,348 +535,6 @@ out: } -static int -construct_reserve_unlock (struct gf_flock *lock, call_frame_t *frame, - client_posix_lock_t *client_lock) -{ - GF_ASSERT (lock); - GF_ASSERT (frame); - - lock->l_type = F_UNLCK; - lock->l_start = 0; - lock->l_whence = SEEK_SET; - lock->l_len = 0; /* Whole file */ - lock->l_pid = (uint64_t)(unsigned long)frame->root; - lock->l_owner = client_lock->owner; - - frame->root->lk_owner = client_lock->owner; - - return 0; -} - -static int -construct_reserve_lock (client_posix_lock_t *client_lock, call_frame_t *frame, - struct gf_flock *lock) -{ - GF_ASSERT (client_lock); - - memcpy (lock, &(client_lock->user_flock), sizeof (struct gf_flock)); - - frame->root->lk_owner = client_lock->owner; - - return 0; -} - -uint64_t -decrement_reopen_fd_count (xlator_t *this, clnt_conf_t *conf) -{ - uint64_t fd_count = 0; - - LOCK (&conf->rec_lock); - { - fd_count = --(conf->reopen_fd_count); - } - UNLOCK (&conf->rec_lock); - - if (fd_count == 0) { - gf_log (this->name, GF_LOG_INFO, - "last fd open'd/lock-self-heal'd - notifying CHILD-UP"); - client_set_lk_version (this); - client_notify_parents_child_up (this); - } - - return fd_count; -} - -int32_t -client_remove_reserve_lock_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock, dict_t *xdata) -{ - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - - uint64_t fd_count = 0; - - local = frame->local; - conf = this->private; - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "removing reserver lock on fd failed: %s", - strerror(op_errno)); - goto cleanup; - } - - gf_log (this->name, GF_LOG_DEBUG, - "Removing reserve lock was successful."); - -cleanup: - frame->local = NULL; - - client_mark_bad_fd (local->client_lock->fd, local->fdctx); - - destroy_client_lock (local->client_lock); - client_local_wipe (local); - STACK_DESTROY (frame->root); - - fd_count = decrement_reopen_fd_count (this, conf); - gf_log (this->name, GF_LOG_TRACE, - "Need to attempt lock recovery on %lld open fds", - (unsigned long long) fd_count); - return 0; -} - -static void -client_remove_reserve_lock (xlator_t *this, call_frame_t *frame, - client_posix_lock_t *lock) -{ - struct gf_flock unlock; - - construct_reserve_unlock (&unlock, frame, lock); - - STACK_WIND (frame, client_remove_reserve_lock_cbk, - this, this->fops->lk, - lock->fd, F_RESLK_UNLCK, &unlock, NULL); -} - -static client_posix_lock_t * -get_next_recovery_lock (xlator_t *this, clnt_local_t *local) -{ - client_posix_lock_t *lock = NULL; - - pthread_mutex_lock (&local->mutex); - { - if (list_empty (&local->lock_list)) { - gf_log (this->name, GF_LOG_DEBUG, - "lock-list empty"); - goto unlock; - } - - lock = list_entry ((local->lock_list).next, typeof (*lock), list); - list_del_init (&lock->list); - } -unlock: - pthread_mutex_unlock (&local->mutex); - - return lock; - -} - -int32_t -client_reserve_lock_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock, dict_t *xdata) -{ - - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - - uint64_t fd_count = 0; - - local = frame->local; - conf = this->private; - - /* Got the reserve lock. Check if lock is grantable and proceed - with the real lk call */ - - if (op_ret >= 0) { - /* Lock is grantable if flock reflects a successful getlk() call*/ - if (lock->l_type == F_UNLCK && lock->l_pid) { - gf_log (this->name, GF_LOG_INFO, - "Got the reservelk, but the lock is not grantable. "); - client_remove_reserve_lock (this, frame, local->client_lock); - goto out; - } - - gf_log (this->name, GF_LOG_DEBUG, "reserve lock succeeded"); - client_send_recovery_lock (frame, this, local->client_lock); - goto out; - } - - /* Somebody else has a reserve lk. Lock conflict detected. - Mark fd as bad */ - - gf_log (this->name, GF_LOG_WARNING, - "reservelk OP failed. aborting lock recovery"); - - client_mark_bad_fd (local->client_lock->fd, - local->fdctx); - destroy_client_lock (local->client_lock); - frame->local = NULL; - client_local_wipe (local); - STACK_DESTROY (frame->root); - - fd_count = decrement_reopen_fd_count (this, conf); - gf_log (this->name, GF_LOG_DEBUG, - "need to attempt lock recovery on %"PRIu64" open fds", - fd_count); - -out: - return 0; -} - -int32_t -client_recovery_lock_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock, dict_t *xdata) -{ - clnt_local_t *local = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - client_posix_lock_t *next_lock = NULL; - - struct gf_flock reserve_flock; - uint64_t fd_count = 0; - - local = frame->local; - conf = this->private; - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, - "lock recovery failed: %s", - strerror(op_errno)); - - client_mark_bad_fd (local->client_lock->fd, - local->fdctx); - goto cleanup; - - /* Lock recovered. Continue with reserve lock for next lock */ - } else { - gf_log (this->name, GF_LOG_DEBUG, - "lock recovered successfully - continuing with next lock."); - - next_lock = get_next_recovery_lock (this, local); - if (!next_lock) { - gf_log (this->name, GF_LOG_DEBUG, - "all locks recovered on fd"); - goto cleanup; - } - - construct_reserve_lock (next_lock, frame, &reserve_flock); - local->fdctx = fdctx; - local->client_lock = next_lock; - - STACK_WIND (frame, client_reserve_lock_cbk, - this, this->fops->lk, - next_lock->fd, F_RESLK_LCK, &reserve_flock, NULL); - goto out; - - } - -cleanup: - - frame->local = NULL; - client_local_wipe (local); - - if (local->client_lock) - destroy_client_lock (local->client_lock); - - STACK_DESTROY (frame->root); - - fd_count = decrement_reopen_fd_count (this, conf); - - gf_log (this->name, GF_LOG_DEBUG, - "need to attempt lock recovery on %"PRIu64" open fds", - fd_count); - -out: - return 0; -} - -static int -client_send_recovery_lock (call_frame_t *frame, xlator_t *this, - client_posix_lock_t *lock) -{ - frame->root->lk_owner = lock->owner; - - /* Send all locks as F_SETLK to prevent the frame - from blocking if there is a conflict */ - - STACK_WIND (frame, client_recovery_lock_cbk, - this, this->fops->lk, - lock->fd, F_SETLK, - &(lock->user_flock), NULL); - - return 0; -} - -static int -client_lockrec_init (clnt_fd_ctx_t *fdctx, clnt_local_t *local) -{ - - INIT_LIST_HEAD (&local->lock_list); - pthread_mutex_init (&local->mutex, NULL); - - pthread_mutex_lock (&fdctx->mutex); - { - list_splice_init (&fdctx->lock_list, &local->lock_list); - } - pthread_mutex_unlock (&fdctx->mutex); - - return 0; -} - - -int -client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx) -{ - call_frame_t *frame = NULL; - clnt_local_t *local = NULL; - client_posix_lock_t *lock = NULL; - - struct gf_flock reserve_flock; - int ret = 0; - - local = mem_get0 (this->local_pool); - if (!local) { - ret = -ENOMEM; - goto out; - } - - client_lockrec_init (fdctx, local); - - lock = get_next_recovery_lock (this, local); - if (!lock) { - gf_log (this->name, GF_LOG_DEBUG, - "no locks found on fd"); - ret = -1; - goto out; - } - - frame = create_frame (this, this->ctx->pool); - if (!frame) { - gf_log (this->name, GF_LOG_ERROR, - "creating of frame failed, lock recovery failed"); - ret = -1; - goto out; - } - - construct_reserve_lock (lock, frame, &reserve_flock); - - frame->local = local; - local->fdctx = fdctx; - local->client_lock = lock; - - STACK_WIND (frame, client_reserve_lock_cbk, - this, this->fops->lk, - lock->fd, F_RESLK_LCK, &reserve_flock, NULL); - -out: - return ret; - - -} - int32_t client_dump_locks (char *name, inode_t *inode, dict_t *dict) -- cgit