diff options
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/mon.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index e27981403fbe..626b6c116a6d 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -30,7 +30,7 @@ u32 nsm_local_state; | |||
30 | * Common procedure for SM_MON/SM_UNMON calls | 30 | * Common procedure for SM_MON/SM_UNMON calls |
31 | */ | 31 | */ |
32 | static int | 32 | static int |
33 | nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res) | 33 | nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res) |
34 | { | 34 | { |
35 | struct rpc_clnt *clnt; | 35 | struct rpc_clnt *clnt; |
36 | int status; | 36 | int status; |
@@ -46,10 +46,10 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res) | |||
46 | goto out; | 46 | goto out; |
47 | } | 47 | } |
48 | 48 | ||
49 | args.addr = host->h_addr.sin_addr.s_addr; | 49 | memset(&args, 0, sizeof(args)); |
50 | args.proto= (host->h_proto<<1) | host->h_server; | 50 | args.addr = nsm->sm_addr.sin_addr.s_addr; |
51 | args.prog = NLM_PROGRAM; | 51 | args.prog = NLM_PROGRAM; |
52 | args.vers = host->h_version; | 52 | args.vers = 3; |
53 | args.proc = NLMPROC_NSM_NOTIFY; | 53 | args.proc = NLMPROC_NSM_NOTIFY; |
54 | memset(res, 0, sizeof(*res)); | 54 | memset(res, 0, sizeof(*res)); |
55 | 55 | ||
@@ -80,7 +80,7 @@ nsm_monitor(struct nlm_host *host) | |||
80 | if (nsm->sm_monitored) | 80 | if (nsm->sm_monitored) |
81 | return 0; | 81 | return 0; |
82 | 82 | ||
83 | status = nsm_mon_unmon(host, SM_MON, &res); | 83 | status = nsm_mon_unmon(nsm, SM_MON, &res); |
84 | 84 | ||
85 | if (status < 0 || res.status != 0) | 85 | if (status < 0 || res.status != 0) |
86 | printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name); | 86 | printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name); |
@@ -99,16 +99,20 @@ nsm_unmonitor(struct nlm_host *host) | |||
99 | struct nsm_res res; | 99 | struct nsm_res res; |
100 | int status = 0; | 100 | int status = 0; |
101 | 101 | ||
102 | dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name); | ||
103 | if (nsm == NULL) | 102 | if (nsm == NULL) |
104 | return 0; | 103 | return 0; |
105 | host->h_nsmhandle = NULL; | 104 | host->h_nsmhandle = NULL; |
106 | 105 | ||
107 | if (!host->h_killed) { | 106 | if (atomic_read(&nsm->sm_count) == 1 |
108 | status = nsm_mon_unmon(host, SM_UNMON, &res); | 107 | && nsm->sm_monitored && !nsm->sm_sticky) { |
108 | dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name); | ||
109 | |||
110 | status = nsm_mon_unmon(nsm, SM_UNMON, &res); | ||
109 | if (status < 0) | 111 | if (status < 0) |
110 | printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", host->h_name); | 112 | printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", |
111 | nsm->sm_monitored = 0; | 113 | host->h_name); |
114 | else | ||
115 | nsm->sm_monitored = 0; | ||
112 | } | 116 | } |
113 | nsm_release(nsm); | 117 | nsm_release(nsm); |
114 | return status; | 118 | return status; |
@@ -171,9 +175,11 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) | |||
171 | p = xdr_encode_common(rqstp, p, argp); | 175 | p = xdr_encode_common(rqstp, p, argp); |
172 | if (IS_ERR(p)) | 176 | if (IS_ERR(p)) |
173 | return PTR_ERR(p); | 177 | return PTR_ERR(p); |
178 | |||
179 | /* Surprise - there may even be room for an IPv6 address now */ | ||
174 | *p++ = argp->addr; | 180 | *p++ = argp->addr; |
175 | *p++ = argp->vers; | 181 | *p++ = 0; |
176 | *p++ = argp->proto; | 182 | *p++ = 0; |
177 | *p++ = 0; | 183 | *p++ = 0; |
178 | rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); | 184 | rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); |
179 | return 0; | 185 | return 0; |