diff options
-rw-r--r-- | fs/ocfs2/dlm/dlmthread.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 71302b90daf5..76526ea95bb2 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -54,6 +54,8 @@ | |||
54 | #include "cluster/masklog.h" | 54 | #include "cluster/masklog.h" |
55 | 55 | ||
56 | static int dlm_thread(void *data); | 56 | static int dlm_thread(void *data); |
57 | static void dlm_purge_lockres_now(struct dlm_ctxt *dlm, | ||
58 | struct dlm_lock_resource *lockres); | ||
57 | 59 | ||
58 | static void dlm_flush_asts(struct dlm_ctxt *dlm); | 60 | static void dlm_flush_asts(struct dlm_ctxt *dlm); |
59 | 61 | ||
@@ -111,10 +113,23 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm, | |||
111 | res->last_used = jiffies; | 113 | res->last_used = jiffies; |
112 | list_add_tail(&res->purge, &dlm->purge_list); | 114 | list_add_tail(&res->purge, &dlm->purge_list); |
113 | dlm->purge_count++; | 115 | dlm->purge_count++; |
116 | |||
117 | /* if this node is not the owner, there is | ||
118 | * no way to keep track of who the owner could be. | ||
119 | * unhash it to avoid serious problems. */ | ||
120 | if (res->owner != dlm->node_num) { | ||
121 | mlog(0, "%s:%.*s: doing immediate " | ||
122 | "purge of lockres owned by %u\n", | ||
123 | dlm->name, res->lockname.len, | ||
124 | res->lockname.name, res->owner); | ||
125 | |||
126 | dlm_purge_lockres_now(dlm, res); | ||
127 | } | ||
114 | } | 128 | } |
115 | } else if (!list_empty(&res->purge)) { | 129 | } else if (!list_empty(&res->purge)) { |
116 | mlog(0, "removing lockres %.*s from purge list\n", | 130 | mlog(0, "removing lockres %.*s from purge list, " |
117 | res->lockname.len, res->lockname.name); | 131 | "owner=%u\n", res->lockname.len, res->lockname.name, |
132 | res->owner); | ||
118 | 133 | ||
119 | list_del_init(&res->purge); | 134 | list_del_init(&res->purge); |
120 | dlm->purge_count--; | 135 | dlm->purge_count--; |
@@ -180,6 +195,24 @@ finish: | |||
180 | __dlm_unhash_lockres(lockres); | 195 | __dlm_unhash_lockres(lockres); |
181 | } | 196 | } |
182 | 197 | ||
198 | /* make an unused lockres go away immediately. | ||
199 | * as soon as the dlm spinlock is dropped, this lockres | ||
200 | * will not be found. kfree still happens on last put. */ | ||
201 | static void dlm_purge_lockres_now(struct dlm_ctxt *dlm, | ||
202 | struct dlm_lock_resource *lockres) | ||
203 | { | ||
204 | assert_spin_locked(&dlm->spinlock); | ||
205 | assert_spin_locked(&lockres->spinlock); | ||
206 | |||
207 | BUG_ON(!__dlm_lockres_unused(lockres)); | ||
208 | |||
209 | if (!list_empty(&lockres->purge)) { | ||
210 | list_del_init(&lockres->purge); | ||
211 | dlm->purge_count--; | ||
212 | } | ||
213 | __dlm_unhash_lockres(lockres); | ||
214 | } | ||
215 | |||
183 | static void dlm_run_purge_list(struct dlm_ctxt *dlm, | 216 | static void dlm_run_purge_list(struct dlm_ctxt *dlm, |
184 | int purge_now) | 217 | int purge_now) |
185 | { | 218 | { |