summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorAnand Avati <avati@gluster.com>2009-10-15 19:36:47 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-10-16 05:13:01 -0700
commitc8f39bea04c6021243d1ab2bcea450a0f067aabc (patch)
treefdfcc4c0bc7f852184476a274060c2144ad3c691 /xlators
parentd3722f7546bdcfeed7cf3c2745c1bfafa7fa79a4 (diff)
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 <avati@dev.gluster.com> 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
Diffstat (limited to 'xlators')
-rw-r--r--xlators/features/locks/src/common.c48
-rw-r--r--xlators/features/locks/src/common.h2
-rw-r--r--xlators/features/locks/src/internal.c4
-rw-r--r--xlators/features/locks/src/locks.h3
-rw-r--r--xlators/features/locks/src/posix.c1
5 files changed, 58 insertions, 0 deletions
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;