diff options
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/dlm_internal.h | 1 | ||||
-rw-r--r-- | fs/dlm/lock.c | 101 |
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 | ||
346 | struct dlm_message { | 347 | struct 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); | |||
85 | static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, | 85 | static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, |
86 | struct dlm_message *ms); | 86 | struct dlm_message *ms); |
87 | static int receive_extralen(struct dlm_message *ms); | 87 | static int receive_extralen(struct dlm_message *ms); |
88 | static 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 | ||
2991 | static void receive_purge(struct dlm_ls *ls, struct dlm_message *ms) | ||
2992 | { | ||
2993 | do_purge(ls, ms->m_nodeid, ms->m_pid); | ||
2994 | } | ||
2995 | |||
2990 | static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms) | 2996 | static 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 | ||
4275 | static 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 | |||
4315 | static 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 | |||
4330 | static 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 | |||
4346 | int 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 | |||