diff options
Diffstat (limited to 'xlators/features/locks/src/entrylk.c')
| -rw-r--r-- | xlators/features/locks/src/entrylk.c | 752 |
1 files changed, 414 insertions, 338 deletions
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index e96097cc1..0785dc547 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2006-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 _CONFIG_H #define _CONFIG_H #include "config.h" @@ -35,27 +25,30 @@ static pl_entry_lock_t * new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type, - transport_t *trans, pid_t client_pid, const char *volume) -{ - pl_entry_lock_t *newlock = NULL; + client_t *client, pid_t client_pid, gf_lkowner_t *owner, + const char *volume) - newlock = CALLOC (1, sizeof (pl_entry_lock_t)); - if (!newlock) { - goto out; - } +{ + pl_entry_lock_t *newlock = NULL; - newlock->basename = basename ? strdup (basename) : NULL; - newlock->type = type; - newlock->trans = trans; - newlock->volume = volume; - newlock->client_pid = client_pid; + newlock = GF_CALLOC (1, sizeof (pl_entry_lock_t), + gf_locks_mt_pl_entry_lock_t); + if (!newlock) { + goto out; + } + newlock->basename = basename ? gf_strdup (basename) : NULL; + newlock->type = type; + newlock->trans = client; + newlock->volume = volume; + newlock->client_pid = client_pid; + newlock->owner = *owner; - INIT_LIST_HEAD (&newlock->domain_list); - INIT_LIST_HEAD (&newlock->blocked_locks); + INIT_LIST_HEAD (&newlock->domain_list); + INIT_LIST_HEAD (&newlock->blocked_locks); out: - return newlock; + return newlock; } @@ -75,15 +68,16 @@ out: static int names_conflict (const char *n1, const char *n2) { - return all_names (n1) || all_names (n2) || !strcmp (n1, n2); + return all_names (n1) || all_names (n2) || !strcmp (n1, n2); } -static int +static inline int __same_entrylk_owner (pl_entry_lock_t *l1, pl_entry_lock_t *l2) { - return ((l1->client_pid == l2->client_pid) && - (l1->trans == l2->trans)); + + return (is_same_lkowner (&l1->owner, &l2->owner) && + (l1->trans == l2->trans)); } @@ -96,33 +90,33 @@ __same_entrylk_owner (pl_entry_lock_t *l1, pl_entry_lock_t *l2) static pl_entry_lock_t * __lock_grantable (pl_dom_list_t *dom, const char *basename, entrylk_type type) { - pl_entry_lock_t *lock = NULL; + pl_entry_lock_t *lock = NULL; - if (list_empty (&dom->entrylk_list)) - return NULL; + if (list_empty (&dom->entrylk_list)) + return NULL; - list_for_each_entry (lock, &dom->entrylk_list, domain_list) { - if (names_conflict (lock->basename, basename)) - return lock; - } + list_for_each_entry (lock, &dom->entrylk_list, domain_list) { + if (names_conflict (lock->basename, basename)) + return lock; + } - return NULL; + return NULL; } static pl_entry_lock_t * __blocked_lock_conflict (pl_dom_list_t *dom, const char *basename, entrylk_type type) { - pl_entry_lock_t *lock = NULL; + pl_entry_lock_t *lock = NULL; - if (list_empty (&dom->blocked_entrylks)) - return NULL; + if (list_empty (&dom->blocked_entrylks)) + return NULL; - list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) { - if (names_conflict (lock->basename, basename)) - return lock; - } + list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) { + if (names_conflict (lock->basename, basename)) + return lock; + } - return NULL; + return NULL; } static int @@ -130,23 +124,23 @@ __owner_has_lock (pl_dom_list_t *dom, pl_entry_lock_t *newlock) { pl_entry_lock_t *lock = NULL; - list_for_each_entry (lock, &dom->entrylk_list, domain_list) { - if (__same_entrylk_owner (lock, newlock)) - return 1; - } + list_for_each_entry (lock, &dom->entrylk_list, domain_list) { + if (__same_entrylk_owner (lock, newlock)) + return 1; + } - list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) { - if (__same_entrylk_owner (lock, newlock)) - return 1; - } + list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) { + if (__same_entrylk_owner (lock, newlock)) + return 1; + } - return 0; + return 0; } static int names_equal (const char *n1, const char *n2) { - return (n1 == NULL && n2 == NULL) || (n1 && n2 && !strcmp (n1, n2)); + return (n1 == NULL && n2 == NULL) || (n1 && n2 && !strcmp (n1, n2)); } void @@ -186,7 +180,7 @@ pl_print_entrylk (char *str, int size, entrylk_cmd cmd, entrylk_type type, break; } - snprintf (str, size, "cmd=%s, type=%s, basename=%s, domain: %s", + snprintf (str, size, "lock=ENTRYLK, cmd=%s, type=%s, basename=%s, domain: %s", cmd_str, type_str, basename, domain); } @@ -210,7 +204,7 @@ entrylk_trace_in (xlator_t *this, call_frame_t *frame, const char *domain, pl_print_lockee (pl_lockee, 256, fd, loc); pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, domain); - gf_log (this->name, GF_LOG_NORMAL, + gf_log (this->name, GF_LOG_INFO, "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}", pl_locker, pl_lockee, pl_entrylk); } @@ -237,7 +231,7 @@ entrylk_trace_out (xlator_t *this, call_frame_t *frame, const char *domain, pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, domain); pl_print_verdict (verdict, 32, op_ret, op_errno); - gf_log (this->name, GF_LOG_NORMAL, + gf_log (this->name, GF_LOG_INFO, "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}", verdict, pl_locker, pl_lockee, pl_entrylk); } @@ -263,7 +257,7 @@ entrylk_trace_block (xlator_t *this, call_frame_t *frame, const char *volume, pl_print_lockee (pl_lockee, 256, fd, loc); pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, volume); - gf_log (this->name, GF_LOG_NORMAL, + gf_log (this->name, GF_LOG_INFO, "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}", pl_locker, pl_lockee, pl_entrylk); } @@ -281,21 +275,21 @@ entrylk_trace_block (xlator_t *this, call_frame_t *frame, const char *volume, static pl_entry_lock_t * __find_most_matching_lock (pl_dom_list_t *dom, const char *basename) { - pl_entry_lock_t *lock; - pl_entry_lock_t *all = NULL; - pl_entry_lock_t *exact = NULL; - - if (list_empty (&dom->entrylk_list)) - return NULL; - - list_for_each_entry (lock, &dom->entrylk_list, domain_list) { - if (all_names (lock->basename)) - all = lock; - else if (names_equal (lock->basename, basename)) - exact = lock; - } + pl_entry_lock_t *lock; + pl_entry_lock_t *all = NULL; + pl_entry_lock_t *exact = NULL; + + if (list_empty (&dom->entrylk_list)) + return NULL; + + list_for_each_entry (lock, &dom->entrylk_list, domain_list) { + if (all_names (lock->basename)) + all = lock; + else if (names_equal (lock->basename, basename)) + exact = lock; + } - return (exact ? exact : all); + return (exact ? exact : all); } /** @@ -311,64 +305,80 @@ __find_most_matching_lock (pl_dom_list_t *dom, const char *basename) int __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type, - call_frame_t *frame, pl_dom_list_t *dom, xlator_t *this, int nonblock) + call_frame_t *frame, pl_dom_list_t *dom, xlator_t *this, + int nonblock, char *conn_id) { - pl_entry_lock_t *lock = NULL; - pl_entry_lock_t *conf = NULL; - transport_t *trans = NULL; - pid_t client_pid = 0; - - int ret = -EINVAL; + pl_entry_lock_t *lock = NULL; + pl_entry_lock_t *conf = NULL; + int ret = -EINVAL; + + lock = new_entrylk_lock (pinode, basename, type, + frame->root->client, frame->root->pid, + &frame->root->lk_owner, dom->domain); + if (!lock) { + ret = -ENOMEM; + goto out; + } - trans = frame->root->trans; - client_pid = frame->root->pid; + lock->frame = frame; + lock->this = this; + lock->trans = frame->root->client; - lock = new_entrylk_lock (pinode, basename, type, trans, client_pid, dom->domain); - if (!lock) { - ret = -ENOMEM; - goto out; - } + if (conn_id) { + lock->connection_id = gf_strdup (conn_id); + } - conf = __lock_grantable (dom, basename, type); - if (conf) { - ret = -EAGAIN; - if (nonblock) - goto out; + conf = __lock_grantable (dom, basename, type); + if (conf) { + ret = -EAGAIN; + if (nonblock){ + GF_FREE (lock->connection_id); + GF_FREE ((char *)lock->basename); + GF_FREE (lock); + goto out; - lock->frame = frame; - lock->this = this; + } - list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks); + gettimeofday (&lock->blkd_time, NULL); + list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks); - gf_log (this->name, GF_LOG_TRACE, - "Blocking lock: {pinode=%p, basename=%s}", - pinode, basename); + gf_log (this->name, GF_LOG_TRACE, + "Blocking lock: {pinode=%p, basename=%s}", + pinode, basename); - goto out; - } + goto out; + } if ( __blocked_lock_conflict (dom, basename, type) && !(__owner_has_lock (dom, lock))) { ret = -EAGAIN; - if (nonblock) + if (nonblock) { + GF_FREE (lock->connection_id); + GF_FREE ((char *) lock->basename); + GF_FREE (lock); goto out; + + } lock->frame = frame; lock->this = this; + gettimeofday (&lock->blkd_time, NULL); list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks); gf_log (this->name, GF_LOG_TRACE, "Lock is grantable, but blocking to prevent starvation"); - gf_log (this->name, GF_LOG_TRACE, - "Blocking lock: {pinode=%p, basename=%s}", - pinode, basename); + gf_log (this->name, GF_LOG_TRACE, + "Blocking lock: {pinode=%p, basename=%s}", + pinode, basename); - goto out; + ret = -EAGAIN; + goto out; } switch (type) { - case ENTRYLK_WRLCK: - list_add (&lock->domain_list, &dom->entrylk_list); - break; + case ENTRYLK_WRLCK: + gettimeofday (&lock->granted_time, NULL); + list_add_tail (&lock->domain_list, &dom->entrylk_list); + break; default: @@ -376,11 +386,11 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type, "Invalid type for entrylk specified: %d", type); ret = -EINVAL; goto out; - } + } - ret = 0; + ret = 0; out: - return ret; + return ret; } /** @@ -393,286 +403,366 @@ out: pl_entry_lock_t * __unlock_name (pl_dom_list_t *dom, const char *basename, entrylk_type type) { - pl_entry_lock_t *lock = NULL; - pl_entry_lock_t *ret_lock = NULL; - - lock = __find_most_matching_lock (dom, basename); - - if (!lock) { - gf_log ("locks", GF_LOG_DEBUG, - "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found", - basename); - goto out; - } - - if (names_equal (lock->basename, basename) - && lock->type == type) { - - if (type == ENTRYLK_WRLCK) { - list_del (&lock->domain_list); - ret_lock = lock; - } - } else { - gf_log ("locks", GF_LOG_DEBUG, - "Unlock for a non-existing lock!"); - goto out; - } + pl_entry_lock_t *lock = NULL; + pl_entry_lock_t *ret_lock = NULL; + + lock = __find_most_matching_lock (dom, basename); + + if (!lock) { + gf_log ("locks", GF_LOG_DEBUG, + "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found", + basename); + goto out; + } + + if (names_equal (lock->basename, basename) + && lock->type == type) { + + if (type == ENTRYLK_WRLCK) { + list_del_init (&lock->domain_list); + ret_lock = lock; + } + } else { + gf_log ("locks", GF_LOG_DEBUG, + "Unlock for a non-existing lock!"); + goto out; + } out: - return ret_lock; + return ret_lock; } +uint32_t +check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename) +{ + uint32_t entrylk = 0; + pl_inode_t *pinode = 0; + pl_dom_list_t *dom = NULL; + pl_entry_lock_t *conf = NULL; + + pinode = pl_inode_get (this, parent); + if (!pinode) + goto out; + pthread_mutex_lock (&pinode->mutex); + { + list_for_each_entry (dom, &pinode->dom_list, inode_list) { + conf = __lock_grantable (dom, basename, ENTRYLK_WRLCK); + if (conf && conf->basename) { + entrylk = 1; + break; + } + } + } + pthread_mutex_unlock (&pinode->mutex); + +out: + return entrylk; +} void __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, - pl_dom_list_t *dom, struct list_head *granted) + pl_dom_list_t *dom, struct list_head *granted) { - int bl_ret = 0; - pl_entry_lock_t *bl = NULL; - pl_entry_lock_t *tmp = NULL; + int bl_ret = 0; + pl_entry_lock_t *bl = NULL; + pl_entry_lock_t *tmp = NULL; struct list_head blocked_list; INIT_LIST_HEAD (&blocked_list); list_splice_init (&dom->blocked_entrylks, &blocked_list); - - list_for_each_entry_safe (bl, tmp, &blocked_list, - blocked_locks) { - list_del_init (&bl->blocked_locks); + list_for_each_entry_safe (bl, tmp, &blocked_list, + blocked_locks) { + + list_del_init (&bl->blocked_locks); - gf_log ("locks", GF_LOG_TRACE, - "Trying to unblock: {pinode=%p, basename=%s}", - pl_inode, bl->basename); + gf_log ("locks", GF_LOG_TRACE, + "Trying to unblock: {pinode=%p, basename=%s}", + pl_inode, bl->basename); - bl_ret = __lock_name (pl_inode, bl->basename, bl->type, - bl->frame, dom, bl->this, 0); + bl_ret = __lock_name (pl_inode, bl->basename, bl->type, + bl->frame, dom, bl->this, 0, + bl->connection_id); - if (bl_ret == 0) { - list_add (&bl->blocked_locks, granted); - } else { - if (bl->basename) - FREE (bl->basename); - FREE (bl); - } - } - return; + if (bl_ret == 0) { + list_add (&bl->blocked_locks, granted); + } else { + gf_log (this->name, GF_LOG_DEBUG, + "should never happen"); + GF_FREE (bl->connection_id); + GF_FREE ((char *)bl->basename); + GF_FREE (bl); + } + } + return; } /* Grants locks if possible which are blocked on a lock */ void grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, - pl_entry_lock_t *unlocked, pl_dom_list_t *dom) + pl_entry_lock_t *unlocked, pl_dom_list_t *dom) { - struct list_head granted_list; - pl_entry_lock_t *tmp = NULL; - pl_entry_lock_t *lock = NULL; + struct list_head granted_list; + pl_entry_lock_t *tmp = NULL; + pl_entry_lock_t *lock = NULL; - INIT_LIST_HEAD (&granted_list); + INIT_LIST_HEAD (&granted_list); - pthread_mutex_lock (&pl_inode->mutex); - { - __grant_blocked_entry_locks (this, pl_inode, dom, &granted_list); - } - pthread_mutex_unlock (&pl_inode->mutex); + pthread_mutex_lock (&pl_inode->mutex); + { + __grant_blocked_entry_locks (this, pl_inode, dom, + &granted_list); + } + pthread_mutex_unlock (&pl_inode->mutex); - list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks) { - list_del_init (&lock->blocked_locks); + list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks) { + list_del_init (&lock->blocked_locks); entrylk_trace_out (this, lock->frame, NULL, NULL, NULL, lock->basename, ENTRYLK_LOCK, lock->type, 0, 0); - STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0); + STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL); - FREE (lock->basename); - FREE (lock); - } + GF_FREE (lock->connection_id); + GF_FREE ((char *)lock->basename); + GF_FREE (lock); + } - FREE (unlocked->basename); - FREE (unlocked); + GF_FREE ((char *)unlocked->basename); + GF_FREE (unlocked->connection_id); + GF_FREE (unlocked); - return; + return; } /** - * release_entry_locks_for_transport: release all entry locks from this - * transport for this loc_t + * release_entry_locks_for_client: release all entry locks from this + * client for this loc_t */ static int -release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, - pl_dom_list_t *dom, transport_t *trans) +release_entry_locks_for_client (xlator_t *this, pl_inode_t *pinode, + pl_dom_list_t *dom, client_t *client) { - pl_entry_lock_t *lock = NULL; - pl_entry_lock_t *tmp = NULL; - struct list_head granted; + pl_entry_lock_t *lock = NULL; + pl_entry_lock_t *tmp = NULL; + struct list_head granted; + struct list_head released; - INIT_LIST_HEAD (&granted); + INIT_LIST_HEAD (&granted); + INIT_LIST_HEAD (&released); - pthread_mutex_lock (&pinode->mutex); - { - if (list_empty (&dom->entrylk_list)) { - goto unlock; - } + pthread_mutex_lock (&pinode->mutex); + { + list_for_each_entry_safe (lock, tmp, &dom->blocked_entrylks, + blocked_locks) { + if (lock->trans != client) + continue; + + list_del_init (&lock->blocked_locks); - list_for_each_entry_safe (lock, tmp, &dom->entrylk_list, - domain_list) { - if (lock->trans != trans) - continue; + gf_log (this->name, GF_LOG_TRACE, + "releasing lock on held by " + "{client=%p}", client); - list_del_init (&lock->domain_list); + list_add (&lock->blocked_locks, &released); + + } - gf_log (this->name, GF_LOG_TRACE, + list_for_each_entry_safe (lock, tmp, &dom->entrylk_list, + domain_list) { + if (lock->trans != client) + continue; + + list_del_init (&lock->domain_list); + + gf_log (this->name, GF_LOG_TRACE, "releasing lock on held by " - "{transport=%p}",trans);; + "{client=%p}", client); - FREE (lock->basename); - FREE (lock); - } + GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); + GF_FREE (lock); + } - __grant_blocked_entry_locks (this, pinode, dom, &granted); + __grant_blocked_entry_locks (this, pinode, dom, &granted); - } -unlock: - pthread_mutex_unlock (&pinode->mutex); + } - list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) { - list_del_init (&lock->blocked_locks); + pthread_mutex_unlock (&pinode->mutex); - STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0); + list_for_each_entry_safe (lock, tmp, &released, blocked_locks) { + list_del_init (&lock->blocked_locks); - if (lock->basename) - FREE (lock->basename); - FREE (lock); - } + STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN, NULL); - return 0; + GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); + GF_FREE (lock); + + } + + list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) { + list_del_init (&lock->blocked_locks); + + STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL); + + GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); + GF_FREE (lock); + } + + return 0; } /* Common entrylk code called by pl_entrylk and pl_fentrylk */ int pl_common_entrylk (call_frame_t *frame, xlator_t *this, const char *volume, inode_t *inode, const char *basename, - entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd) + entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd, + dict_t *xdata) + { - int32_t op_ret = -1; - int32_t op_errno = 0; - - transport_t * transport = NULL; - pid_t pid = -1; - - pl_inode_t * pinode = NULL; - int ret = -1; - pl_entry_lock_t *unlocked = NULL; - char unwind = 1; - - pl_dom_list_t *dom = NULL; - - pinode = pl_inode_get (this, inode); - if (!pinode) { - gf_log (this->name, GF_LOG_ERROR, - "Out of memory."); - op_errno = ENOMEM; - goto out; - } - - dom = get_domain (pinode, volume); - if (!dom){ - gf_log (this->name, GF_LOG_ERROR, - "Out of memory"); - op_errno = ENOMEM; - goto out; - } + int32_t op_ret = -1; + int32_t op_errno = 0; + int ret = -1; + char unwind = 1; + GF_UNUSED int dict_ret = -1; + pl_inode_t *pinode = NULL; + pl_entry_lock_t *unlocked = NULL; + pl_dom_list_t *dom = NULL; + char *conn_id = NULL; + pl_ctx_t *ctx = NULL; + + if (xdata) + dict_ret = dict_get_str (xdata, "connection-id", &conn_id); + + pinode = pl_inode_get (this, inode); + if (!pinode) { + op_errno = ENOMEM; + goto out; + } - entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type); + dom = get_domain (pinode, volume); + if (!dom){ + op_errno = ENOMEM; + goto out; + } - pid = frame->root->pid; - transport = frame->root->trans; + entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type); - if (pid == 0) { - /* + if (frame->root->lk_owner.len == 0) { + /* this is a special case that means release - all locks from this transport - */ - - gf_log (this->name, GF_LOG_TRACE, - "Releasing locks for transport %p", transport); - - release_entry_locks_for_transport (this, pinode, dom, transport); - op_ret = 0; - - goto out; - } - - switch (cmd) { - case ENTRYLK_LOCK: - pthread_mutex_lock (&pinode->mutex); - { - ret = __lock_name (pinode, basename, type, - frame, dom, this, 0); - } - pthread_mutex_unlock (&pinode->mutex); - - if (ret < 0) { - if (ret == -EAGAIN) - unwind = 0; - op_errno = -ret; - goto out; - } - - break; - - case ENTRYLK_LOCK_NB: - pthread_mutex_lock (&pinode->mutex); - { - ret = __lock_name (pinode, basename, type, - frame, dom, this, 1); - } - pthread_mutex_unlock (&pinode->mutex); - - if (ret < 0) { - op_errno = -ret; - goto out; - } - - break; - - case ENTRYLK_UNLOCK: - pthread_mutex_lock (&pinode->mutex); - { + all locks from this client + */ + + gf_log (this->name, GF_LOG_TRACE, + "Releasing locks for client %p", frame->root->client); + + release_entry_locks_for_client (this, pinode, dom, + frame->root->client); + op_ret = 0; + + goto out; + } + + switch (cmd) { + case ENTRYLK_LOCK: + pthread_mutex_lock (&pinode->mutex); + { + ret = __lock_name (pinode, basename, type, + frame, dom, this, 0, conn_id); + } + pthread_mutex_unlock (&pinode->mutex); + + op_errno = -ret; + if (ret < 0) { + if (ret == -EAGAIN) + unwind = 0; + else + unwind = 1; + goto out; + } else { + op_ret = 0; + op_errno = 0; + unwind = 1; + goto out; + } + + break; + + case ENTRYLK_LOCK_NB: + unwind = 1; + pthread_mutex_lock (&pinode->mutex); + { + ret = __lock_name (pinode, basename, type, + frame, dom, this, 1, conn_id); + } + pthread_mutex_unlock (&pinode->mutex); + + if (ret < 0) { + op_errno = -ret; + goto out; + } + + break; + + case ENTRYLK_UNLOCK: + pthread_mutex_lock (&pinode->mutex); + { unlocked = __unlock_name (dom, basename, type); - } - pthread_mutex_unlock (&pinode->mutex); + } + pthread_mutex_unlock (&pinode->mutex); - if (unlocked) - grant_blocked_entry_locks (this, pinode, unlocked, dom); + if (unlocked) + grant_blocked_entry_locks (this, pinode, unlocked, dom); - break; + break; - default: - gf_log (this->name, GF_LOG_ERROR, - "Unexpected case in entrylk (cmd=%d). Please file" + default: + gf_log (this->name, GF_LOG_ERROR, + "Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com", cmd); - goto out; - } + goto out; + } - op_ret = 0; + op_ret = 0; out: pl_update_refkeeper (this, inode); - if (unwind) { + if (unwind) { entrylk_trace_out (this, frame, volume, fd, loc, basename, cmd, type, op_ret, op_errno); - STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno); - } else { + ctx = pl_ctx_get (frame->root->client, this); + + if (ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "pl_ctx_get() failed"); + goto unwind; + } + + if (cmd == ENTRYLK_UNLOCK) + pl_del_locker (ctx->ltable, volume, loc, fd, + &frame->root->lk_owner, + GF_FOP_ENTRYLK); + else + pl_add_locker (ctx->ltable, volume, loc, fd, + frame->root->pid, + &frame->root->lk_owner, + GF_FOP_ENTRYLK); + +unwind: + STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, NULL); + } else { entrylk_trace_block (this, frame, volume, fd, loc, basename, cmd, type); } - return 0; + return 0; } /** @@ -683,11 +773,11 @@ out: int pl_entrylk (call_frame_t *frame, xlator_t *this, - const char *volume, loc_t *loc, const char *basename, - entrylk_cmd cmd, entrylk_type type) + const char *volume, loc_t *loc, const char *basename, + entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { - - pl_common_entrylk (frame, this, volume, loc->inode, basename, cmd, type, loc, NULL); + pl_common_entrylk (frame, this, volume, loc->inode, basename, cmd, + type, loc, NULL, xdata); return 0; } @@ -702,16 +792,16 @@ pl_entrylk (call_frame_t *frame, xlator_t *this, int pl_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, - entrylk_cmd cmd, entrylk_type type) + entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { - - pl_common_entrylk (frame, this, volume, fd->inode, basename, cmd, type, NULL, fd); + pl_common_entrylk (frame, this, volume, fd->inode, basename, cmd, + type, NULL, fd, xdata); return 0; } -static int32_t +int32_t __get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode) { int32_t count = 0; @@ -720,24 +810,10 @@ __get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode) 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++; } |
