summaryrefslogtreecommitdiffstats
path: root/xlators/features/locks/src/entrylk.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/locks/src/entrylk.c')
-rw-r--r--xlators/features/locks/src/entrylk.c237
1 files changed, 133 insertions, 104 deletions
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c
index f22ae0d74..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,19 +322,24 @@ __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;
}
+ gettimeofday (&lock->blkd_time, NULL);
list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks);
gf_log (this->name, GF_LOG_TRACE,
@@ -361,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;
@@ -370,6 +361,7 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
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,
@@ -384,6 +376,7 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
switch (type) {
case ENTRYLK_WRLCK:
+ gettimeofday (&lock->granted_time, NULL);
list_add_tail (&lock->domain_list, &dom->entrylk_list);
break;
@@ -439,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,
@@ -464,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);
}
}
@@ -492,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);
@@ -503,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;
@@ -534,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);
@@ -549,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);
}
@@ -571,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);
}
@@ -582,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);
}
@@ -596,21 +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;
- pid_t pid = -1;
+ 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) {
@@ -626,20 +654,17 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type);
- pid = frame->root->pid;
- 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;
@@ -650,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);
@@ -675,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);
@@ -712,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);
@@ -731,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;
}
@@ -749,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;
@@ -767,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++;
}