From 9e38b5066d42d47f1011e1d1bc32ed9c41df57ec Mon Sep 17 00:00:00 2001 From: Pavan Sondur Date: Sun, 6 Dec 2009 13:29:08 +0000 Subject: features/locks: Implement release xlator callback. This patch solves the lock bailout problem seen recently when autoconf tools were run. This is a workaround, where 'flock' locks are removed in pl_release, if an explicit UNLCK call does not come. The complete fix would be to allow 'fcntl' and 'flock' locks to operate in different domains. Signed-off-by: Pavan Vilas Sondur Signed-off-by: Anand V. Avati BUG: 449 (Handle flock calls in a different domain from fcntl calls) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=449 --- xlators/features/locks/src/common.c | 11 +++++++--- xlators/features/locks/src/common.h | 3 +++ xlators/features/locks/src/locks.h | 2 +- xlators/features/locks/src/posix.c | 42 +++++++++++++++++++++++++++++++------ 4 files changed, 48 insertions(+), 10 deletions(-) (limited to 'xlators/features/locks/src') diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index 7cbf45958a8..d82e47aa36f 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -96,6 +96,11 @@ found: return dom; } +unsigned long +fd_to_fdnum (fd_t *fd) +{ + return ((unsigned long) fd); +} int __pl_inode_is_empty (pl_inode_t *pl_inode) @@ -444,7 +449,7 @@ new_posix_lock (struct flock *flock, transport_t *transport, pid_t client_pid, lock->fl_end = flock->l_start + flock->l_len - 1; lock->transport = transport; - lock->fd = fd; + lock->fd_num = fd_to_fdnum (fd); lock->client_pid = client_pid; lock->owner = owner; @@ -688,7 +693,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock) sum->fl_type = lock->fl_type; sum->transport = lock->transport; - sum->fd = lock->fd; + sum->fd_num = lock->fd_num; sum->client_pid = lock->client_pid; sum->owner = lock->owner; @@ -704,7 +709,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock) sum->fl_type = conf->fl_type; sum->transport = conf->transport; - sum->fd = conf->fd; + sum->fd_num = conf->fd_num; sum->client_pid = conf->client_pid; sum->owner = conf->owner; diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index 32c27c7d198..46da9e78cb1 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -110,4 +110,7 @@ pl_print_locker (char *str, int size, xlator_t *this, call_frame_t *frame); void pl_print_inodelk (char *str, int size, int cmd, struct flock *flock, const char *domain); +unsigned long +fd_to_fdnum (fd_t *fd); + #endif /* __COMMON_H__ */ diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index 7dc8e2d4f93..e89092811a6 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -42,7 +42,7 @@ struct __posix_lock { short blocked; /* waiting to acquire */ struct flock user_flock; /* the flock supplied by the user */ xlator_t *this; /* required for blocked locks */ - fd_t *fd; + unsigned long fd_num; call_frame_t *frame; diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 4a1a2a76376..d4e1b152f48 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -248,7 +248,7 @@ delete_locks_of_fd (xlator_t *this, pl_inode_t *pl_inode, fd_t *fd) { list_for_each_entry_safe (l, tmp, &pl_inode->ext_list, list) { - if ((l->fd == fd)) { + if ((l->fd_num == fd_to_fdnum(fd))) { if (l->blocked) { list_move_tail (&l->list, &blocked_list); continue; @@ -368,6 +368,14 @@ int pl_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd) { + int dummy = 1; + int ret = -1; + + ret = fd_ctx_set (fd, this, dummy); + if (ret != 0) + gf_log (this->name, GF_LOG_DEBUG, + "fd_ctx_set failed"); + STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd); return 0; @@ -517,7 +525,7 @@ pl_readv (call_frame_t *frame, xlator_t *this, region.fl_start = offset; region.fl_end = offset + size - 1; region.transport = frame->root->trans; - region.fd = fd; + region.fd_num = fd_to_fdnum(fd); region.client_pid = frame->root->pid; region.owner = frame->root->lk_owner; @@ -614,7 +622,7 @@ pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, region.fl_start = offset; region.fl_end = offset + iov_length (vector, count) - 1; region.transport = frame->root->trans; - region.fd = fd; + region.fd_num = fd_to_fdnum(fd); region.client_pid = frame->root->pid; region.owner = frame->root->lk_owner; @@ -736,9 +744,9 @@ pl_lk (call_frame_t *frame, xlator_t *this, #endif case F_SETLKW: can_block = 1; - reqlock->frame = frame; - reqlock->this = this; - reqlock->fd = fd; + reqlock->frame = frame; + reqlock->this = this; + reqlock->fd_num = fd_to_fdnum(fd); /* fall through */ @@ -859,6 +867,27 @@ pl_forget (xlator_t *this, return 0; } +int +pl_release (xlator_t *this, fd_t *fd) +{ + pl_inode_t *pl_inode = NULL; + uint64_t tmp_pl_inode = 0; + int ret = -1; + + ret = inode_ctx_get (fd->inode, this, &tmp_pl_inode); + if (ret != 0) + goto out; + + pl_inode = (pl_inode_t *)(long)tmp_pl_inode; + + gf_log (this->name, GF_LOG_TRACE, + "Releasing all locks with fd %p", fd); + + delete_locks_of_fd (this, pl_inode, fd); + +out: + return ret; +} static int32_t __get_posixlk_count (xlator_t *this, pl_inode_t *pl_inode) { @@ -1420,6 +1449,7 @@ struct xlator_dumpops dumpops = { struct xlator_cbks cbks = { .forget = pl_forget, + .release = pl_release, }; -- cgit