From c8f39bea04c6021243d1ab2bcea450a0f067aabc Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Thu, 15 Oct 2009 19:36:47 +0000 Subject: locks: keep ref on the inode while locks are held keeping refs on the inode while there are held locks prevents the inode from getting pruned away Signed-off-by: Anand V. Avati BUG: 112 (parallel deletion of files mounted by different clients on the same back-end hangs and/or does not completely delete) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=112 --- xlators/features/locks/src/common.c | 48 +++++++++++++++++++++++++++++++++++ xlators/features/locks/src/common.h | 2 ++ xlators/features/locks/src/internal.c | 4 +++ xlators/features/locks/src/locks.h | 3 +++ xlators/features/locks/src/posix.c | 1 + 5 files changed, 58 insertions(+) diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index 5f115f6fa..11841e92d 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -35,6 +35,7 @@ #include "common-utils.h" #include "locks.h" +#include "common.h" static int @@ -48,6 +49,53 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock, ? &pl_inode->ext_list \ : &pl_inode->int_list) + +int +__pl_inode_is_empty (pl_inode_t *pl_inode) +{ + int is_empty = 1; + + if (!list_empty (&pl_inode->ext_list)) + is_empty = 0; + + if (!list_empty (&pl_inode->int_list)) + is_empty = 0; + + if (!list_empty (&pl_inode->dir_list)) + is_empty = 0; + + return is_empty; +} + +void +pl_update_refkeeper (xlator_t *this, inode_t *inode) +{ + pl_inode_t *pl_inode = NULL; + int is_empty = 0; + int need_unref = 0; + + pl_inode = pl_inode_get (this, inode); + + pthread_mutex_lock (&pl_inode->mutex); + { + is_empty = __pl_inode_is_empty (pl_inode); + + if (is_empty && pl_inode->refkeeper) { + need_unref = 1; + pl_inode->refkeeper = NULL; + } + + if (!is_empty && !pl_inode->refkeeper) { + pl_inode->refkeeper = inode_ref (inode); + } + } + pthread_mutex_unlock (&pl_inode->mutex); + + if (need_unref) + inode_unref (inode); +} + + pl_inode_t * pl_inode_get (xlator_t *this, inode_t *inode) { diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index 06f104f52..78de8432f 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -49,4 +49,6 @@ void __delete_lock (pl_inode_t *, posix_lock_t *); void __destroy_lock (posix_lock_t *); +void pl_update_refkeeper (xlator_t *this, inode_t *inode); + #endif /* __COMMON_H__ */ diff --git a/xlators/features/locks/src/internal.c b/xlators/features/locks/src/internal.c index 1c1220931..487826587 100644 --- a/xlators/features/locks/src/internal.c +++ b/xlators/features/locks/src/internal.c @@ -191,6 +191,7 @@ pl_inodelk (call_frame_t *frame, xlator_t *this, op_ret = 0; unwind: + pl_update_refkeeper (this, loc->inode); STACK_UNWIND (frame, op_ret, op_errno); out: return 0; @@ -293,6 +294,7 @@ pl_finodelk (call_frame_t *frame, xlator_t *this, op_ret = 0; unwind: + pl_update_refkeeper (this, fd->inode); STACK_UNWIND (frame, op_ret, op_errno); out: return 0; @@ -782,6 +784,7 @@ pl_entrylk (call_frame_t *frame, xlator_t *this, op_ret = 0; out: + pl_update_refkeeper (this, loc->inode); if (unwind) { STACK_UNWIND (frame, op_ret, op_errno); } @@ -888,6 +891,7 @@ pl_fentrylk (call_frame_t *frame, xlator_t *this, op_ret = 0; out: + pl_update_refkeeper (this, fd->inode); if (unwind) { STACK_UNWIND (frame, op_ret, op_errno); } diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index 65da3a365..fe1333504 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -89,6 +89,9 @@ struct __pl_inode { struct list_head int_list; /* list of internal locks */ struct list_head rw_list; /* list of waiting r/w requests */ int mandatory; /* if mandatory locking is enabled */ + + inode_t *refkeeper; /* hold refs on an inode while locks are + held to prevent pruning */ }; typedef struct __pl_inode pl_inode_t; diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index f963d5c93..b1eb7e435 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -687,6 +687,7 @@ pl_lk (call_frame_t *frame, xlator_t *this, } unwind: + pl_update_refkeeper (this, fd->inode); STACK_UNWIND (frame, op_ret, op_errno, flock); out: return 0; -- cgit