struct dlm_lock_result32 {
__u32 version[3];
__u32 length;
__u32 user_astaddr;
__u32 user_astparam;
__u32 user_lksb; struct dlm_lksb32 lksb;
__u8 bast_mode;
__u8 unused[3]; /* Offsets may be zero if no data is present */
__u32 lvb_offset;
};
/* Figure out if this lock is at the end of its life and no longer availablefortheapplicationtouse.Thelkbstillexistsuntil thefinalastisread.AlockbecomesEOLinthreesituations: 1.anoqueuerequestfailswithEAGAIN 2.anunlockcompleteswithEUNLOCK 3.acancelofawaitingrequestcompleteswithECANCEL/EDEADLK AnEOLlockneedstoberemovedfromtheprocess'slistoflocks. Andwecan'tallowanynewoperationonanEOLlock.Thisis notrelatedtothelifetimeofthelkbstructwhichismanaged
entirely by refcount. */
staticint lkb_is_endoflife(int mode, int status)
{ switch (status) { case -DLM_EUNLOCK: return1; case -DLM_ECANCEL: case -ETIMEDOUT: case -EDEADLK: case -EAGAIN: if (mode == DLM_LOCK_IV) return1; break;
} return0;
}
/* we could possibly check if the cancel of an orphan has resulted in the lkb
being removed and then remove that lkb from the orphans list and free it */
void dlm_user_add_ast(struct dlm_lkb *lkb, uint32_t flags, int mode, int status, uint32_t sbflags)
{ struct dlm_ls *ls; struct dlm_user_args *ua; struct dlm_user_proc *proc; struct dlm_callback *cb; int rv, copy_lvb;
if (test_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags) ||
test_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags)) return;
ls = lkb->lkb_resource->res_ls;
spin_lock_bh(&ls->ls_clear_proc_locks);
/* If ORPHAN/DEAD flag is set, it means the process is dead so an ast can'tbedelivered.ForORPHAN's,dlm_clear_proc_locks()freed lkb->uasowecan'ttrytouseit.Thissecondcheckisnecessary forcaseswhereacompletionastisreceivedforanoperationthat
began before clear_proc_locks did its cancel/unlock. */
if (test_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags) ||
test_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags)) goto out;
DLM_ASSERT(lkb->lkb_ua, dlm_print_lkb(lkb););
ua = lkb->lkb_ua;
proc = ua->proc;
if ((flags & DLM_CB_BAST) && ua->bastaddr == NULL) goto out;
if ((flags & DLM_CB_CAST) && lkb_is_endoflife(mode, status))
set_bit(DLM_IFL_ENDOFLIFE_BIT, &lkb->lkb_iflags);
error = misc_register(&ls->ls_device); if (error) {
kfree(ls->ls_device.name); /* this has to be set to NULL *toavoidadouble-freeindlm_device_deregister
*/
ls->ls_device.name = NULL;
}
fail: return error;
}
int dlm_device_deregister(struct dlm_ls *ls)
{ /* The device is not registered. This happens when the lockspace wasneverusedfromuserspace,orwhendevice_create_lockspace()
calls dlm_release_lockspace() after the register fails. */ if (!ls->ls_device.name) return0;
if (error)
dlm_release_lockspace(lockspace, 0); else
error = ls->ls_device.minor;
return error;
}
staticint device_remove_lockspace(struct dlm_lspace_params *params)
{
dlm_lockspace_t *lockspace; struct dlm_ls *ls; int error, force = 0;
if (!capable(CAP_SYS_ADMIN)) return -EPERM;
ls = dlm_find_lockspace_device(params->minor); if (!ls) return -ENOENT;
if (params->flags & DLM_USER_LSFLG_FORCEFREE)
force = 2;
lockspace = ls;
dlm_put_lockspace(ls);
/* The final dlm_release_lockspace waits for references to go to zero,soallprocesseswillneedtoclosetheirdeviceforthe lsbeforethereleasewillproceed.releasealsocallsthe device_deregisterabove.Convertingapositivereturnvalue fromreleasetozeromeansthatuserspacewon'tknowwhenits
release was the final one, but it shouldn't need to know. */
/* add 1 after namelen so that the name string is terminated */
kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1,
GFP_NOFS); if (!kbuf) {
kfree(k32buf); return -ENOMEM;
}
if (proc)
set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
/* do we really need this? can a write happen after a close? */ if ((kbuf->cmd == DLM_USER_LOCK || kbuf->cmd == DLM_USER_UNLOCK) &&
(proc && test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))) {
error = -EINVAL; goto out_free;
}
error = -EINVAL;
switch (kbuf->cmd)
{ case DLM_USER_LOCK: if (!proc) {
log_print("no locking on control device"); goto out_free;
}
error = device_user_lock(proc, &kbuf->i.lock); break;
case DLM_USER_UNLOCK: if (!proc) {
log_print("no locking on control device"); goto out_free;
}
error = device_user_unlock(proc, &kbuf->i.lock); break;
case DLM_USER_DEADLOCK: if (!proc) {
log_print("no locking on control device"); goto out_free;
}
error = device_user_deadlock(proc, &kbuf->i.lock); break;
case DLM_USER_CREATE_LOCKSPACE: if (proc) {
log_print("create/remove only on control device"); goto out_free;
}
error = device_create_lockspace(&kbuf->i.lspace); break;
case DLM_USER_REMOVE_LOCKSPACE: if (proc) {
log_print("create/remove only on control device"); goto out_free;
}
error = device_remove_lockspace(&kbuf->i.lspace); break;
case DLM_USER_PURGE: if (!proc) {
log_print("no locking on control device"); goto out_free;
}
error = device_user_purge(proc, &kbuf->i.purge); break;
/* Every process that opens the lockspace device has its own "proc" structure hangingofftheopenfilethat'susedtokeeptrackoflocksownedbythe
process and asts that need to be delivered to the process. */
/* FIXME: dlm1 provides for the user's bastparam/addr to not be updated inaconversionunlesstheconversionissuccessful.Seecode indlm_user_convert()forupdatinguafromua_tmp.OpenVMS,though, notesthatanewblockingASTaddressandparameteraresetevenif
the conversion fails, so maybe we should just do that. */
if (signal_pending(current)) {
spin_unlock_bh(&proc->asts_spin); return -ERESTARTSYS;
}
}
/* if we empty lkb_callbacks, we don't want to unlock the spinlock withoutremovinglkb_cb_list;soemptylkb_cb_listisalways
consistent with empty lkb_callbacks */
int dlm_user_daemon_available(void)
{ /* dlm_controld hasn't started (or, has started, but not
properly populated configfs) */
if (!dlm_our_nodeid()) return0;
/* This is to deal with versions of dlm_controld that don't knowaboutthemonitordevice.Weassumethatifthe dlm_controldwasstarted(above),butthemonitordevice wasneveropened,thatit'sanoldversion.dlm_controld
should open the monitor device before populating configfs. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.