summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavan Sondur <pavan@gluster.com>2010-08-22 14:09:48 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-08-22 22:27:49 -0700
commit0d33cce6f7bbb71abe0086469f2f726151b0e62c (patch)
tree74192cf39d8963889a4f37182d2bed229e99d347
parent63f9e2a49573a0b539c0082fd0c08c1b4d4db983 (diff)
protocol/server: features/locks: Fix nonblocking entrylks, inodelks in locks and server.
Signed-off-by: Pavan Vilas Sondur <pavan@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 960 () URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=960
-rw-r--r--xlators/features/locks/src/entrylk.c45
-rw-r--r--xlators/features/locks/src/inodelk.c17
-rw-r--r--xlators/protocol/server/src/server-helpers.c29
-rw-r--r--xlators/protocol/server/src/server-helpers.h5
-rw-r--r--xlators/protocol/server/src/server.h1
-rw-r--r--xlators/protocol/server/src/server3_1-fops.c20
6 files changed, 68 insertions, 49 deletions
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c
index ffdac707617..6a0f81ec3f3 100644
--- a/xlators/features/locks/src/entrylk.c
+++ b/xlators/features/locks/src/entrylk.c
@@ -334,15 +334,16 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
goto out;
}
+ lock->frame = frame;
+ lock->this = this;
+ lock->trans = trans;
+
conf = __lock_grantable (dom, basename, type);
if (conf) {
ret = -EAGAIN;
if (nonblock)
goto out;
- lock->frame = frame;
- lock->this = this;
-
list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks);
gf_log (this->name, GF_LOG_TRACE,
@@ -367,12 +368,13 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
"Blocking lock: {pinode=%p, basename=%s}",
pinode, basename);
+ ret = -EAGAIN;
goto out;
}
switch (type) {
case ENTRYLK_WRLCK:
- list_add (&lock->domain_list, &dom->entrylk_list);
+ list_add_tail (&lock->domain_list, &dom->entrylk_list);
break;
default:
@@ -414,7 +416,7 @@ __unlock_name (pl_dom_list_t *dom, const char *basename, entrylk_type type)
&& lock->type == type) {
if (type == ENTRYLK_WRLCK) {
- list_del (&lock->domain_list);
+ list_del_init (&lock->domain_list);
ret_lock = lock;
}
} else {
@@ -457,6 +459,8 @@ __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
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);
@@ -491,8 +495,6 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0);
- GF_FREE ((char *)lock->basename);
- GF_FREE (lock);
}
GF_FREE ((char *)unlocked->basename);
@@ -586,8 +588,9 @@ 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)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
+ uint64_t owner = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
void * transport = NULL;
pid_t pid = -1;
@@ -618,9 +621,10 @@ 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 (pid == 0) {
+ if (owner == 0) {
/*
this is a special case that means release
all locks from this transport
@@ -644,12 +648,19 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
}
pthread_mutex_unlock (&pinode->mutex);
+ op_errno = -ret;
if (ret < 0) {
- if (ret == -EAGAIN)
- unwind = 0;
- op_errno = -ret;
+ if (ret == -EAGAIN)
+ unwind = 0;
+ else
+ unwind = 1;
goto out;
- }
+ } else {
+ op_ret = 0;
+ op_errno = 0;
+ unwind = 1;
+ goto out;
+ }
break;
@@ -661,11 +672,11 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
}
pthread_mutex_unlock (&pinode->mutex);
- if (ret < 0) {
+ if (ret < 0)
op_errno = -ret;
- goto out;
- }
+ unwind = 1;
+ goto out;
break;
case ENTRYLK_UNLOCK:
diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c
index 592d14e0876..eaae8d4deed 100644
--- a/xlators/features/locks/src/inodelk.c
+++ b/xlators/features/locks/src/inodelk.c
@@ -130,13 +130,8 @@ static int same_inodelk_owner (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
static int
inodelk_conflict (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
- if (same_inodelk_owner (l1, l2))
- return 0;
-
- if (!inodelk_overlap (l1, l2))
- return 0;
-
- return (inodelk_type_conflict(l1, l2));
+ return (inodelk_overlap (l1, l2) &&
+ inodelk_type_conflict (l1, l2));
}
/* Determine if lock is grantable or not */
@@ -271,7 +266,8 @@ find_matching_inodelk (pl_inode_lock_t *lock, pl_dom_list_t *dom)
{
pl_inode_lock_t *l = NULL;
list_for_each_entry (l, &dom->inodelk_list, list) {
- if (inodelks_equal (l, lock))
+ if (inodelks_equal (l, lock) &&
+ same_inodelk_owner (l, lock))
return l;
}
return NULL;
@@ -582,7 +578,7 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
dom = get_domain (pinode, volume);
- if (client_pid == 0) {
+ if (owner == 0) {
/*
special case: this means release all locks
from this transport
@@ -604,6 +600,9 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
goto unwind;
}
+ reqlock->frame = frame;
+ reqlock->this = this;
+
switch (cmd) {
case F_SETLKW:
can_block = 1;
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 380e47216bd..af1ba1a4eb8 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -138,7 +138,7 @@ free_state (server_state_t *state)
int
gf_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc, fd_t *fd, pid_t pid)
+ loc_t *loc, fd_t *fd, pid_t pid, uint64_t owner)
{
int32_t ret = -1;
struct _locker *new = NULL;
@@ -162,7 +162,8 @@ gf_add_locker (struct _lock_table *table, const char *volume,
dir = IA_ISDIR (fd->inode->ia_type);
}
- new->pid = pid;
+ new->pid = pid;
+ new->owner = owner;
LOCK (&table->lock);
{
@@ -179,7 +180,7 @@ out:
int
gf_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc, fd_t *fd, pid_t pid)
+ loc_t *loc, fd_t *fd, uint64_t owner)
{
struct _locker *locker = NULL;
struct _locker *tmp = NULL;
@@ -206,13 +207,13 @@ gf_del_locker (struct _lock_table *table, const char *volume,
list_for_each_entry_safe (locker, tmp, head, lockers) {
if (locker->fd && fd &&
- (locker->fd == fd) && (locker->pid == pid)
+ (locker->fd == fd) && (locker->owner == owner)
&& !strcmp (locker->volume, volume)) {
list_move_tail (&locker->lockers, &del);
} else if (locker->loc.inode &&
loc &&
(locker->loc.inode == loc->inode) &&
- (locker->pid == pid)
+ (locker->owner == owner)
&& !strcmp (locker->volume, volume)) {
list_move_tail (&locker->lockers, &del);
}
@@ -307,11 +308,12 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
goto out;
}
/*
- pid = 0 is a special case that tells posix-locks
+ lock owner = 0 is a special case that tells posix-locks
to release all locks from this transport
*/
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->lk_owner = 0;
+ tmp_frame->root->trans = conn;
if (locker->fd) {
STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
@@ -338,8 +340,9 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
tmp_frame = copy_frame (frame);
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
+ tmp_frame->root->lk_owner = 0;
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
if (locker->fd) {
STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
@@ -560,10 +563,10 @@ server_connection_destroy (xlator_t *this, server_connection_t *conn)
tmp, &file_lockers, lockers) {
tmp_frame = copy_frame (frame);
/*
- pid = 0 is a special case that tells posix-locks
+ lock_owner = 0 is a special case that tells posix-locks
to release all locks from this transport
*/
- tmp_frame->root->pid = 0;
+ tmp_frame->root->lk_owner = 0;
tmp_frame->root->trans = conn;
if (locker->fd) {
@@ -591,7 +594,7 @@ server_connection_destroy (xlator_t *this, server_connection_t *conn)
list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
tmp_frame = copy_frame (frame);
- tmp_frame->root->pid = 0;
+ tmp_frame->root->lk_owner = 0;
tmp_frame->root->trans = conn;
if (locker->fd) {
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index 9e295cd1099..94c4d509b02 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -51,13 +51,14 @@ int32_t
gf_add_locker (struct _lock_table *table, const char *volume,
loc_t *loc,
fd_t *fd,
- pid_t pid);
+ pid_t pid,
+ uint64_t owner);
int32_t
gf_del_locker (struct _lock_table *table, const char *volume,
loc_t *loc,
fd_t *fd,
- pid_t pid);
+ uint64_t owner);
void
server_print_request (call_frame_t *frame);
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
index a35eeb166dc..62e5ef886cf 100644
--- a/xlators/protocol/server/src/server.h
+++ b/xlators/protocol/server/src/server.h
@@ -39,6 +39,7 @@ struct _locker {
char *volume;
loc_t loc;
fd_t *fd;
+ uint64_t owner;
pid_t pid;
};
diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c
index 9fbf720716b..69f37d6b370 100644
--- a/xlators/protocol/server/src/server3_1-fops.c
+++ b/xlators/protocol/server/src/server3_1-fops.c
@@ -242,10 +242,11 @@ server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
if (state->flock.l_type == F_UNLCK)
gf_del_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
+ &state->loc, NULL, frame->root->lk_owner);
else
gf_add_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
+ &state->loc, NULL, frame->root->pid,
+ frame->root->lk_owner);
} else if (op_errno != ENOSYS) {
gf_log (this->name, GF_LOG_TRACE,
"%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
@@ -283,11 +284,12 @@ server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (state->flock.l_type == F_UNLCK)
gf_del_locker (conn->ltable, state->volume,
NULL, state->fd,
- frame->root->pid);
+ frame->root->lk_owner);
else
gf_add_locker (conn->ltable, state->volume,
NULL, state->fd,
- frame->root->pid);
+ frame->root->pid,
+ frame->root->lk_owner);
} else if (op_errno != ENOSYS) {
gf_log (this->name, GF_LOG_TRACE,
"%"PRId64": FINODELK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
@@ -323,10 +325,11 @@ server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
if (state->cmd == ENTRYLK_UNLOCK)
gf_del_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
+ &state->loc, NULL, frame->root->lk_owner);
else
gf_add_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
+ &state->loc, NULL, frame->root->pid,
+ frame->root->lk_owner);
} else if (op_errno != ENOSYS) {
gf_log (this->name, GF_LOG_TRACE,
"%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
@@ -361,10 +364,11 @@ server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
if (state->cmd == ENTRYLK_UNLOCK)
gf_del_locker (conn->ltable, state->volume,
- NULL, state->fd, frame->root->pid);
+ NULL, state->fd, frame->root->lk_owner);
else
gf_add_locker (conn->ltable, state->volume,
- NULL, state->fd, frame->root->pid);
+ NULL, state->fd, frame->root->pid,
+ frame->root->lk_owner);
} else if (op_errno != ENOSYS) {
gf_log (this->name, GF_LOG_TRACE,
"%"PRId64": FENTRYLK %"PRId64" (%"PRId64") "