summaryrefslogtreecommitdiffstats
path: root/xlators/features
diff options
context:
space:
mode:
authorAnand Avati <avati@gluster.com>2009-10-16 09:12:57 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-10-16 08:04:31 -0700
commit7bf78408ffec1efbceed17ed2e540d7d0af19763 (patch)
tree98a1c9b8ae048867242932ac00054fd4728c45d2 /xlators/features
parent5d423ab4548c941921c1e64135fec6e15c7787f2 (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: 315 (generation number support) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=315
Diffstat (limited to 'xlators/features')
-rw-r--r--xlators/features/locks/src/common.c53
-rw-r--r--xlators/features/locks/src/common.h2
-rw-r--r--xlators/features/locks/src/entrylk.c1
-rw-r--r--xlators/features/locks/src/inodelk.c1
-rw-r--r--xlators/features/locks/src/locks.h15
-rw-r--r--xlators/features/locks/src/posix.c1
6 files changed, 66 insertions, 7 deletions
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c
index 08dc451..b903768 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
@@ -43,7 +44,7 @@ static void
__insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock);
static pl_dom_list_t *
-allocate_domain(const char *volume)
+allocate_domain (const char *volume)
{
pl_dom_list_t *dom = NULL;
@@ -95,6 +96,56 @@ found:
return dom;
}
+
+int
+__pl_inode_is_empty (pl_inode_t *pl_inode)
+{
+ pl_dom_list_t *dom = NULL;
+ int is_empty = 1;
+
+ if (!list_empty (&pl_inode->ext_list))
+ is_empty = 0;
+
+ list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
+ if (!list_empty (&dom->entrylk_list))
+ is_empty = 0;
+
+ if (!list_empty (&dom->inodelk_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 fabe8bd..59201c9 100644
--- a/xlators/features/locks/src/common.h
+++ b/xlators/features/locks/src/common.h
@@ -65,4 +65,6 @@ void
grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
pl_entry_lock_t *unlocked, pl_dom_list_t *dom);
+void pl_update_refkeeper (xlator_t *this, inode_t *inode);
+
#endif /* __COMMON_H__ */
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c
index f1536f8..e22a830 100644
--- a/xlators/features/locks/src/entrylk.c
+++ b/xlators/features/locks/src/entrylk.c
@@ -534,6 +534,7 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
op_ret = 0;
out:
+ pl_update_refkeeper (this, inode);
if (unwind) {
STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
}
diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c
index 4c76f64..1cb2c95 100644
--- a/xlators/features/locks/src/inodelk.c
+++ b/xlators/features/locks/src/inodelk.c
@@ -525,6 +525,7 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
op_ret = 0;
unwind:
+ pl_update_refkeeper (this, inode);
STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
out:
return 0;
diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h
index 4ad16c7..9d030f1 100644
--- a/xlators/features/locks/src/locks.h
+++ b/xlators/features/locks/src/locks.h
@@ -86,12 +86,12 @@ struct __pl_rw_req_t {
typedef struct __pl_rw_req_t pl_rw_req_t;
struct __pl_dom_list_t {
- const char *domain;
- struct list_head inode_list; /* list_head back to pl_inode_t */
- struct list_head entrylk_list; /* List of entry locks */
- struct list_head blocked_entrylks; /* List of all blocked entrylks */
- struct list_head inodelk_list; /* List of inode locks */
- struct list_head blocked_inodelks; /* List of all blocked inodelks */
+ struct list_head inode_list; /* list_head back to pl_inode_t */
+ const char *domain;
+ struct list_head entrylk_list; /* List of entry locks */
+ struct list_head blocked_entrylks; /* List of all blocked entrylks */
+ struct list_head inodelk_list; /* List of inode locks */
+ struct list_head blocked_inodelks; /* List of all blocked inodelks */
};
typedef struct __pl_dom_list_t pl_dom_list_t;
@@ -123,6 +123,9 @@ struct __pl_inode {
struct list_head ext_list; /* list of fcntl 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 f2e73b9..50958a2 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -686,6 +686,7 @@ pl_lk (call_frame_t *frame, xlator_t *this,
}
unwind:
+ pl_update_refkeeper (this, fd->inode);
STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, flock);
out:
return 0;