diff options
Diffstat (limited to 'xlators/features/locks/src/entrylk.c')
| -rw-r--r-- | xlators/features/locks/src/entrylk.c | 232 |
1 files changed, 130 insertions, 102 deletions
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index 886a30b0e..0785dc547 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2006-2011 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,7 +25,8 @@ static pl_entry_lock_t * new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type, - void *trans, pid_t client_pid, uint64_t owner, const char *volume) + client_t *client, pid_t client_pid, gf_lkowner_t *owner, + const char *volume) { pl_entry_lock_t *newlock = NULL; @@ -46,12 +37,12 @@ new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type, goto out; } - newlock->basename = basename ? gf_strdup (basename) : NULL; - newlock->type = type; - newlock->trans = trans; - newlock->volume = volume; - newlock->client_pid = client_pid; - newlock->owner = owner; + 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); @@ -81,11 +72,11 @@ names_conflict (const char *n1, const char *n2) } -static int +static inline int __same_entrylk_owner (pl_entry_lock_t *l1, pl_entry_lock_t *l2) { - return ((l1->owner == l2->owner) && + return (is_same_lkowner (&l1->owner, &l2->owner) && (l1->trans == l2->trans)); } @@ -314,21 +305,16 @@ __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; - void *trans = NULL; - pid_t client_pid = 0; - uint64_t owner = 0; - - int ret = -EINVAL; - - trans = frame->root->trans; - client_pid = frame->root->pid; - owner = frame->root->lk_owner; + int ret = -EINVAL; - lock = new_entrylk_lock (pinode, basename, type, trans, client_pid, owner, dom->domain); + 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; @@ -336,14 +322,18 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type, lock->frame = frame; lock->this = this; - lock->trans = trans; + lock->trans = frame->root->client; + + if (conn_id) { + lock->connection_id = gf_strdup (conn_id); + } conf = __lock_grantable (dom, basename, type); if (conf) { ret = -EAGAIN; if (nonblock){ - if (lock->basename) - GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); + GF_FREE ((char *)lock->basename); GF_FREE (lock); goto out; @@ -362,8 +352,8 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type, if ( __blocked_lock_conflict (dom, basename, type) && !(__owner_has_lock (dom, lock))) { ret = -EAGAIN; if (nonblock) { - if (lock->basename) - GF_FREE ((char *) lock->basename); + GF_FREE (lock->connection_id); + GF_FREE ((char *) lock->basename); GF_FREE (lock); goto out; @@ -442,6 +432,32 @@ out: 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, @@ -467,15 +483,16 @@ __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, pl_inode, bl->basename); bl_ret = __lock_name (pl_inode, bl->basename, bl->type, - bl->frame, dom, bl->this, 0); + bl->frame, dom, bl->this, 0, + bl->connection_id); if (bl_ret == 0) { list_add (&bl->blocked_locks, granted); } else { gf_log (this->name, GF_LOG_DEBUG, "should never happen"); - if (bl->basename) - GF_FREE ((char *)bl->basename); + GF_FREE (bl->connection_id); + GF_FREE ((char *)bl->basename); GF_FREE (bl); } } @@ -495,7 +512,8 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, pthread_mutex_lock (&pl_inode->mutex); { - __grant_blocked_entry_locks (this, pl_inode, dom, &granted_list); + __grant_blocked_entry_locks (this, pl_inode, dom, + &granted_list); } pthread_mutex_unlock (&pl_inode->mutex); @@ -506,24 +524,28 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, 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); + GF_FREE (lock->connection_id); + GF_FREE ((char *)lock->basename); + GF_FREE (lock); } GF_FREE ((char *)unlocked->basename); + GF_FREE (unlocked->connection_id); GF_FREE (unlocked); 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, void *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; @@ -537,14 +559,14 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, { list_for_each_entry_safe (lock, tmp, &dom->blocked_entrylks, blocked_locks) { - if (lock->trans != trans) + if (lock->trans != client) continue; list_del_init (&lock->blocked_locks); gf_log (this->name, GF_LOG_TRACE, "releasing lock on held by " - "{transport=%p}",trans); + "{client=%p}", client); list_add (&lock->blocked_locks, &released); @@ -552,16 +574,17 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, list_for_each_entry_safe (lock, tmp, &dom->entrylk_list, domain_list) { - if (lock->trans != trans) + 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); GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); GF_FREE (lock); } @@ -574,10 +597,10 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, list_for_each_entry_safe (lock, tmp, &released, blocked_locks) { list_del_init (&lock->blocked_locks); - STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN); + STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN, NULL); - if (lock->basename) - GF_FREE ((char *)lock->basename); + GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); GF_FREE (lock); } @@ -585,10 +608,10 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) { list_del_init (&lock->blocked_locks); - STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0); + STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL); - if (lock->basename) - GF_FREE ((char *)lock->basename); + GF_FREE ((char *)lock->basename); + GF_FREE (lock->connection_id); GF_FREE (lock); } @@ -599,20 +622,23 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, 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) -{ - uint64_t owner = 0; - int32_t op_ret = -1; - int32_t op_errno = 0; - - void * transport = NULL; + entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd, + dict_t *xdata) - pl_inode_t * pinode = NULL; +{ + int32_t op_ret = -1; + int32_t op_errno = 0; int ret = -1; - pl_entry_lock_t *unlocked = NULL; 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; - pl_dom_list_t *dom = NULL; + if (xdata) + dict_ret = dict_get_str (xdata, "connection-id", &conn_id); pinode = pl_inode_get (this, inode); if (!pinode) { @@ -628,19 +654,17 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this, entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type); - owner = frame->root->lk_owner; - transport = frame->root->trans; - - if (owner == 0) { + if (frame->root->lk_owner.len == 0) { /* this is a special case that means release - all locks from this transport + all locks from this client */ gf_log (this->name, GF_LOG_TRACE, - "Releasing locks for transport %p", transport); + "Releasing locks for client %p", frame->root->client); - release_entry_locks_for_transport (this, pinode, dom, transport); + release_entry_locks_for_client (this, pinode, dom, + frame->root->client); op_ret = 0; goto out; @@ -651,7 +675,7 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this, pthread_mutex_lock (&pinode->mutex); { ret = __lock_name (pinode, basename, type, - frame, dom, this, 0); + frame, dom, this, 0, conn_id); } pthread_mutex_unlock (&pinode->mutex); @@ -676,7 +700,7 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this, pthread_mutex_lock (&pinode->mutex); { ret = __lock_name (pinode, basename, type, - frame, dom, this, 1); + frame, dom, this, 1, conn_id); } pthread_mutex_unlock (&pinode->mutex); @@ -713,7 +737,25 @@ out: entrylk_trace_out (this, frame, volume, fd, loc, basename, cmd, type, op_ret, op_errno); - STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno); + 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); @@ -732,10 +774,10 @@ 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) + 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; } @@ -750,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; @@ -768,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++; } |
