summaryrefslogtreecommitdiff
path: root/fs/lockd/host.c
diff options
context:
space:
mode:
authorOlaf Kirch <okir@suse.de>2006-10-04 02:15:55 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 07:55:17 -0700
commit5c8dd29ca7fc7483690cef4306549742d534f2a2 (patch)
treeedf51e354535448ea6b57a59358d9f28c556684c /fs/lockd/host.c
parentf0737a39a64a9df32bb045c54e1cdf6cecdcbdd7 (diff)
downloadlwn-5c8dd29ca7fc7483690cef4306549742d534f2a2.tar.gz
lwn-5c8dd29ca7fc7483690cef4306549742d534f2a2.zip
[PATCH] knfsd: lockd: Make nlm_host_rebooted use the nsm_handle
This patch makes the SM_NOTIFY handling understand and use the nsm_handle. To make it a bit clear what is happening: nlmclent_prepare_reclaim and nlmclnt_finish_reclaim get open-coded into 'reclaimer' The result is tidied up. Then some of that functionality is moved out into nlm_host_rebooted (which calls nlmclnt_recovery which starts a thread which runs reclaimer). Also host_rebooted now finds an nsm_handle rather than a host, then then iterates over all hosts and deals with each host that shares that nsm_handle. Signed-off-by: Olaf Kirch <okir@suse.de> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/lockd/host.c')
-rw-r--r--fs/lockd/host.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 4990223a3e18..3cd96e2e1256 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -290,28 +290,57 @@ void nlm_release_host(struct nlm_host *host)
* has rebooted.
* Release all resources held by that peer.
*/
-void nlm_host_rebooted(const struct sockaddr_in *sin, const struct nlm_reboot *argp)
+void nlm_host_rebooted(const struct sockaddr_in *sin,
+ const char *hostname, int hostname_len,
+ u32 new_state)
{
- struct nlm_host *host;
- int server;
+ struct nsm_handle *nsm;
+ struct nlm_host *host, **hp;
+ int hash;
- /* Obtain the host pointer for this NFS server and try to
- * reclaim all locks we hold on this server.
- */
- server = (argp->proto & 1)? 1 : 0;
- host = nlm_lookup_host(server, sin, argp->proto >> 1, argp->vers,
- argp->mon, argp->len);
- if (host == NULL)
+ dprintk("lockd: nlm_host_rebooted(%s, %u.%u.%u.%u)\n",
+ hostname, NIPQUAD(sin->sin_addr));
+
+ /* Find the NSM handle for this peer */
+ if (!(nsm = __nsm_find(sin, hostname, hostname_len, 0)))
return;
- if (server == 0) {
- /* We are client, he's the server: try to reclaim all locks. */
- nlmclnt_recovery(host, argp->state);
- } else {
- /* He's the client, we're the server: delete all locks held by the client */
- nlmsvc_free_host_resources(host);
+ /* When reclaiming locks on this peer, make sure that
+ * we set up a new notification */
+ nsm->sm_monitored = 0;
+
+ /* Mark all hosts tied to this NSM state as having rebooted.
+ * We run the loop repeatedly, because we drop the host table
+ * lock for this.
+ * To avoid processing a host several times, we match the nsmstate.
+ */
+again: mutex_lock(&nlm_host_mutex);
+ for (hash = 0; hash < NLM_HOST_NRHASH; hash++) {
+ for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) {
+ if (host->h_nsmhandle == nsm
+ && host->h_nsmstate != new_state) {
+ host->h_nsmstate = new_state;
+ host->h_state++;
+
+ nlm_get_host(host);
+ mutex_unlock(&nlm_host_mutex);
+
+ if (host->h_server) {
+ /* We're server for this guy, just ditch
+ * all the locks he held. */
+ nlmsvc_free_host_resources(host);
+ } else {
+ /* He's the server, initiate lock recovery. */
+ nlmclnt_recovery(host);
+ }
+
+ nlm_release_host(host);
+ goto again;
+ }
+ }
}
- nlm_release_host(host);
+
+ mutex_unlock(&nlm_host_mutex);
}
/*