diff options
Diffstat (limited to 'fs/lockd/mon.c')
-rw-r--r-- | fs/lockd/mon.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index a816b920d431..e0179f8c327f 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -24,13 +24,13 @@ static struct rpc_program nsm_program; | |||
24 | /* | 24 | /* |
25 | * Local NSM state | 25 | * Local NSM state |
26 | */ | 26 | */ |
27 | u32 nsm_local_state; | 27 | int nsm_local_state; |
28 | 28 | ||
29 | /* | 29 | /* |
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,11 @@ 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.mon_name = nsm->sm_name; |
51 | args.addr = nsm->sm_addr.sin_addr.s_addr; | ||
51 | args.prog = NLM_PROGRAM; | 52 | args.prog = NLM_PROGRAM; |
52 | args.vers = host->h_version; | 53 | args.vers = 3; |
53 | args.proc = NLMPROC_NSM_NOTIFY; | 54 | args.proc = NLMPROC_NSM_NOTIFY; |
54 | memset(res, 0, sizeof(*res)); | 55 | memset(res, 0, sizeof(*res)); |
55 | 56 | ||
@@ -70,17 +71,22 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res) | |||
70 | int | 71 | int |
71 | nsm_monitor(struct nlm_host *host) | 72 | nsm_monitor(struct nlm_host *host) |
72 | { | 73 | { |
74 | struct nsm_handle *nsm = host->h_nsmhandle; | ||
73 | struct nsm_res res; | 75 | struct nsm_res res; |
74 | int status; | 76 | int status; |
75 | 77 | ||
76 | dprintk("lockd: nsm_monitor(%s)\n", host->h_name); | 78 | dprintk("lockd: nsm_monitor(%s)\n", host->h_name); |
79 | BUG_ON(nsm == NULL); | ||
77 | 80 | ||
78 | status = nsm_mon_unmon(host, SM_MON, &res); | 81 | if (nsm->sm_monitored) |
82 | return 0; | ||
83 | |||
84 | status = nsm_mon_unmon(nsm, SM_MON, &res); | ||
79 | 85 | ||
80 | if (status < 0 || res.status != 0) | 86 | if (status < 0 || res.status != 0) |
81 | printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name); | 87 | printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name); |
82 | else | 88 | else |
83 | host->h_monitored = 1; | 89 | nsm->sm_monitored = 1; |
84 | return status; | 90 | return status; |
85 | } | 91 | } |
86 | 92 | ||
@@ -90,16 +96,26 @@ nsm_monitor(struct nlm_host *host) | |||
90 | int | 96 | int |
91 | nsm_unmonitor(struct nlm_host *host) | 97 | nsm_unmonitor(struct nlm_host *host) |
92 | { | 98 | { |
99 | struct nsm_handle *nsm = host->h_nsmhandle; | ||
93 | struct nsm_res res; | 100 | struct nsm_res res; |
94 | int status; | 101 | int status = 0; |
95 | 102 | ||
96 | dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name); | 103 | if (nsm == NULL) |
97 | 104 | return 0; | |
98 | status = nsm_mon_unmon(host, SM_UNMON, &res); | 105 | host->h_nsmhandle = NULL; |
99 | if (status < 0) | 106 | |
100 | printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", host->h_name); | 107 | if (atomic_read(&nsm->sm_count) == 1 |
101 | else | 108 | && nsm->sm_monitored && !nsm->sm_sticky) { |
102 | host->h_monitored = 0; | 109 | dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name); |
110 | |||
111 | status = nsm_mon_unmon(nsm, SM_UNMON, &res); | ||
112 | if (status < 0) | ||
113 | printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", | ||
114 | host->h_name); | ||
115 | else | ||
116 | nsm->sm_monitored = 0; | ||
117 | } | ||
118 | nsm_release(nsm); | ||
103 | return status; | 119 | return status; |
104 | } | 120 | } |
105 | 121 | ||
@@ -135,7 +151,7 @@ nsm_create(void) | |||
135 | static u32 * | 151 | static u32 * |
136 | xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) | 152 | xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) |
137 | { | 153 | { |
138 | char buffer[20]; | 154 | char buffer[20], *name; |
139 | 155 | ||
140 | /* | 156 | /* |
141 | * Use the dotted-quad IP address of the remote host as | 157 | * Use the dotted-quad IP address of the remote host as |
@@ -143,8 +159,13 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) | |||
143 | * hostname first for whatever remote hostname it receives, | 159 | * hostname first for whatever remote hostname it receives, |
144 | * so this works alright. | 160 | * so this works alright. |
145 | */ | 161 | */ |
146 | sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr)); | 162 | if (nsm_use_hostnames) { |
147 | if (!(p = xdr_encode_string(p, buffer)) | 163 | name = argp->mon_name; |
164 | } else { | ||
165 | sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr)); | ||
166 | name = buffer; | ||
167 | } | ||
168 | if (!(p = xdr_encode_string(p, name)) | ||
148 | || !(p = xdr_encode_string(p, utsname()->nodename))) | 169 | || !(p = xdr_encode_string(p, utsname()->nodename))) |
149 | return ERR_PTR(-EIO); | 170 | return ERR_PTR(-EIO); |
150 | *p++ = htonl(argp->prog); | 171 | *p++ = htonl(argp->prog); |
@@ -160,9 +181,11 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) | |||
160 | p = xdr_encode_common(rqstp, p, argp); | 181 | p = xdr_encode_common(rqstp, p, argp); |
161 | if (IS_ERR(p)) | 182 | if (IS_ERR(p)) |
162 | return PTR_ERR(p); | 183 | return PTR_ERR(p); |
184 | |||
185 | /* Surprise - there may even be room for an IPv6 address now */ | ||
163 | *p++ = argp->addr; | 186 | *p++ = argp->addr; |
164 | *p++ = argp->vers; | 187 | *p++ = 0; |
165 | *p++ = argp->proto; | 188 | *p++ = 0; |
166 | *p++ = 0; | 189 | *p++ = 0; |
167 | rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); | 190 | rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); |
168 | return 0; | 191 | return 0; |