summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2013-12-03 16:30:45 -0800
committerVijay Bellur <vbellur@redhat.com>2014-01-13 21:44:19 -0800
commitaa3b01533efcd85fc1e654ac14a03ab8e1d5bbab (patch)
treeee2640323d45c3822ffba89685e9da42d253e6cd
parentce86c132347f0a788ab50ffbd6795a2eb982074e (diff)
locks: various fixes
- implement ref/unref of entry locks (and fix bad pointer deref crashes) - code cleanup and deleted various data types - fix improper read/write lock conflict detection in entrylk - fix indefinite hang of blocked locks on disconnect - register locks in client_t synchronously, fix crashes in disconnect path Change-Id: Id273690c9111b8052139d1847060d1fb5a711924 BUG: 849630 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/6638 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--libglusterfs/src/client_t.h1
-rw-r--r--libglusterfs/src/glusterfs.h1
-rw-r--r--tests/bugs/bug-765564.t2
-rw-r--r--xlators/features/locks/src/clear.c11
-rw-r--r--xlators/features/locks/src/common.c120
-rw-r--r--xlators/features/locks/src/common.h35
-rw-r--r--xlators/features/locks/src/entrylk.c490
-rw-r--r--xlators/features/locks/src/inodelk.c208
-rw-r--r--xlators/features/locks/src/locks.h36
-rw-r--r--xlators/features/locks/src/posix.c109
10 files changed, 386 insertions, 627 deletions
diff --git a/libglusterfs/src/client_t.h b/libglusterfs/src/client_t.h
index f7812f8f0..548081896 100644
--- a/libglusterfs/src/client_t.h
+++ b/libglusterfs/src/client_t.h
@@ -60,6 +60,7 @@ struct clienttable {
gf_lock_t lock;
cliententry_t *cliententries;
int first_free;
+ client_t *local;
};
typedef struct clienttable clienttable_t;
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index ed483d19c..6dc2fe6df 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -455,7 +455,6 @@ struct _glusterfs_ctx {
int daemon_pipe[2];
- struct client_disconnect *client_disconnect;
struct clienttable *clienttable;
};
typedef struct _glusterfs_ctx glusterfs_ctx_t;
diff --git a/tests/bugs/bug-765564.t b/tests/bugs/bug-765564.t
index 0b8b8cd4f..6e4087f80 100644
--- a/tests/bugs/bug-765564.t
+++ b/tests/bugs/bug-765564.t
@@ -3,6 +3,8 @@
. $(dirname $0)/../include.rc
. $(dirname $0)/../volume.rc
+cleanup;
+
TEST glusterd
TEST pidof glusterd
diff --git a/xlators/features/locks/src/clear.c b/xlators/features/locks/src/clear.c
index 124b9ad0f..75593b898 100644
--- a/xlators/features/locks/src/clear.c
+++ b/xlators/features/locks/src/clear.c
@@ -338,9 +338,8 @@ blkd:
elock->basename, ENTRYLK_LOCK, elock->type,
-1, EAGAIN);
STACK_UNWIND_STRICT (entrylk, elock->frame, -1, EAGAIN, NULL);
- GF_FREE ((char *) elock->basename);
- GF_FREE (elock->connection_id);
- GF_FREE (elock);
+
+ __pl_entrylk_unref (elock);
}
if (!(args->kind & CLRLK_GRANTED)) {
@@ -363,13 +362,13 @@ granted:
gcount++;
list_del_init (&elock->domain_list);
list_add_tail (&elock->domain_list, &removed);
+
+ __pl_entrylk_unref (elock);
}
}
pthread_mutex_unlock (&pl_inode->mutex);
- list_for_each_entry_safe (elock, tmp, &removed, domain_list) {
- grant_blocked_entry_locks (this, pl_inode, elock, dom);
- }
+ grant_blocked_entry_locks (this, pl_inode, dom);
ret = 0;
out:
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c
index b3309580d..f6c71c1cf 100644
--- a/xlators/features/locks/src/common.c
+++ b/xlators/features/locks/src/common.c
@@ -1099,123 +1099,3 @@ pl_getlk (pl_inode_t *pl_inode, posix_lock_t *lock)
return conf;
}
-
-struct _lock_table *
-pl_lock_table_new (void)
-{
- struct _lock_table *new = NULL;
-
- new = GF_CALLOC (1, sizeof (struct _lock_table), gf_common_mt_lock_table);
- if (new == NULL) {
- goto out;
- }
- INIT_LIST_HEAD (&new->entrylk_lockers);
- INIT_LIST_HEAD (&new->inodelk_lockers);
- LOCK_INIT (&new->lock);
-out:
- return new;
-}
-
-
-int
-pl_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc, fd_t *fd, pid_t pid, gf_lkowner_t *owner,
- glusterfs_fop_t type)
-{
- int32_t ret = -1;
- struct _locker *new = NULL;
-
- GF_VALIDATE_OR_GOTO ("lock-table", table, out);
- GF_VALIDATE_OR_GOTO ("lock-table", volume, out);
-
- new = GF_CALLOC (1, sizeof (struct _locker), gf_common_mt_locker);
- if (new == NULL) {
- goto out;
- }
- INIT_LIST_HEAD (&new->lockers);
-
- new->volume = gf_strdup (volume);
-
- if (fd == NULL) {
- loc_copy (&new->loc, loc);
- } else {
- new->fd = fd_ref (fd);
- }
-
- new->pid = pid;
- new->owner = *owner;
-
- LOCK (&table->lock);
- {
- if (type == GF_FOP_ENTRYLK)
- list_add_tail (&new->lockers, &table->entrylk_lockers);
- else
- list_add_tail (&new->lockers, &table->inodelk_lockers);
- }
- UNLOCK (&table->lock);
-out:
- return ret;
-}
-
-int
-pl_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc, fd_t *fd, gf_lkowner_t *owner, glusterfs_fop_t type)
-{
- struct _locker *locker = NULL;
- struct _locker *tmp = NULL;
- int32_t ret = -1;
- struct list_head *head = NULL;
- struct list_head del;
-
- GF_VALIDATE_OR_GOTO ("lock-table", table, out);
- GF_VALIDATE_OR_GOTO ("lock-table", volume, out);
-
- INIT_LIST_HEAD (&del);
-
- LOCK (&table->lock);
- {
- if (type == GF_FOP_ENTRYLK) {
- head = &table->entrylk_lockers;
- } else {
- head = &table->inodelk_lockers;
- }
-
- list_for_each_entry_safe (locker, tmp, head, lockers) {
- if (!is_same_lkowner (&locker->owner, owner) ||
- strcmp (locker->volume, volume))
- continue;
-
- /*
- * It is possible for inodelk lock to come on anon-fd
- * and inodelk unlock to come on normal fd in case of
- * client re-opens. So don't check for fds to be equal.
- */
- if (locker->fd && fd)
- list_move_tail (&locker->lockers, &del);
- else if (locker->loc.inode && loc &&
- (locker->loc.inode == loc->inode))
- list_move_tail (&locker->lockers, &del);
- }
- }
- UNLOCK (&table->lock);
-
- tmp = NULL;
- locker = NULL;
-
- list_for_each_entry_safe (locker, tmp, &del, lockers) {
- list_del_init (&locker->lockers);
- if (locker->fd)
- fd_unref (locker->fd);
- else
- loc_wipe (&locker->loc);
-
- GF_FREE (locker->volume);
- GF_FREE (locker);
- }
-
- ret = 0;
-out:
- return ret;
-
-}
-
diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h
index db19ec978..5ec630ee8 100644
--- a/xlators/features/locks/src/common.h
+++ b/xlators/features/locks/src/common.h
@@ -32,20 +32,6 @@
#define SET_FLOCK_PID(flock, lock) ((flock)->l_pid = lock->client_pid)
-struct _locker {
- struct list_head lockers;
- char *volume;
- loc_t loc;
- fd_t *fd;
- gf_lkowner_t owner;
- pid_t pid;
-};
-
-struct _lock_table {
- struct list_head inodelk_lockers;
- struct list_head entrylk_lockers;
- gf_lock_t lock;
-};
posix_lock_t *
new_posix_lock (struct gf_flock *flock, client_t *client, pid_t client_pid,
@@ -92,7 +78,7 @@ __pl_inodelk_unref (pl_inode_lock_t *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_dom_list_t *dom);
void pl_update_refkeeper (xlator_t *this, inode_t *inode);
@@ -166,22 +152,7 @@ pl_reserve_unlock (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *reqlock);
uint32_t
check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename);
-int32_t
-pl_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid,
- gf_lkowner_t *owner,
- glusterfs_fop_t type);
-
-int32_t
-pl_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- gf_lkowner_t *owner,
- glusterfs_fop_t type);
-
-struct _lock_table *
-pl_lock_table_new (void);
+void __pl_inodelk_unref (pl_inode_lock_t *lock);
+void __pl_entrylk_unref (pl_entry_lock_t *lock);
#endif /* __COMMON_H__ */
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c
index 0785dc547..208bc140e 100644
--- a/xlators/features/locks/src/entrylk.c
+++ b/xlators/features/locks/src/entrylk.c
@@ -23,11 +23,29 @@
#include "locks.h"
#include "common.h"
+
+void
+__pl_entrylk_unref (pl_entry_lock_t *lock)
+{
+ lock->ref--;
+ if (!lock->ref) {
+ GF_FREE ((char *)lock->basename);
+ GF_FREE (lock->connection_id);
+ GF_FREE (lock);
+ }
+}
+
+
+static void
+__pl_entrylk_ref (pl_entry_lock_t *lock)
+{
+ lock->ref++;
+}
+
+
static pl_entry_lock_t *
new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type,
- client_t *client, pid_t client_pid, gf_lkowner_t *owner,
- const char *volume)
-
+ const char *domain, call_frame_t *frame, char *conn_id)
{
pl_entry_lock_t *newlock = NULL;
@@ -39,14 +57,21 @@ new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type,
newlock->basename = basename ? gf_strdup (basename) : NULL;
newlock->type = type;
- newlock->trans = client;
- newlock->volume = volume;
- newlock->client_pid = client_pid;
- newlock->owner = *owner;
+ newlock->client = frame->root->client;
+ newlock->client_pid = frame->root->pid;
+ newlock->volume = domain;
+ newlock->owner = frame->root->lk_owner;
+ newlock->frame = frame;
+
+ if (conn_id) {
+ newlock->connection_id = gf_strdup (conn_id);
+ }
INIT_LIST_HEAD (&newlock->domain_list);
INIT_LIST_HEAD (&newlock->blocked_locks);
+ INIT_LIST_HEAD (&newlock->client_list);
+ __pl_entrylk_ref (newlock);
out:
return newlock;
}
@@ -77,42 +102,42 @@ __same_entrylk_owner (pl_entry_lock_t *l1, pl_entry_lock_t *l2)
{
return (is_same_lkowner (&l1->owner, &l2->owner) &&
- (l1->trans == l2->trans));
+ (l1->client == l2->client));
}
/**
- * lock_grantable - is this lock grantable?
+ * entrylk_grantable - is this lock grantable?
* @inode: inode in which to look
* @basename: name we're trying to lock
* @type: type of lock
*/
static pl_entry_lock_t *
-__lock_grantable (pl_dom_list_t *dom, const char *basename, entrylk_type type)
+__entrylk_grantable (pl_dom_list_t *dom, pl_entry_lock_t *lock)
{
- pl_entry_lock_t *lock = NULL;
+ pl_entry_lock_t *tmp = 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 (tmp, &dom->entrylk_list, domain_list) {
+ if (names_conflict (tmp->basename, lock->basename))
+ return tmp;
}
return NULL;
}
static pl_entry_lock_t *
-__blocked_lock_conflict (pl_dom_list_t *dom, const char *basename, entrylk_type type)
+__blocked_entrylk_conflict (pl_dom_list_t *dom, pl_entry_lock_t *lock)
{
- pl_entry_lock_t *lock = NULL;
+ pl_entry_lock_t *tmp = 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))
+ list_for_each_entry (tmp, &dom->blocked_entrylks, blocked_locks) {
+ if (names_conflict (tmp->basename, lock->basename))
return lock;
}
@@ -293,7 +318,7 @@ __find_most_matching_lock (pl_dom_list_t *dom, const char *basename)
}
/**
- * __lock_name - lock a name in a directory
+ * __lock_entrylk - lock a name in a directory
* @inode: inode for the directory in which to lock
* @basename: name of the entry to lock
* if null, lock the entire directory
@@ -304,89 +329,49 @@ __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, char *conn_id)
+__lock_entrylk (xlator_t *this, pl_inode_t *pinode, pl_entry_lock_t *lock,
+ int nonblock, pl_dom_list_t *dom)
{
- 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;
- }
-
- lock->frame = frame;
- lock->this = this;
- lock->trans = frame->root->client;
+ pl_entry_lock_t *conf = NULL;
+ int ret = -EAGAIN;
- if (conn_id) {
- lock->connection_id = gf_strdup (conn_id);
- }
-
- conf = __lock_grantable (dom, basename, type);
+ conf = __entrylk_grantable (dom, lock);
if (conf) {
ret = -EAGAIN;
- if (nonblock){
- GF_FREE (lock->connection_id);
- GF_FREE ((char *)lock->basename);
- GF_FREE (lock);
+ if (nonblock)
goto out;
- }
-
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);
+ pinode, lock->basename);
goto out;
}
- if ( __blocked_lock_conflict (dom, basename, type) && !(__owner_has_lock (dom, lock))) {
+ if (__blocked_entrylk_conflict (dom, lock) && !(__owner_has_lock (dom, lock))) {
ret = -EAGAIN;
- if (nonblock) {
- GF_FREE (lock->connection_id);
- GF_FREE ((char *) lock->basename);
- GF_FREE (lock);
+ if (nonblock)
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,
+ gf_log (this->name, GF_LOG_DEBUG,
"Lock is grantable, but blocking to prevent starvation");
gf_log (this->name, GF_LOG_TRACE,
"Blocking lock: {pinode=%p, basename=%s}",
- pinode, basename);
+ pinode, lock->basename);
- ret = -EAGAIN;
goto out;
}
- switch (type) {
- case ENTRYLK_WRLCK:
- gettimeofday (&lock->granted_time, NULL);
- list_add_tail (&lock->domain_list, &dom->entrylk_list);
- break;
-
- default:
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Invalid type for entrylk specified: %d", type);
- ret = -EINVAL;
- goto out;
- }
+ __pl_entrylk_ref (lock);
+ gettimeofday (&lock->granted_time, NULL);
+ list_add (&lock->domain_list, &dom->entrylk_list);
+ lock->frame = NULL;
ret = 0;
out:
@@ -394,37 +379,36 @@ out:
}
/**
- * __unlock_name - unlock a name in a directory
+ * __unlock_entrylk - unlock a name in a directory
* @inode: inode for the directory to unlock in
* @basename: name of the entry to unlock
* if null, unlock the entire directory
*/
pl_entry_lock_t *
-__unlock_name (pl_dom_list_t *dom, const char *basename, entrylk_type type)
+__unlock_entrylk (pl_dom_list_t *dom, pl_entry_lock_t *lock)
{
- pl_entry_lock_t *lock = NULL;
+ pl_entry_lock_t *tmp = NULL;
pl_entry_lock_t *ret_lock = NULL;
- lock = __find_most_matching_lock (dom, basename);
+ tmp = __find_most_matching_lock (dom, lock->basename);
- if (!lock) {
- gf_log ("locks", GF_LOG_DEBUG,
+ if (!tmp) {
+ gf_log ("locks", GF_LOG_ERROR,
"unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found",
- basename);
+ lock->basename);
goto out;
}
- if (names_equal (lock->basename, basename)
- && lock->type == type) {
+ if (names_equal (tmp->basename, lock->basename)
+ && tmp->type == lock->type) {
+
+ list_del_init (&tmp->domain_list);
+ ret_lock = tmp;
- 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!");
+ gf_log ("locks", GF_LOG_ERROR,
+ "Unlock on %s for a non-existing lock!", lock->basename);
goto out;
}
@@ -446,7 +430,7 @@ check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename)
pthread_mutex_lock (&pinode->mutex);
{
list_for_each_entry (dom, &pinode->dom_list, inode_list) {
- conf = __lock_grantable (dom, basename, ENTRYLK_WRLCK);
+ conf = __find_most_matching_lock (dom, basename);
if (conf && conf->basename) {
entrylk = 1;
break;
@@ -472,28 +456,14 @@ __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
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_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);
-
- bl_ret = __lock_name (pl_inode, bl->basename, bl->type,
- bl->frame, dom, bl->this, 0,
- bl->connection_id);
+ bl_ret = __lock_entrylk (bl->this, pl_inode, bl, 0, dom);
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;
@@ -502,7 +472,7 @@ __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
/* 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_dom_list_t *dom)
{
struct list_head granted_list;
pl_entry_lock_t *tmp = NULL;
@@ -518,105 +488,26 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
pthread_mutex_unlock (&pl_inode->mutex);
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, NULL);
+ lock->frame = 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);
+ pthread_mutex_lock (&pl_inode->mutex);
+ {
+ list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks) {
+ list_del_init (&lock->blocked_locks);
+ __pl_entrylk_unref (lock);
+ }
+ }
+ pthread_mutex_unlock (&pl_inode->mutex);
return;
}
-/**
- * release_entry_locks_for_client: release all entry locks from this
- * client for this loc_t
- */
-
-static int
-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;
- struct list_head released;
-
- INIT_LIST_HEAD (&granted);
- INIT_LIST_HEAD (&released);
-
- 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);
-
- gf_log (this->name, GF_LOG_TRACE,
- "releasing lock on held by "
- "{client=%p}", client);
-
- list_add (&lock->blocked_locks, &released);
-
- }
-
- 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 "
- "{client=%p}", client);
-
- GF_FREE ((char *)lock->basename);
- GF_FREE (lock->connection_id);
- GF_FREE (lock);
- }
-
- __grant_blocked_entry_locks (this, pinode, dom, &granted);
-
- }
-
- pthread_mutex_unlock (&pinode->mutex);
-
- list_for_each_entry_safe (lock, tmp, &released, blocked_locks) {
- list_del_init (&lock->blocked_locks);
-
- STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN, NULL);
-
- 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
@@ -632,10 +523,12 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
char unwind = 1;
GF_UNUSED int dict_ret = -1;
pl_inode_t *pinode = NULL;
+ pl_entry_lock_t *reqlock = NULL;
pl_entry_lock_t *unlocked = NULL;
pl_dom_list_t *dom = NULL;
char *conn_id = NULL;
pl_ctx_t *ctx = NULL;
+ int nonblock = 0;
if (xdata)
dict_ret = dict_get_str (xdata, "connection-id", &conn_id);
@@ -646,6 +539,15 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (frame->root->client) {
+ ctx = pl_ctx_get (frame->root->client, this);
+ if (!ctx) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_INFO, "pl_ctx_get() failed");
+ goto unwind;
+ }
+ }
+
dom = get_domain (pinode, volume);
if (!dom){
op_errno = ENOMEM;
@@ -654,72 +556,64 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type);
- if (frame->root->lk_owner.len == 0) {
- /*
- this is a special case that means release
- 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;
+ reqlock = new_entrylk_lock (pinode, basename, type, dom->domain, frame,
+ conn_id);
+ if (!reqlock) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
}
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;
+ nonblock = 1;
+ /* fall through */
+ case ENTRYLK_LOCK:
+ if (ctx)
+ pthread_mutex_lock (&ctx->lock);
pthread_mutex_lock (&pinode->mutex);
{
- ret = __lock_name (pinode, basename, type,
- frame, dom, this, 1, conn_id);
+ reqlock->pinode = pinode;
+
+ ret = __lock_entrylk (this, pinode, reqlock, nonblock, dom);
+ if (ret == 0)
+ op_ret = 0;
+ else
+ op_errno = -ret;
+
+ if (ctx && (!ret || !nonblock))
+ list_add (&reqlock->client_list,
+ &ctx->entrylk_lockers);
+
+ if (ret == -EAGAIN && !nonblock) {
+ /* blocked */
+ unwind = 0;
+ } else {
+ __pl_entrylk_unref (reqlock);
+ }
}
pthread_mutex_unlock (&pinode->mutex);
-
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
-
- break;
+ if (ctx)
+ pthread_mutex_unlock (&ctx->lock);
+ break;
case ENTRYLK_UNLOCK:
+ if (ctx)
+ pthread_mutex_lock (&ctx->lock);
pthread_mutex_lock (&pinode->mutex);
{
- unlocked = __unlock_name (dom, basename, type);
+ unlocked = __unlock_entrylk (dom, reqlock);
+ if (unlocked) {
+ list_del_init (&unlocked->client_list);
+ __pl_entrylk_unref (unlocked);
+ }
+ __pl_entrylk_unref (reqlock);
}
pthread_mutex_unlock (&pinode->mutex);
+ if (ctx)
+ pthread_mutex_unlock (&ctx->lock);
- if (unlocked)
- grant_blocked_entry_locks (this, pinode, unlocked, dom);
+ grant_blocked_entry_locks (this, pinode, dom);
break;
@@ -733,27 +627,10 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
op_ret = 0;
out:
pl_update_refkeeper (this, inode);
+
if (unwind) {
entrylk_trace_out (this, frame, volume, fd, loc, basename,
cmd, type, 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 {
@@ -761,7 +638,6 @@ unwind:
cmd, type);
}
-
return 0;
}
@@ -801,6 +677,88 @@ pl_fentrylk (call_frame_t *frame, xlator_t *this,
}
+static void
+pl_entrylk_log_cleanup (pl_entry_lock_t *lock)
+{
+ pl_inode_t *pinode = NULL;
+ char *path = NULL;
+ char *file = NULL;
+
+ pinode = lock->pinode;
+
+ inode_path (pinode->refkeeper, NULL, &path);
+
+ if (path)
+ file = path;
+ else
+ file = uuid_utoa (pinode->refkeeper->gfid);
+
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "releasing lock on %s held by "
+ "{client=%p, pid=%"PRId64" lk-owner=%s}",
+ file, lock->client, (uint64_t) lock->client_pid,
+ lkowner_utoa (&lock->owner));
+ GF_FREE (path);
+}
+
+
+/* Release all entrylks from this client */
+int
+pl_entrylk_client_cleanup (xlator_t *this, pl_ctx_t *ctx)
+{
+ pl_entry_lock_t *tmp = NULL;
+ pl_entry_lock_t *l = NULL;
+ pl_dom_list_t *dom = NULL;
+ pl_inode_t *pinode = NULL;
+
+ struct list_head released;
+
+ INIT_LIST_HEAD (&released);
+
+ pthread_mutex_lock (&ctx->lock);
+ {
+ list_for_each_entry_safe (l, tmp, &ctx->entrylk_lockers,
+ client_list) {
+ list_del_init (&l->client_list);
+ list_add_tail (&l->client_list, &released);
+
+ pl_entrylk_log_cleanup (l);
+
+ pinode = l->pinode;
+
+ pthread_mutex_lock (&pinode->mutex);
+ {
+ list_del_init (&l->domain_list);
+ }
+ pthread_mutex_unlock (&pinode->mutex);
+ }
+ }
+ pthread_mutex_unlock (&ctx->lock);
+
+ list_for_each_entry_safe (l, tmp, &released, client_list) {
+ list_del_init (&l->client_list);
+
+ if (l->frame)
+ STACK_UNWIND_STRICT (entrylk, l->frame, -1, EAGAIN,
+ NULL);
+
+ pinode = l->pinode;
+
+ dom = get_domain (pinode, l->volume);
+
+ grant_blocked_inode_locks (this, pinode, dom);
+
+ pthread_mutex_lock (&pinode->mutex);
+ {
+ __pl_entrylk_unref (l);
+ }
+ pthread_mutex_unlock (&pinode->mutex);
+ }
+
+ return 0;
+}
+
+
int32_t
__get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode)
{
diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c
index 508523e11..969b67a61 100644
--- a/xlators/features/locks/src/inodelk.c
+++ b/xlators/features/locks/src/inodelk.c
@@ -35,7 +35,7 @@ __pl_inodelk_ref (pl_inode_lock_t *lock)
lock->ref++;
}
-inline void
+void
__pl_inodelk_unref (pl_inode_lock_t *lock)
{
lock->ref--;
@@ -204,7 +204,7 @@ __lock_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
int ret = -EINVAL;
conf = __inodelk_grantable (dom, lock);
- if (conf){
+ if (conf) {
ret = -EAGAIN;
if (can_block == 0)
goto out;
@@ -232,7 +232,7 @@ __lock_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
gettimeofday (&lock->blkd_time, NULL);
list_add_tail (&lock->blocked_locks, &dom->blocked_inodelks);
- gf_log (this->name, GF_LOG_TRACE,
+ gf_log (this->name, GF_LOG_DEBUG,
"Lock is grantable, but blocking to prevent starvation");
gf_log (this->name, GF_LOG_TRACE,
"%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => Blocked",
@@ -307,6 +307,8 @@ __inode_unlock_lock (xlator_t *this, pl_inode_lock_t *lock, pl_dom_list_t *dom)
out:
return conf;
}
+
+
static void
__grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
struct list_head *granted, pl_dom_list_t *dom)
@@ -363,6 +365,7 @@ grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
&lock->user_flock, 0, 0, lock->volume);
STACK_UNWIND_STRICT (inodelk, lock->frame, 0, 0, NULL);
+ lock->frame = NULL;
}
pthread_mutex_lock (&pl_inode->mutex);
@@ -375,103 +378,101 @@ grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
pthread_mutex_unlock (&pl_inode->mutex);
}
-/* Release all inodelks from this client */
-static int
-release_inode_locks_of_client (xlator_t *this, pl_dom_list_t *dom,
- inode_t *inode, client_t *client)
+
+static void
+pl_inodelk_log_cleanup (pl_inode_lock_t *lock)
{
- pl_inode_lock_t *tmp = NULL;
- pl_inode_lock_t *l = NULL;
+ pl_inode_t *pl_inode = NULL;
+ char *path = NULL;
+ char *file = NULL;
- pl_inode_t * pinode = NULL;
+ pl_inode = lock->pl_inode;
- struct list_head released;
+ inode_path (pl_inode->refkeeper, NULL, &path);
- char *path = NULL;
- char *file = NULL;
+ if (path)
+ file = path;
+ else
+ file = uuid_utoa (pl_inode->refkeeper->gfid);
- INIT_LIST_HEAD (&released);
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "releasing lock on %s held by "
+ "{client=%p, pid=%"PRId64" lk-owner=%s}",
+ file, lock->client, (uint64_t) lock->client_pid,
+ lkowner_utoa (&lock->owner));
+ GF_FREE (path);
+}
- pinode = pl_inode_get (this, inode);
- pthread_mutex_lock (&pinode->mutex);
- {
+/* Release all entrylks from this client */
+int
+pl_inodelk_client_cleanup (xlator_t *this, pl_ctx_t *ctx)
+{
+ pl_inode_lock_t *tmp = NULL;
+ pl_inode_lock_t *l = NULL;
+ pl_dom_list_t *dom = NULL;
+ pl_inode_t *pl_inode = NULL;
+
+ struct list_head released;
- list_for_each_entry_safe (l, tmp, &dom->blocked_inodelks, blocked_locks) {
- if (l->client != client)
- continue;
+ INIT_LIST_HEAD (&released);
- list_del_init (&l->blocked_locks);
+ pthread_mutex_lock (&ctx->lock);
+ {
+ list_for_each_entry_safe (l, tmp, &ctx->inodelk_lockers,
+ client_list) {
+ list_del_init (&l->client_list);
+ list_add_tail (&l->client_list, &released);
- inode_path (inode, NULL, &path);
- if (path)
- file = path;
- else
- file = uuid_utoa (inode->gfid);
+ pl_inodelk_log_cleanup (l);
- gf_log (this->name, GF_LOG_DEBUG,
- "releasing blocking lock on %s held by "
- "{client=%p, pid=%"PRId64" lk-owner=%s}",
- file, client, (uint64_t) l->client_pid,
- lkowner_utoa (&l->owner));
+ pl_inode = l->pl_inode;
- list_add (&l->blocked_locks, &released);
- if (path) {
- GF_FREE (path);
- path = NULL;
+ pthread_mutex_lock (&pl_inode->mutex);
+ {
+ __delete_inode_lock (l);
}
+ pthread_mutex_unlock (&pl_inode->mutex);
}
+ }
+ pthread_mutex_unlock (&ctx->lock);
- list_for_each_entry_safe (l, tmp, &dom->inodelk_list, list) {
- if (l->client != client)
- continue;
-
- inode_path (inode, NULL, &path);
- if (path)
- file = path;
- else
- file = uuid_utoa (inode->gfid);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "releasing granted lock on %s held by "
- "{client=%p, pid=%"PRId64" lk-owner=%s}",
- file, client, (uint64_t) l->client_pid,
- lkowner_utoa (&l->owner));
-
- if (path) {
- GF_FREE (path);
- path = NULL;
- }
+ list_for_each_entry_safe (l, tmp, &released, client_list) {
+ list_del_init (&l->client_list);
- __delete_inode_lock (l);
- __pl_inodelk_unref (l);
- }
- }
- GF_FREE (path);
+ if (l->frame)
+ STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN,
+ NULL);
+
+ pl_inode = l->pl_inode;
- pthread_mutex_unlock (&pinode->mutex);
+ dom = get_domain (pl_inode, l->volume);
- list_for_each_entry_safe (l, tmp, &released, blocked_locks) {
- list_del_init (&l->blocked_locks);
+ grant_blocked_inode_locks (this, pl_inode, dom);
- STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN, NULL);
- //No need to take lock as the locks are only in one list
- __pl_inodelk_unref (l);
+ pthread_mutex_lock (&pl_inode->mutex);
+ {
+ __pl_inodelk_unref (l);
+ }
+ pthread_mutex_unlock (&pl_inode->mutex);
}
- grant_blocked_inode_locks (this, pinode, dom);
return 0;
}
static int
-pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
- int can_block, pl_dom_list_t *dom)
+pl_inode_setlk (xlator_t *this, pl_ctx_t *ctx, pl_inode_t *pl_inode,
+ pl_inode_lock_t *lock, int can_block, pl_dom_list_t *dom)
{
int ret = -EINVAL;
pl_inode_lock_t *retlock = NULL;
gf_boolean_t unref = _gf_true;
+ lock->pl_inode = pl_inode;
+
+ if (ctx)
+ pthread_mutex_lock (&ctx->lock);
pthread_mutex_lock (&pl_inode->mutex);
{
if (lock->fl_type != F_UNLCK) {
@@ -495,6 +496,10 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
if (can_block)
unref = _gf_false;
}
+
+ if (ctx && (!ret || can_block))
+ list_add_tail (&lock->client_list,
+ &ctx->inodelk_lockers);
} else {
retlock = __inode_unlock_lock (this, lock, dom);
if (!retlock) {
@@ -503,16 +508,21 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
ret = -EINVAL;
goto out;
}
- __pl_inodelk_unref (retlock);
+ list_del_init (&retlock->client_list);
+ __pl_inodelk_unref (retlock);
ret = 0;
}
- }
out:
- if (unref)
- __pl_inodelk_unref (lock);
+ if (unref)
+ __pl_inodelk_unref (lock);
+ }
pthread_mutex_unlock (&pl_inode->mutex);
+ if (ctx)
+ pthread_mutex_unlock (&ctx->lock);
+
grant_blocked_inode_locks (this, pl_inode, dom);
+
return ret;
}
@@ -552,6 +562,7 @@ new_inode_lock (struct gf_flock *flock, client_t *client, pid_t client_pid,
INIT_LIST_HEAD (&lock->list);
INIT_LIST_HEAD (&lock->blocked_locks);
+ INIT_LIST_HEAD (&lock->client_list);
__pl_inodelk_ref (lock);
return lock;
@@ -627,6 +638,15 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
pl_trace_in (this, frame, fd, loc, cmd, flock, volume);
+ if (frame->root->client) {
+ ctx = pl_ctx_get (frame->root->client, this);
+ if (!ctx) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_INFO, "pl_ctx_get() failed");
+ goto unwind;
+ }
+ }
+
pinode = pl_inode_get (this, inode);
if (!pinode) {
op_errno = ENOMEM;
@@ -639,27 +659,6 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
goto unwind;
}
- if (frame->root->lk_owner.len == 0) {
- /*
- special case: this means release all locks
- from this client
- */
- gf_log (this->name, GF_LOG_TRACE,
- "Releasing all locks from client %p", frame->root->client);
-
- release_inode_locks_of_client (this, dom, inode, frame->root->client);
- _pl_convert_volume (volume, &res1);
- if (res1) {
- dom = get_domain (pinode, res1);
- if (dom)
- release_inode_locks_of_client (this, dom,
- inode, frame->root->client);
- }
-
- op_ret = 0;
- goto unwind;
- }
-
reqlock = new_inode_lock (flock, frame->root->client, frame->root->pid,
frame, this, volume, conn_id);
@@ -678,8 +677,8 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
case F_SETLK:
memcpy (&reqlock->user_flock, flock, sizeof (struct gf_flock));
- ret = pl_inode_setlk (this, pinode, reqlock,
- can_block, dom);
+ ret = pl_inode_setlk (this, ctx, pinode, reqlock, can_block,
+ dom);
if (ret < 0) {
if ((can_block) && (F_UNLCK != flock->l_type)) {
@@ -704,23 +703,6 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
op_ret = 0;
- 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 (flock->l_type == F_UNLCK)
- pl_del_locker (ctx->ltable, volume, loc, fd,
- &frame->root->lk_owner,
- GF_FOP_INODELK);
- else
- pl_add_locker (ctx->ltable, volume, loc, fd,
- frame->root->pid,
- &frame->root->lk_owner,
- GF_FOP_INODELK);
-
unwind:
if ((inode != NULL) && (flock !=NULL)) {
pl_update_refkeeper (this, inode);
diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h
index 76fc941d7..8c2a6f867 100644
--- a/xlators/features/locks/src/locks.h
+++ b/xlators/features/locks/src/locks.h
@@ -65,7 +65,7 @@ struct __pl_inode_lock {
struct gf_flock user_flock; /* the flock supplied by the user */
xlator_t *this; /* required for blocked locks */
- fd_t *fd;
+ struct __pl_inode *pl_inode;
call_frame_t *frame;
@@ -80,6 +80,8 @@ struct __pl_inode_lock {
pid_t client_pid; /* pid of client process */
char *connection_id; /* stores the client connection id */
+
+ struct list_head client_list; /* list of all locks from a client */
};
typedef struct __pl_inode_lock pl_inode_lock_t;
@@ -103,9 +105,11 @@ typedef struct __pl_dom_list_t pl_dom_list_t;
struct __entry_lock {
struct list_head domain_list; /* list_head back to pl_dom_list_t */
struct list_head blocked_locks; /* list_head back to blocked_entrylks */
+ int ref;
call_frame_t *frame;
xlator_t *this;
+ struct __pl_inode *pinode;
const char *volume;
@@ -115,11 +119,13 @@ struct __entry_lock {
struct timeval blkd_time; /*time at which lock was queued into blkd list*/
struct timeval granted_time; /*time at which lock was queued into active list*/
- void *trans;
+ void *client;
gf_lkowner_t owner;
pid_t client_pid; /* pid of client process */
char *connection_id; /* stores the client connection id */
+
+ struct list_head client_list; /* list of all locks from a client */
};
typedef struct __entry_lock pl_entry_lock_t;
@@ -144,12 +150,6 @@ struct __pl_inode {
typedef struct __pl_inode pl_inode_t;
-struct __pl_fd {
- gf_boolean_t nonblocking; /* whether O_NONBLOCK has been set */
-};
-typedef struct __pl_fd pl_fd_t;
-
-
typedef struct {
gf_boolean_t mandatory; /* if mandatory locking is enabled */
gf_boolean_t trace; /* trace lock requests in and out */
@@ -178,15 +178,27 @@ typedef struct {
} pl_fdctx_t;
+struct _locker {
+ struct list_head lockers;
+ char *volume;
+ inode_t *inode;
+ gf_lkowner_t owner;
+};
+
typedef struct _locks_ctx {
- gf_lock_t ltable_lock; /* only for replace,
- ltable has its own internal
- lock for operations */
- struct _lock_table *ltable;
+ pthread_mutex_t lock;
+ struct list_head inodelk_lockers;
+ struct list_head entrylk_lockers;
} pl_ctx_t;
pl_ctx_t *
pl_ctx_get (client_t *client, xlator_t *xlator);
+int
+pl_inodelk_client_cleanup (xlator_t *this, pl_ctx_t *ctx);
+
+int
+pl_entrylk_client_cleanup (xlator_t *this, pl_ctx_t *ctx);
+
#endif /* __POSIX_LOCKS_H__ */
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
index 7bfb38a51..fce0d509f 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -2243,7 +2243,7 @@ __dump_entrylks (pl_inode_t *pl_inode)
lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
"ENTRYLK_WRLCK", lock->basename,
(unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->trans,
+ lkowner_utoa (&lock->owner), lock->client,
lock->connection_id,
ctime_r (&lock->granted_time.tv_sec, granted));
} else {
@@ -2251,7 +2251,7 @@ __dump_entrylks (pl_inode_t *pl_inode)
lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
"ENTRYLK_WRLCK", lock->basename,
(unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->trans,
+ lkowner_utoa (&lock->owner), lock->client,
lock->connection_id,
ctime_r (&lock->blkd_time.tv_sec, blocked),
ctime_r (&lock->granted_time.tv_sec, granted));
@@ -2271,7 +2271,7 @@ __dump_entrylks (pl_inode_t *pl_inode)
lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
"ENTRYLK_WRLCK", lock->basename,
(unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->trans,
+ lkowner_utoa (&lock->owner), lock->client,
lock->connection_id,
ctime_r (&lock->blkd_time.tv_sec, blocked));
@@ -2524,19 +2524,12 @@ pl_ctx_get (client_t *client, xlator_t *xlator)
if (ctx == NULL)
goto out;
- ctx->ltable = pl_lock_table_new();
-
- if (ctx->ltable == NULL) {
- GF_FREE (ctx);
- ctx = NULL;
- goto out;
- }
-
- LOCK_INIT (&ctx->ltable_lock);
+ pthread_mutex_init (&ctx->lock, NULL);
+ INIT_LIST_HEAD (&ctx->inodelk_lockers);
+ INIT_LIST_HEAD (&ctx->entrylk_lockers);
if (client_ctx_set (client, xlator, ctx) != 0) {
- LOCK_DESTROY (&ctx->ltable_lock);
- GF_FREE (ctx->ltable);
+ pthread_mutex_destroy (&ctx->lock);
GF_FREE (ctx);
ctx = NULL;
}
@@ -2544,82 +2537,44 @@ out:
return ctx;
}
-static void
-ltable_delete_locks (struct _lock_table *ltable)
+
+static int
+pl_client_disconnect_cbk (xlator_t *this, client_t *client)
{
- struct _locker *locker = NULL;
- struct _locker *tmp = NULL;
+ pl_ctx_t *pl_ctx = NULL;
- list_for_each_entry_safe (locker, tmp, &ltable->inodelk_lockers, lockers) {
- if (locker->fd)
- pl_del_locker (ltable, locker->volume, &locker->loc,
- locker->fd, &locker->owner,
- GF_FOP_INODELK);
- GF_FREE (locker->volume);
- GF_FREE (locker);
- }
+ pl_ctx = pl_ctx_get (client, this);
- list_for_each_entry_safe (locker, tmp, &ltable->entrylk_lockers, lockers) {
- if (locker->fd)
- pl_del_locker (ltable, locker->volume, &locker->loc,
- locker->fd, &locker->owner,
- GF_FOP_ENTRYLK);
- GF_FREE (locker->volume);
- GF_FREE (locker);
- }
- GF_FREE (ltable);
+ pl_inodelk_client_cleanup (this, pl_ctx);
+
+ pl_entrylk_client_cleanup (this, pl_ctx);
+
+ return 0;
}
-static int32_t
-destroy_cbk (xlator_t *this, client_t *client)
+static int
+pl_client_destroy_cbk (xlator_t *this, client_t *client)
{
- void *tmp = NULL;
- pl_ctx_t *locks_ctx = NULL;
+ void *tmp = NULL;
+ pl_ctx_t *pl_ctx = NULL;
+
+ pl_client_disconnect_cbk (this, client);
client_ctx_del (client, this, &tmp);
if (tmp == NULL)
- return 0
-;
- locks_ctx = tmp;
- if (locks_ctx->ltable)
- ltable_delete_locks (locks_ctx->ltable);
-
- LOCK_DESTROY (&locks_ctx->ltable_lock);
- GF_FREE (locks_ctx);
-
- return 0;
-}
+ return 0;
+ pl_ctx = tmp;
-static int32_t
-disconnect_cbk (xlator_t *this, client_t *client)
-{
- int32_t ret = 0;
- pl_ctx_t *locks_ctx = NULL;
- struct _lock_table *ltable = NULL;
+ GF_ASSERT (list_empty(&pl_ctx->inodelk_lockers));
+ GF_ASSERT (list_empty(&pl_ctx->entrylk_lockers));
- locks_ctx = pl_ctx_get (client, this);
- if (locks_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "pl_ctx_get() failed");
- goto out;
- }
+ pthread_mutex_destroy (&pl_ctx->lock);
+ GF_FREE (pl_ctx);
- LOCK (&locks_ctx->ltable_lock);
- {
- if (locks_ctx->ltable) {
- ltable = locks_ctx->ltable;
- locks_ctx->ltable = pl_lock_table_new ();
- }
- }
- UNLOCK (&locks_ctx->ltable_lock);
-
- if (ltable)
- ltable_delete_locks (ltable);
-
-out:
- return ret;
+ return 0;
}
@@ -2756,8 +2711,8 @@ struct xlator_cbks cbks = {
.forget = pl_forget,
.release = pl_release,
.releasedir = pl_releasedir,
- .client_destroy = destroy_cbk,
- .client_disconnect = disconnect_cbk,
+ .client_destroy = pl_client_destroy_cbk,
+ .client_disconnect = pl_client_disconnect_cbk,
};