aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2007-03-30 16:02:40 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-05-01 04:11:10 -0400
commit8499137d4ef1829281e04838113b6b09a0bf1269 (patch)
tree9083983db5099f0a4764194aabc27f81342f13ea /fs/dlm
parent7e4dac33594468153c38b5c94d8ebcafb0e0a68d (diff)
[DLM] add orphan purging code (1/2)
Add code for purging orphan locks. A process can also purge all of its own non-orphan locks by passing a pid of zero. Code already exists for processes to create persistent locks that become orphans when the process exits, but the complimentary capability for another process to then purge these orphans has been missing. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/dlm_internal.h1
-rw-r--r--fs/dlm/lock.c101
2 files changed, 102 insertions, 0 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 178931cca67c..30994d68f6a0 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -342,6 +342,7 @@ struct dlm_header {
342#define DLM_MSG_LOOKUP 11 342#define DLM_MSG_LOOKUP 11
343#define DLM_MSG_REMOVE 12 343#define DLM_MSG_REMOVE 12
344#define DLM_MSG_LOOKUP_REPLY 13 344#define DLM_MSG_LOOKUP_REPLY 13
345#define DLM_MSG_PURGE 14
345 346
346struct dlm_message { 347struct dlm_message {
347 struct dlm_header m_header; 348 struct dlm_header m_header;
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 7807958846c5..9d26b3a39671 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -85,6 +85,7 @@ static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
85static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, 85static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
86 struct dlm_message *ms); 86 struct dlm_message *ms);
87static int receive_extralen(struct dlm_message *ms); 87static int receive_extralen(struct dlm_message *ms);
88static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
88 89
89/* 90/*
90 * Lock compatibilty matrix - thanks Steve 91 * Lock compatibilty matrix - thanks Steve
@@ -2987,6 +2988,11 @@ static void receive_remove(struct dlm_ls *ls, struct dlm_message *ms)
2987 dlm_dir_remove_entry(ls, from_nodeid, ms->m_extra, len); 2988 dlm_dir_remove_entry(ls, from_nodeid, ms->m_extra, len);
2988} 2989}
2989 2990
2991static void receive_purge(struct dlm_ls *ls, struct dlm_message *ms)
2992{
2993 do_purge(ls, ms->m_nodeid, ms->m_pid);
2994}
2995
2990static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms) 2996static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
2991{ 2997{
2992 struct dlm_lkb *lkb; 2998 struct dlm_lkb *lkb;
@@ -3409,6 +3415,12 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
3409 receive_lookup_reply(ls, ms); 3415 receive_lookup_reply(ls, ms);
3410 break; 3416 break;
3411 3417
3418 /* other messages */
3419
3420 case DLM_MSG_PURGE:
3421 receive_purge(ls, ms);
3422 break;
3423
3412 default: 3424 default:
3413 log_error(ls, "unknown message type %d", ms->m_type); 3425 log_error(ls, "unknown message type %d", ms->m_type);
3414 } 3426 }
@@ -4260,3 +4272,92 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
4260 unlock_recovery(ls); 4272 unlock_recovery(ls);
4261} 4273}
4262 4274
4275static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
4276{
4277 struct dlm_lkb *lkb, *safe;
4278
4279 while (1) {
4280 lkb = NULL;
4281 spin_lock(&proc->locks_spin);
4282 if (!list_empty(&proc->locks)) {
4283 lkb = list_entry(proc->locks.next, struct dlm_lkb,
4284 lkb_ownqueue);
4285 list_del_init(&lkb->lkb_ownqueue);
4286 }
4287 spin_unlock(&proc->locks_spin);
4288
4289 if (!lkb)
4290 break;
4291
4292 lkb->lkb_flags |= DLM_IFL_DEAD;
4293 unlock_proc_lock(ls, lkb);
4294 dlm_put_lkb(lkb); /* ref from proc->locks list */
4295 }
4296
4297 spin_lock(&proc->locks_spin);
4298 list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
4299 list_del_init(&lkb->lkb_ownqueue);
4300 lkb->lkb_flags |= DLM_IFL_DEAD;
4301 dlm_put_lkb(lkb);
4302 }
4303 spin_unlock(&proc->locks_spin);
4304
4305 spin_lock(&proc->asts_spin);
4306 list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
4307 list_del(&lkb->lkb_astqueue);
4308 dlm_put_lkb(lkb);
4309 }
4310 spin_unlock(&proc->asts_spin);
4311}
4312
4313/* pid of 0 means purge all orphans */
4314
4315static void do_purge(struct dlm_ls *ls, int nodeid, int pid)
4316{
4317 struct dlm_lkb *lkb, *safe;
4318
4319 mutex_lock(&ls->ls_orphans_mutex);
4320 list_for_each_entry_safe(lkb, safe, &ls->ls_orphans, lkb_ownqueue) {
4321 if (pid && lkb->lkb_ownpid != pid)
4322 continue;
4323 unlock_proc_lock(ls, lkb);
4324 list_del_init(&lkb->lkb_ownqueue);
4325 dlm_put_lkb(lkb);
4326 }
4327 mutex_unlock(&ls->ls_orphans_mutex);
4328}
4329
4330static int send_purge(struct dlm_ls *ls, int nodeid, int pid)
4331{
4332 struct dlm_message *ms;
4333 struct dlm_mhandle *mh;
4334 int error;
4335
4336 error = _create_message(ls, sizeof(struct dlm_message), nodeid,
4337 DLM_MSG_PURGE, &ms, &mh);
4338 if (error)
4339 return error;
4340 ms->m_nodeid = nodeid;
4341 ms->m_pid = pid;
4342
4343 return send_message(mh, ms);
4344}
4345
4346int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
4347 int nodeid, int pid)
4348{
4349 int error = 0;
4350
4351 if (nodeid != dlm_our_nodeid()) {
4352 error = send_purge(ls, nodeid, pid);
4353 } else {
4354 lock_recovery(ls);
4355 if (pid == current->pid)
4356 purge_proc_locks(ls, proc);
4357 else
4358 do_purge(ls, nodeid, pid);
4359 unlock_recovery(ls);
4360 }
4361 return error;
4362}
4363