dprintk("lockd: call procedure %d on %s\n",
(int)proc, host->h_name);
do { if (host->h_reclaiming && !argp->reclaim) goto in_grace_period;
/* If we have no RPC client yet, create one. */ if ((clnt = nlm_bind_host(host)) == NULL) return -ENOLCK;
msg.rpc_proc = &clnt->cl_procinfo[proc];
/* Perform the RPC call. If an error occurs, try again */ if ((status = rpc_call_sync(clnt, &msg, 0)) < 0) {
dprintk("lockd: rpc_call returned error %d\n", -status); switch (status) { case -EPROTONOSUPPORT:
status = -EINVAL; break; case -ECONNREFUSED: case -ETIMEDOUT: case -ENOTCONN:
nlm_rebind_host(host);
status = -EAGAIN; break; case -ERESTARTSYS: return signalled () ? -EINTR : status; default: break;
} break;
} else if (resp->status == nlm_lck_denied_grace_period) {
dprintk("lockd: server in grace period\n"); if (argp->reclaim) {
printk(KERN_WARNING "lockd: spurious grace period reject?!\n"); return -ENOLCK;
}
} else { if (!argp->reclaim) { /* We appear to be out of the grace period */
wake_up_all(&host->h_gracewait);
}
dprintk("lockd: server returns status %d\n",
ntohl(resp->status)); return0; /* Okay, call complete */
}
in_grace_period: /* *Theserverhasrebootedandappearstobeinthegrace *periodduringwhichlocksareonlyallowedtobe *reclaimed. *Wecanonlybackoffandtryagainlater.
*/
status = nlm_wait_on_grace(&host->h_gracewait);
} while (status == 0);
/* *AGRANTEDcallbackcancomeatanytime--evenbeforethereply *totheLOCKrequestarrives,sowequeuethewaitbefore *requestingthelock.
*/
nlmclnt_queue_block(&block); for (;;) { /* Reboot protection */
fl->fl_u.nfs_fl.state = host->h_state;
status = nlmclnt_call(cred, req, NLMPROC_LOCK); if (status < 0) break; /* Did a reclaimer thread notify us of a server reboot? */ if (resp->status == nlm_lck_denied_grace_period) continue; if (resp->status != nlm_lck_blocked) break; /* Wait on an NLM blocking lock */
status = nlmclnt_wait(&block, req, NLMCLNT_POLL_TIMEOUT); if (status < 0) break; if (block.b_status != nlm_lck_blocked) break;
}
b_status = nlmclnt_dequeue_block(&block); if (resp->status == nlm_lck_blocked)
resp->status = b_status;
/* if we were interrupted while blocking, then cancel the lock request *andexit
*/ if (resp->status == nlm_lck_blocked) { if (!req->a_args.block) goto out_unlock; if (nlmclnt_cancel(host, req->a_args.block, fl) == 0) goto out;
}
if (resp->status == nlm_granted) {
down_read(&host->h_rwsem); /* Check whether or not the server has rebooted */ if (fl->fl_u.nfs_fl.state != host->h_state) {
up_read(&host->h_rwsem); goto again;
} /* Ensure the resulting lock will get added to granted list */
fl->c.flc_flags |= FL_SLEEP; if (do_vfs_lock(fl) < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__);
up_read(&host->h_rwsem);
fl->c.flc_flags = flags;
status = 0;
} if (status < 0) goto out_unlock; /* *EAGAINdoesn'tmakesenseforsleepinglocks,andinsome *casesNLM_LCK_DENIEDisreturnedforapermanenterror.So *turnitintoanENOLCK.
*/ if (resp->status == nlm_lck_denied && (flags & FL_SLEEP))
status = -ENOLCK; else
status = nlm_stat_to_errno(resp->status);
out:
trace_nlmclnt_lock(&req->a_args.lock,
(conststruct sockaddr *)&req->a_host->h_addr,
req->a_host->h_addrlen, req->a_res.status);
nlmclnt_release_call(req); return status;
out_unlock: /* Fatal error: ensure that we remove the lock altogether */
trace_nlmclnt_lock(&req->a_args.lock,
(conststruct sockaddr *)&req->a_host->h_addr,
req->a_host->h_addrlen, req->a_res.status);
dprintk("lockd: lock attempt ended in fatal error.\n" " Attempting to unlock.\n");
type = fl->c.flc_type;
fl->c.flc_type = F_UNLCK;
down_read(&host->h_rwsem);
do_vfs_lock(fl);
up_read(&host->h_rwsem);
fl->c.flc_type = type;
fl->c.flc_flags = flags;
nlmclnt_async_call(cred, req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops); return status;
}
/* *RECLAIM:Trytoreclaimalock
*/ int
nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl, struct nlm_rqst *req)
{ int status;
/* *Note:theserverissupposedtoeithergrantustheunlock *request,ortodenyitwithNLM_LCK_DENIED_GRACE_PERIOD.Ineither *case,wewanttounlock.
*/
fl->c.flc_flags |= FL_EXISTS;
down_read(&host->h_rwsem);
status = do_vfs_lock(fl);
up_read(&host->h_rwsem);
fl->c.flc_flags = flags; if (status == -ENOENT) {
status = 0; goto out;
}
refcount_inc(&req->a_count);
status = nlmclnt_async_call(nfs_file_cred(fl->c.flc_file), req,
NLMPROC_UNLOCK, &nlmclnt_unlock_ops); if (status < 0) goto out;
if (resp->status == nlm_granted) goto out;
if (resp->status != nlm_lck_denied_nolocks)
printk("lockd: unexpected unlock status: %d\n",
ntohl(resp->status)); /* What to do now? I'm out of my depth... */
status = -ENOLCK;
out:
trace_nlmclnt_unlock(&req->a_args.lock,
(conststruct sockaddr *)&req->a_host->h_addr,
req->a_host->h_addrlen, req->a_res.status);
nlmclnt_release_call(req); return status;
}
switch (status) { case NLM_LCK_GRANTED: case NLM_LCK_DENIED_GRACE_PERIOD: case NLM_LCK_DENIED: /* Everything's good */ break; case NLM_LCK_DENIED_NOLOCKS:
dprintk("lockd: CANCEL failed (server has no locks)\n"); goto retry_cancel; default:
printk(KERN_NOTICE "lockd: weird return %d for CANCEL call\n",
status);
}
die: return;
retry_cancel: /* Don't ever retry more than 3 times */ if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) goto die;
nlm_rebind_host(req->a_host);
rpc_restart_call(task);
rpc_delay(task, 30 * HZ);
}
/* *ConvertanNLMstatuscodetoagenerickernelerrno
*/ staticint
nlm_stat_to_errno(__be32 status)
{ switch(ntohl(status)) { case NLM_LCK_GRANTED: return0; case NLM_LCK_DENIED: return -EAGAIN; case NLM_LCK_DENIED_NOLOCKS: case NLM_LCK_DENIED_GRACE_PERIOD: return -ENOLCK; case NLM_LCK_BLOCKED:
printk(KERN_NOTICE "lockd: unexpected status NLM_BLOCKED\n"); return -ENOLCK; #ifdef CONFIG_LOCKD_V4 case NLM_DEADLCK: return -EDEADLK; case NLM_ROFS: return -EROFS; case NLM_STALE_FH: return -ESTALE; case NLM_FBIG: return -EOVERFLOW; case NLM_FAILED: return -ENOLCK; #endif
}
printk(KERN_NOTICE "lockd: unexpected server status %d\n",
ntohl(status)); return -ENOLCK;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-09-29)
¤
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.