diff options
author | Pavan Sondur <pavan@gluster.com> | 2010-08-22 14:09:48 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-08-22 22:27:49 -0700 |
commit | 0d33cce6f7bbb71abe0086469f2f726151b0e62c (patch) | |
tree | 74192cf39d8963889a4f37182d2bed229e99d347 | |
parent | 63f9e2a49573a0b539c0082fd0c08c1b4d4db983 (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.c | 45 | ||||
-rw-r--r-- | xlators/features/locks/src/inodelk.c | 17 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 29 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-helpers.h | 5 | ||||
-rw-r--r-- | xlators/protocol/server/src/server.h | 1 | ||||
-rw-r--r-- | xlators/protocol/server/src/server3_1-fops.c | 20 |
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") " |