From b3b4fc4afb7d206d0a481f3234bf83c768f02aa2 Mon Sep 17 00:00:00 2001 From: Pavan Sondur Date: Wed, 28 Oct 2009 12:27:54 +0000 Subject: Implement lookup in locks to return lock count in a dict value. Signed-off-by: Anand V. Avati BUG: 306 (Enhance locks to aid debugging) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=306 --- xlators/features/locks/src/common.h | 6 ++ xlators/features/locks/src/entrylk.c | 61 ++++++++++++ xlators/features/locks/src/inodelk.c | 67 +++++++++++++ xlators/features/locks/src/locks.h | 5 + xlators/features/locks/src/posix.c | 181 +++++++++++++++++++++++++++++++++++ 5 files changed, 320 insertions(+) (limited to 'xlators/features/locks') diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index 36a74168649..4e9b30be211 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -67,4 +67,10 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, void pl_update_refkeeper (xlator_t *this, inode_t *inode); +int32_t +get_inodelk_count (xlator_t *this, inode_t *inode); + +int32_t +get_entrylk_count (xlator_t *this, inode_t *inode); + #endif /* __COMMON_H__ */ diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index 4e038809cac..fdfa2ba86ad 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -576,3 +576,64 @@ pl_fentrylk (call_frame_t *frame, xlator_t *this, return 0; } + + +static int32_t +__get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode) +{ + int32_t count = 0; + pl_entry_lock_t *lock = NULL; + pl_dom_list_t *dom = NULL; + + list_for_each_entry (dom, &pl_inode->dom_list, inode_list) { + list_for_each_entry (lock, &dom->entrylk_list, domain_list) { + + gf_log (this->name, GF_LOG_DEBUG, + " XATTR DEBUG" + " domain: %s %s on %s state = Active", + dom->domain, + lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" : + "ENTRYLK_WRLCK", lock->basename); + count++; + } + + list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) { + + gf_log (this->name, GF_LOG_DEBUG, + " XATTR DEBUG" + " domain: %s %s on %s state = Blocked", + dom->domain, + lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" : + "ENTRYLK_WRLCK", lock->basename); + count++; + } + + } + + return count; +} + +int32_t +get_entrylk_count (xlator_t *this, inode_t *inode) +{ + pl_inode_t *pl_inode = NULL; + uint64_t tmp_pl_inode = 0; + int ret = 0; + int32_t count = 0; + + ret = inode_ctx_get (inode, this, &tmp_pl_inode); + if (ret != 0) { + goto out; + } + + pl_inode = (pl_inode_t *)(long) tmp_pl_inode; + + pthread_mutex_lock (&pl_inode->mutex); + { + count = __get_entrylk_count (this, pl_inode); + } + pthread_mutex_unlock (&pl_inode->mutex); + +out: + return count; +} diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c index 1ec5b00417f..78e4154bcc5 100644 --- a/xlators/features/locks/src/inodelk.c +++ b/xlators/features/locks/src/inodelk.c @@ -552,3 +552,70 @@ pl_finodelk (call_frame_t *frame, xlator_t *this, return 0; } + + +static int32_t +__get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode) +{ + int32_t count = 0; + pl_inode_lock_t *lock = NULL; + pl_dom_list_t *dom = NULL; + + list_for_each_entry (dom, &pl_inode->dom_list, inode_list) { + list_for_each_entry (lock, &dom->inodelk_list, list) { + + gf_log (this->name, GF_LOG_DEBUG, + " XATTR DEBUG" + " domain: %s %s (pid=%d) %"PRId64" - %"PRId64" state = Active", + dom->domain, + lock->fl_type == F_UNLCK ? "Unlock" : "Lock", + lock->client_pid, + lock->user_flock.l_start, + lock->user_flock.l_len); + + count++; + } + + list_for_each_entry (lock, &dom->blocked_inodelks, blocked_locks) { + + gf_log (this->name, GF_LOG_DEBUG, + " XATTR DEBUG" + " domain: %s %s (pid=%d) %"PRId64" - %"PRId64" state = Blocked", + dom->domain, + lock->fl_type == F_UNLCK ? "Unlock" : "Lock", + lock->client_pid, + lock->user_flock.l_start, + lock->user_flock.l_len); + + count++; + } + + } + + return count; +} + +int32_t +get_inodelk_count (xlator_t *this, inode_t *inode) +{ + pl_inode_t *pl_inode = NULL; + uint64_t tmp_pl_inode = 0; + int ret = 0; + int32_t count = 0; + + ret = inode_ctx_get (inode, this, &tmp_pl_inode); + if (ret != 0) { + goto out; + } + + pl_inode = (pl_inode_t *)(long) tmp_pl_inode; + + pthread_mutex_lock (&pl_inode->mutex); + { + count = __get_inodelk_count (this, pl_inode); + } + pthread_mutex_unlock (&pl_inode->mutex); + +out: + return count; +} diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index cf6d595147a..0f3ab29b6e9 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -140,5 +140,10 @@ typedef struct { gf_boolean_t mandatory; /* if mandatory locking is enabled */ } posix_locks_private_t; +typedef struct { + gf_boolean_t entrylk_count_req; + gf_boolean_t inodelk_count_req; + gf_boolean_t posixlk_count_req; +} pl_local_t; #endif /* __POSIX_LOCKS_H__ */ diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index c7ae1baedbd..3b011317c01 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -781,6 +781,186 @@ pl_forget (xlator_t *this, return 0; } +static int32_t +__get_posixlk_count (xlator_t *this, pl_inode_t *pl_inode) +{ + posix_lock_t *lock = NULL; + int32_t count = 0; + + list_for_each_entry (lock, &pl_inode->ext_list, list) { + + gf_log (this->name, GF_LOG_DEBUG, + " XATTR DEBUG" + "%s (pid=%d) %"PRId64" - %"PRId64" state: %s", + lock->fl_type == F_UNLCK ? "Unlock" : "Lock", + lock->client_pid, + lock->user_flock.l_start, + lock->user_flock.l_len, + lock->blocked == 1 ? "Blocked" : "Active"); + + count++; + } + + return count; +} + +int32_t +get_posixlk_count (xlator_t *this, inode_t *inode) +{ + pl_inode_t *pl_inode = NULL; + uint64_t tmp_pl_inode = 0; + int ret = 0; + int32_t count = 0; + + ret = inode_ctx_get (inode, this, &tmp_pl_inode); + if (ret != 0) { + goto out; + } + + pl_inode = (pl_inode_t *)(long) tmp_pl_inode; + + pthread_mutex_lock (&pl_inode->mutex); + { + count =__get_posixlk_count (this, pl_inode); + } + pthread_mutex_unlock (&pl_inode->mutex); + +out: + return count; +} + +void pl_entrylk_xattr_fill (xlator_t *this, inode_t *inode, + dict_t *dict) +{ + int32_t count = 0; + int ret = -1; + + count = get_entrylk_count (this, inode); + ret = dict_set_int32 (dict, GLUSTERFS_ENTRYLK_COUNT, count); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + " dict_set failed on key %s", GLUSTERFS_ENTRYLK_COUNT); + } + +} + +void pl_inodelk_xattr_fill (xlator_t *this, inode_t *inode, + dict_t *dict) +{ + int32_t count = 0; + int ret = -1; + + count = get_inodelk_count (this, inode); + ret = dict_set_int32 (dict, GLUSTERFS_INODELK_COUNT, count); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + " dict_set failed on key %s", GLUSTERFS_INODELK_COUNT); + } + +} + +void pl_posixlk_xattr_fill (xlator_t *this, inode_t *inode, + dict_t *dict) +{ + int32_t count = 0; + int ret = -1; + + count = get_posixlk_count (this, inode); + ret = dict_set_int32 (dict, GLUSTERFS_POSIXLK_COUNT, count); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + " dict_set failed on key %s", GLUSTERFS_POSIXLK_COUNT); + } + +} + +int32_t +pl_lookup_cbk (call_frame_t *frame, + void *cookie, + xlator_t *this, + int32_t op_ret, + int32_t op_errno, + inode_t *inode, + struct stat *buf, + dict_t *dict, + struct stat *postparent) +{ + pl_local_t *local = NULL; + + if (!frame->local) { + goto out; + } + + local = frame->local; + + if (local->entrylk_count_req) + pl_entrylk_xattr_fill (this, inode, dict); + if (local->inodelk_count_req) + pl_inodelk_xattr_fill (this, inode, dict); + if (local->posixlk_count_req) + pl_posixlk_xattr_fill (this, inode, dict); + + + frame->local = NULL; + + if (local != NULL) + FREE (local); + +out: + STACK_UNWIND (frame, + op_ret, + op_errno, + inode, + buf, + dict, + postparent); + return 0; +} + +int32_t +pl_lookup (call_frame_t *frame, + xlator_t *this, + loc_t *loc, + dict_t *xattr_req) +{ + pl_local_t *local = NULL; + int ret = -1; + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (this, out); + VALIDATE_OR_GOTO (loc, out); + VALIDATE_OR_GOTO (xattr_req, out); + + local = CALLOC (1, sizeof (*local)); + if (!local) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + " Out of memory"); + goto out; + } + + if (dict_get (xattr_req, GLUSTERFS_ENTRYLK_COUNT)) + local->entrylk_count_req = 1; + if (dict_get (xattr_req, GLUSTERFS_INODELK_COUNT)) + local->inodelk_count_req = 1; + if (dict_get (xattr_req, GLUSTERFS_POSIXLK_COUNT)) + local->posixlk_count_req = 1; + + frame->local = local; + + STACK_WIND (frame, + pl_lookup_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, + loc, + xattr_req); + ret = 0; +out: + if (ret == -1) + STACK_UNWIND_STRICT (lookup, frame, -1, 0, NULL, NULL, NULL, NULL); + + return 0; +} int32_t pl_dump_inode_priv (xlator_t *this, inode_t *inode) @@ -912,6 +1092,7 @@ pl_fentrylk (call_frame_t *frame, xlator_t *this, entrylk_cmd cmd, entrylk_type type); struct xlator_fops fops = { + .lookup = pl_lookup, .create = pl_create, .truncate = pl_truncate, .ftruncate = pl_ftruncate, -- cgit