if (op->info.wait) {
rv = wait_event_interruptible(recv_wq, (op->done != 0)); if (rv == -ERESTARTSYS) {
spin_lock(&ops_lock); /* recheck under ops_lock if we got a done != 0, *ifsothisinterruptcaseshouldbeignored
*/ if (op->done != 0) {
spin_unlock(&ops_lock); goto do_lock_wait;
}
spin_unlock(&ops_lock);
rv = do_lock_cancel(&op->info); switch (rv) { case0: /* waiter was deleted in user space, answer will never come *removeoriginalrequest.Theoriginalrequestmustbe *onrecv_listbecausetheanswerofdo_lock_cancel() *synchronizedit.
*/
spin_lock(&ops_lock);
list_del(&op->list);
spin_unlock(&ops_lock);
rv = -EINTR; break; case -ENOENT: /* cancellation wasn't successful but op should be done */
fallthrough; default: /* internal error doing cancel we need to wait */ goto wait;
}
/* this only works for async request for now and nfs is the only *kerneluserrightnow.
*/ if (WARN_ON_ONCE(!fl->fl_lmops || !fl->fl_lmops->lm_grant)) return -EOPNOTSUPP;
ls = dlm_find_lockspace_local(lockspace); if (!ls) return -EINVAL;
rv = do_lock_cancel(&info); switch (rv) { case0:
spin_lock(&ops_lock); /* lock request to cancel must be on recv_list because *do_lock_cancel()synchronizesit.
*/
op = plock_lookup_waiter(&info); if (WARN_ON_ONCE(!op)) {
spin_unlock(&ops_lock);
rv = -ENOLCK; break;
}
list_del(&op->list);
spin_unlock(&ops_lock);
WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK);
op->data->callback(op->data->fl, -EINTR);
dlm_release_plock_op(op);
rv = -EINTR; break; case -ENOENT: /* if cancel wasn't successful we probably were to late *oritwasanon-blockinglockrequest,sojustunlockit.
*/
rv = dlm_posix_unlock(lockspace, number, file, fl); break; default: break;
}
return rv;
}
EXPORT_SYMBOL_GPL(dlm_posix_cancel);
int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, struct file_lock *fl)
{ struct dlm_ls *ls; struct plock_op *op; int rv;
ls = dlm_find_lockspace_local(lockspace); if (!ls) return -EINVAL;
op = kzalloc(sizeof(*op), GFP_NOFS); if (!op) {
rv = -ENOMEM; goto out;
}
/* a read copies out one plock request from the send list */ static ssize_t dev_read(struct file *file, char __user *u, size_t count,
loff_t *ppos)
{ struct dlm_plock_info info; struct plock_op *op = NULL;
if (count < sizeof(info)) return -EINVAL;
spin_lock(&ops_lock); if (!list_empty(&send_list)) {
op = list_first_entry(&send_list, struct plock_op, list); if (op->info.flags & DLM_PLOCK_FL_CLOSE)
list_del(&op->list); else
list_move_tail(&op->list, &recv_list);
memcpy(&info, &op->info, sizeof(info));
}
spin_unlock(&ops_lock);
if (!op) return -EAGAIN;
trace_dlm_plock_read(&info);
/* there is no need to get a reply from userspace for unlocks thatweregeneratedbythevfscleaningupforaclose
(the process did not make an unlock call). */
if (op->info.flags & DLM_PLOCK_FL_CLOSE)
dlm_release_plock_op(op);
if (copy_to_user(u, &info, sizeof(info))) return -EFAULT; returnsizeof(info);
}
/* a write copies in one plock result that should match a plock_op
on the recv list */ static ssize_t dev_write(struct file *file, constchar __user *u, size_t count,
loff_t *ppos)
{ struct plock_op *op = NULL, *iter; struct dlm_plock_info info; int do_callback = 0;
if (count != sizeof(info)) return -EINVAL;
if (copy_from_user(&info, u, sizeof(info))) return -EFAULT;
trace_dlm_plock_write(&info);
if (check_version(&info)) return -EINVAL;
/* *Theresultsforwaitingops(SETLKW)canbereturnedinany *order,somatchallfieldstofindtheop.Theresultsfor *non-waitingopsarereturnedintheorderthattheyweresent *touserspace,somatchtheresultwiththefirstnon-waitingop.
*/
spin_lock(&ops_lock); if (info.wait) {
op = plock_lookup_waiter(&info);
} else {
list_for_each_entry(iter, &recv_list, list) { if (!iter->info.wait &&
iter->info.fsid == info.fsid) {
op = iter; break;
}
}
}
if (op) { /* Sanity check that op and info match. */ if (info.wait)
WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK); else
WARN_ON(op->info.number != info.number ||
op->info.owner != info.owner ||
op->info.optype != info.optype);
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.