summaryrefslogtreecommitdiffstats
path: root/xlators/features/locks/src/inodelk.c
diff options
context:
space:
mode:
authorPranith Kumar K <pranithk@gluster.com>2012-03-07 17:48:12 +0530
committerVijay Bellur <vijay@gluster.com>2012-03-10 02:24:30 -0800
commitf75277b12af4c7e72c448480feec0d0e2e6582cd (patch)
tree76846886f4d88d8abb83cf4fe95576418d571bbe /xlators/features/locks/src/inodelk.c
parent7afa2747234778be3f2cffb860a8c48286dde566 (diff)
features/locks: Make inodelk ref-counted
Ref when the object is allocated. Unref after the response is submitted to that inodelk. Ref when the lock is granted. Unref when the lock is unlocked. Change-Id: I2bfe9182b67bea7dc7b9d0ed9f99f1c7fa0b8a3c BUG: 783449 Signed-off-by: Pranith Kumar K <pranithk@gluster.com> Reviewed-on: http://review.gluster.com/2891 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'xlators/features/locks/src/inodelk.c')
-rw-r--r--xlators/features/locks/src/inodelk.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c
index cc7160330..b8b5643e8 100644
--- a/xlators/features/locks/src/inodelk.c
+++ b/xlators/features/locks/src/inodelk.c
@@ -33,20 +33,28 @@
#include "locks.h"
#include "common.h"
-void
+inline void
__delete_inode_lock (pl_inode_lock_t *lock)
{
list_del (&lock->list);
}
-void
-__destroy_inode_lock (pl_inode_lock_t *lock)
+static inline void
+__pl_inodelk_ref (pl_inode_lock_t *lock)
+{
+ lock->ref++;
+}
+
+inline void
+__pl_inodelk_unref (pl_inode_lock_t *lock)
{
- GF_FREE (lock);
+ lock->ref--;
+ if (!lock->ref)
+ GF_FREE (lock);
}
/* Check if 2 inodelks are conflicting on type. Only 2 shared locks don't conflict */
-static int
+static inline int
inodelk_type_conflict (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
if (l2->fl_type == F_WRLCK || l1->fl_type == F_WRLCK)
@@ -245,6 +253,7 @@ __lock_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
goto out;
}
+ __pl_inodelk_ref (lock);
gettimeofday (&lock->granted_time, NULL);
list_add (&lock->list, &dom->inodelk_list);
@@ -296,8 +305,6 @@ __inode_unlock_lock (xlator_t *this, pl_inode_lock_t *lock, pl_dom_list_t *dom)
__delete_inode_lock (conf);
gf_log (this->name, GF_LOG_DEBUG,
" Matching lock found for unlock");
- __destroy_inode_lock (lock);
-
out:
return conf;
@@ -340,11 +347,6 @@ grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *
INIT_LIST_HEAD (&granted);
- if (list_empty (&dom->blocked_inodelks)) {
- gf_log (this->name, GF_LOG_TRACE,
- "No blocked locks to be granted for domain: %s", dom->domain);
- }
-
pthread_mutex_lock (&pl_inode->mutex);
{
__grant_blocked_inode_locks (this, pl_inode, &granted, dom);
@@ -366,6 +368,14 @@ grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *
STACK_UNWIND_STRICT (inodelk, lock->frame, 0, 0);
}
+ pthread_mutex_lock (&pl_inode->mutex);
+ {
+ list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
+ list_del_init (&lock->blocked_locks);
+ __pl_inodelk_unref (lock);
+ }
+ }
+ pthread_mutex_unlock (&pl_inode->mutex);
}
/* Release all inodelks from this transport */
@@ -378,13 +388,11 @@ release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom,
pl_inode_t * pinode = NULL;
- struct list_head granted;
struct list_head released;
char *path = NULL;
char *file = NULL;
- INIT_LIST_HEAD (&granted);
INIT_LIST_HEAD (&released);
pinode = pl_inode_get (this, inode);
@@ -439,7 +447,7 @@ release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom,
}
__delete_inode_lock (l);
- __destroy_inode_lock (l);
+ __pl_inodelk_unref (l);
}
}
if (path)
@@ -451,7 +459,8 @@ release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom,
list_del_init (&l->blocked_locks);
STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN);
- GF_FREE (l);
+ //No need to take lock as the locks are only in one list
+ __pl_inodelk_unref (l);
}
grant_blocked_inode_locks (this, pinode, dom);
@@ -465,12 +474,13 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
{
int ret = -EINVAL;
pl_inode_lock_t *retlock = NULL;
+ gf_boolean_t unref = _gf_true;
pthread_mutex_lock (&pl_inode->mutex);
{
if (lock->fl_type != F_UNLCK) {
ret = __lock_inodelk (this, pl_inode, lock, can_block, dom);
- if (ret == 0)
+ if (ret == 0) {
gf_log (this->name, GF_LOG_TRACE,
"%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => OK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
@@ -478,8 +488,7 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
lkowner_utoa (&lock->owner),
lock->fl_start,
lock->fl_end);
-
- if (ret == -EAGAIN)
+ } else if (ret == -EAGAIN) {
gf_log (this->name, GF_LOG_TRACE,
"%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => NOK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
@@ -487,25 +496,25 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
lkowner_utoa (&lock->owner),
lock->user_flock.l_start,
lock->user_flock.l_len);
+ if (can_block)
+ unref = _gf_false;
+ }
+ } else {
+ retlock = __inode_unlock_lock (this, lock, dom);
+ if (!retlock) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Bad Unlock issued on Inode lock");
+ ret = -EINVAL;
+ goto out;
+ }
+ __pl_inodelk_unref (retlock);
- goto out;
- }
-
-
- retlock = __inode_unlock_lock (this, lock, dom);
- if (!retlock) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Bad Unlock issued on Inode lock");
- ret = -EINVAL;
- goto out;
+ ret = 0;
}
- __destroy_inode_lock (retlock);
-
- ret = 0;
-
-
}
out:
+ if (unref)
+ __pl_inodelk_unref (lock);
pthread_mutex_unlock (&pl_inode->mutex);
grant_blocked_inode_locks (this, pl_inode, dom);
return ret;
@@ -540,6 +549,7 @@ new_inode_lock (struct gf_flock *flock, void *transport, pid_t client_pid,
INIT_LIST_HEAD (&lock->list);
INIT_LIST_HEAD (&lock->blocked_locks);
+ __pl_inodelk_ref (lock);
return lock;
}
@@ -629,7 +639,6 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
}
gf_log (this->name, GF_LOG_TRACE, "returning EAGAIN");
op_errno = -ret;
- __destroy_inode_lock (reqlock);
goto unwind;
}
break;