summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-04-11 10:34:59 +0000
committerdfr <dfr@FreeBSD.org>2008-04-11 10:34:59 +0000
commit5dd963773ae028c909b38502e98d913b021614d9 (patch)
tree755cc6a0efa107e37096fd3acafbfaac5fd229f5
parent8facfb056964e9008f5d249e71fe0ccbe88fb62a (diff)
downloadFreeBSD-src-5dd963773ae028c909b38502e98d913b021614d9.zip
FreeBSD-src-5dd963773ae028c909b38502e98d913b021614d9.tar.gz
Fix some issues that showed up during Kris' testing.
Reported by: kris MFC after: 3 days
-rw-r--r--sys/nlm/nlm_prot_impl.c42
-rw-r--r--sys/rpc/clnt_rc.c10
2 files changed, 36 insertions, 16 deletions
diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c
index 2b89827..626fa02 100644
--- a/sys/nlm/nlm_prot_impl.c
+++ b/sys/nlm/nlm_prot_impl.c
@@ -161,6 +161,11 @@ TAILQ_HEAD(nlm_async_lock_list, nlm_async_lock);
/*
* NLM host.
*/
+enum nlm_host_state {
+ NLM_UNMONITORED,
+ NLM_MONITORED,
+ NLM_MONITOR_FAILED
+};
struct nlm_host {
struct mtx nh_lock;
TAILQ_ENTRY(nlm_host) nh_link; /* (s) global list of hosts */
@@ -171,7 +176,7 @@ struct nlm_host {
CLIENT *nh_rpc; /* (s) RPC handle to send to host */
rpcvers_t nh_vers; /* (s) NLM version of host */
int nh_state; /* (s) last seen NSM state of host */
- bool_t nh_monitored; /* (s) TRUE if local NSM is monitoring */
+ enum nlm_host_state nh_monstate; /* (s) local NSM monitoring state */
time_t nh_idle_timeout; /* (s) Time at which host is idle */
struct sysctl_ctx_list nh_sysctl; /* (c) vfs.nlm.sysid nodes */
struct nlm_async_lock_list nh_pending; /* (l) pending async locks */
@@ -607,7 +612,7 @@ nlm_create_host(const char* caller_name)
host->nh_rpc = NULL;
host->nh_vers = 0;
host->nh_state = 0;
- host->nh_monitored = FALSE;
+ host->nh_monstate = NLM_UNMONITORED;
TAILQ_INIT(&host->nh_pending);
TAILQ_INIT(&host->nh_finished);
TAILQ_INSERT_TAIL(&nlm_hosts, host, nh_link);
@@ -621,7 +626,7 @@ nlm_create_host(const char* caller_name)
SYSCTL_ADD_INT(&host->nh_sysctl, SYSCTL_CHILDREN(oid), OID_AUTO,
"version", CTLFLAG_RD, &host->nh_vers, 0, "");
SYSCTL_ADD_INT(&host->nh_sysctl, SYSCTL_CHILDREN(oid), OID_AUTO,
- "monitored", CTLFLAG_RD, &host->nh_monitored, 0, "");
+ "monitored", CTLFLAG_RD, &host->nh_monstate, 0, "");
SYSCTL_ADD_PROC(&host->nh_sysctl, SYSCTL_CHILDREN(oid), OID_AUTO,
"lock_count", CTLTYPE_INT | CTLFLAG_RD, host, 0,
nlm_host_lock_count_sysctl, "I", "");
@@ -679,7 +684,7 @@ nlm_check_idle(void)
nlm_next_idle_check = time_uptime + NLM_IDLE_PERIOD;
TAILQ_FOREACH(host, &nlm_hosts, nh_link) {
- if (host->nh_monitored
+ if (host->nh_monstate == NLM_MONITORED
&& time_uptime > host->nh_idle_timeout) {
if (lf_countlocks(host->nh_sysid) > 0) {
host->nh_idle_timeout =
@@ -861,7 +866,7 @@ nlm_host_unmonitor(struct nlm_host *host)
return;
}
- host->nh_monitored = FALSE;
+ host->nh_monstate = NLM_UNMONITORED;
}
/*
@@ -896,7 +901,7 @@ nlm_host_monitor(struct nlm_host *host, int state)
host->nh_caller_name, host->nh_sysid, state);
}
- if (host->nh_monitored)
+ if (host->nh_monstate != NLM_UNMONITORED)
return;
if (nlm_debug_level >= 1)
@@ -928,10 +933,11 @@ nlm_host_monitor(struct nlm_host *host, int state)
if (smstat.res_stat == stat_fail) {
printf("Local NSM refuses to monitor %s\n",
host->nh_caller_name);
+ host->nh_monstate = NLM_MONITOR_FAILED;
return;
}
- host->nh_monitored = TRUE;
+ host->nh_monstate = NLM_MONITORED;
}
/*
@@ -1265,6 +1271,7 @@ struct vfs_state {
struct mount *vs_mp;
struct vnode *vs_vp;
int vs_vfslocked;
+ int vs_vnlocked;
};
static int
@@ -1296,6 +1303,7 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp,
error = VFS_FHTOVP(vs->vs_mp, &fhp->fh_fid, &vs->vs_vp);
if (error)
goto out;
+ vs->vs_vnlocked = TRUE;
cred = crget();
freecred = TRUE;
@@ -1308,11 +1316,6 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp,
cred = credanon;
freecred = FALSE;
}
-#if __FreeBSD_version < 800011
- VOP_UNLOCK(vs->vs_vp, 0, curthread);
-#else
- VOP_UNLOCK(vs->vs_vp, 0);
-#endif
/*
* Check cred.
@@ -1321,6 +1324,13 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp,
if (error)
goto out;
+#if __FreeBSD_version < 800011
+ VOP_UNLOCK(vs->vs_vp, 0, curthread);
+#else
+ VOP_UNLOCK(vs->vs_vp, 0);
+#endif
+ vs->vs_vnlocked = FALSE;
+
out:
if (freecred)
crfree(cred);
@@ -1332,8 +1342,12 @@ static void
nlm_release_vfs_state(struct vfs_state *vs)
{
- if (vs->vs_vp)
- vrele(vs->vs_vp);
+ if (vs->vs_vp) {
+ if (vs->vs_vnlocked)
+ vput(vs->vs_vp);
+ else
+ vrele(vs->vs_vp);
+ }
if (vs->vs_mp)
vfs_rel(vs->vs_mp);
VFS_UNLOCK_GIANT(vs->vs_vfslocked);
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c
index ab93773..8b5fc26 100644
--- a/sys/rpc/clnt_rc.c
+++ b/sys/rpc/clnt_rc.c
@@ -139,6 +139,9 @@ clnt_reconnect_connect(CLIENT *cl)
(struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers,
rc->rc_sendsz, rc->rc_recvsz);
+ if (!rc->rc_client)
+ return (rpc_createerr.cf_stat);
+
CLNT_CONTROL(rc->rc_client, CLSET_FD_CLOSE, 0);
CLNT_CONTROL(rc->rc_client, CLSET_CONNECT, &one);
CLNT_CONTROL(rc->rc_client, CLSET_TIMEOUT, &rc->rc_timeout);
@@ -163,8 +166,11 @@ clnt_reconnect_call(
enum clnt_stat stat;
do {
- if (!rc->rc_client)
- clnt_reconnect_connect(cl);
+ if (!rc->rc_client) {
+ stat = clnt_reconnect_connect(cl);
+ if (stat != RPC_SUCCESS)
+ return (stat);
+ }
stat = CLNT_CALL(rc->rc_client, proc, xargs, argsp,
xresults, resultsp, utimeout);
OpenPOWER on IntegriCloud