aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
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