diff options
Diffstat (limited to 'fs/lockd/svc.c')
-rw-r--r-- | fs/lockd/svc.c | 88 |
1 files changed, 37 insertions, 51 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 5bd9bf0fa9df..c631a83931ce 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -51,7 +51,6 @@ static DEFINE_MUTEX(nlmsvc_mutex); | |||
51 | static unsigned int nlmsvc_users; | 51 | static unsigned int nlmsvc_users; |
52 | static struct task_struct *nlmsvc_task; | 52 | static struct task_struct *nlmsvc_task; |
53 | static struct svc_rqst *nlmsvc_rqst; | 53 | static struct svc_rqst *nlmsvc_rqst; |
54 | int nlmsvc_grace_period; | ||
55 | unsigned long nlmsvc_timeout; | 54 | unsigned long nlmsvc_timeout; |
56 | 55 | ||
57 | /* | 56 | /* |
@@ -85,27 +84,23 @@ static unsigned long get_lockd_grace_period(void) | |||
85 | return nlm_timeout * 5 * HZ; | 84 | return nlm_timeout * 5 * HZ; |
86 | } | 85 | } |
87 | 86 | ||
88 | unsigned long get_nfs_grace_period(void) | 87 | static struct lock_manager lockd_manager = { |
89 | { | 88 | }; |
90 | unsigned long lockdgrace = get_lockd_grace_period(); | ||
91 | unsigned long nfsdgrace = 0; | ||
92 | |||
93 | if (nlmsvc_ops) | ||
94 | nfsdgrace = nlmsvc_ops->get_grace_period(); | ||
95 | |||
96 | return max(lockdgrace, nfsdgrace); | ||
97 | } | ||
98 | EXPORT_SYMBOL(get_nfs_grace_period); | ||
99 | 89 | ||
100 | static unsigned long set_grace_period(void) | 90 | static void grace_ender(struct work_struct *not_used) |
101 | { | 91 | { |
102 | nlmsvc_grace_period = 1; | 92 | locks_end_grace(&lockd_manager); |
103 | return get_nfs_grace_period() + jiffies; | ||
104 | } | 93 | } |
105 | 94 | ||
106 | static inline void clear_grace_period(void) | 95 | static DECLARE_DELAYED_WORK(grace_period_end, grace_ender); |
96 | |||
97 | static void set_grace_period(void) | ||
107 | { | 98 | { |
108 | nlmsvc_grace_period = 0; | 99 | unsigned long grace_period = get_lockd_grace_period(); |
100 | |||
101 | locks_start_grace(&lockd_manager); | ||
102 | cancel_delayed_work_sync(&grace_period_end); | ||
103 | schedule_delayed_work(&grace_period_end, grace_period); | ||
109 | } | 104 | } |
110 | 105 | ||
111 | /* | 106 | /* |
@@ -116,7 +111,6 @@ lockd(void *vrqstp) | |||
116 | { | 111 | { |
117 | int err = 0, preverr = 0; | 112 | int err = 0, preverr = 0; |
118 | struct svc_rqst *rqstp = vrqstp; | 113 | struct svc_rqst *rqstp = vrqstp; |
119 | unsigned long grace_period_expire; | ||
120 | 114 | ||
121 | /* try_to_freeze() is called from svc_recv() */ | 115 | /* try_to_freeze() is called from svc_recv() */ |
122 | set_freezable(); | 116 | set_freezable(); |
@@ -139,7 +133,7 @@ lockd(void *vrqstp) | |||
139 | nlm_timeout = LOCKD_DFLT_TIMEO; | 133 | nlm_timeout = LOCKD_DFLT_TIMEO; |
140 | nlmsvc_timeout = nlm_timeout * HZ; | 134 | nlmsvc_timeout = nlm_timeout * HZ; |
141 | 135 | ||
142 | grace_period_expire = set_grace_period(); | 136 | set_grace_period(); |
143 | 137 | ||
144 | /* | 138 | /* |
145 | * The main request loop. We don't terminate until the last | 139 | * The main request loop. We don't terminate until the last |
@@ -153,21 +147,12 @@ lockd(void *vrqstp) | |||
153 | flush_signals(current); | 147 | flush_signals(current); |
154 | if (nlmsvc_ops) { | 148 | if (nlmsvc_ops) { |
155 | nlmsvc_invalidate_all(); | 149 | nlmsvc_invalidate_all(); |
156 | grace_period_expire = set_grace_period(); | 150 | set_grace_period(); |
157 | } | 151 | } |
158 | continue; | 152 | continue; |
159 | } | 153 | } |
160 | 154 | ||
161 | /* | 155 | timeout = nlmsvc_retry_blocked(); |
162 | * Retry any blocked locks that have been notified by | ||
163 | * the VFS. Don't do this during grace period. | ||
164 | * (Theoretically, there shouldn't even be blocked locks | ||
165 | * during grace period). | ||
166 | */ | ||
167 | if (!nlmsvc_grace_period) { | ||
168 | timeout = nlmsvc_retry_blocked(); | ||
169 | } else if (time_before(grace_period_expire, jiffies)) | ||
170 | clear_grace_period(); | ||
171 | 156 | ||
172 | /* | 157 | /* |
173 | * Find a socket with data available and call its | 158 | * Find a socket with data available and call its |
@@ -195,6 +180,7 @@ lockd(void *vrqstp) | |||
195 | svc_process(rqstp); | 180 | svc_process(rqstp); |
196 | } | 181 | } |
197 | flush_signals(current); | 182 | flush_signals(current); |
183 | cancel_delayed_work_sync(&grace_period_end); | ||
198 | if (nlmsvc_ops) | 184 | if (nlmsvc_ops) |
199 | nlmsvc_invalidate_all(); | 185 | nlmsvc_invalidate_all(); |
200 | nlm_shutdown_hosts(); | 186 | nlm_shutdown_hosts(); |
@@ -203,25 +189,28 @@ lockd(void *vrqstp) | |||
203 | } | 189 | } |
204 | 190 | ||
205 | /* | 191 | /* |
206 | * Make any sockets that are needed but not present. | 192 | * Ensure there are active UDP and TCP listeners for lockd. |
207 | * If nlm_udpport or nlm_tcpport were set as module | 193 | * |
208 | * options, make those sockets unconditionally | 194 | * Even if we have only TCP NFS mounts and/or TCP NFSDs, some |
195 | * local services (such as rpc.statd) still require UDP, and | ||
196 | * some NFS servers do not yet support NLM over TCP. | ||
197 | * | ||
198 | * Returns zero if all listeners are available; otherwise a | ||
199 | * negative errno value is returned. | ||
209 | */ | 200 | */ |
210 | static int make_socks(struct svc_serv *serv, int proto) | 201 | static int make_socks(struct svc_serv *serv) |
211 | { | 202 | { |
212 | static int warned; | 203 | static int warned; |
213 | struct svc_xprt *xprt; | 204 | struct svc_xprt *xprt; |
214 | int err = 0; | 205 | int err = 0; |
215 | 206 | ||
216 | if (proto == IPPROTO_UDP || nlm_udpport) { | 207 | xprt = svc_find_xprt(serv, "udp", 0, 0); |
217 | xprt = svc_find_xprt(serv, "udp", 0, 0); | 208 | if (!xprt) |
218 | if (!xprt) | 209 | err = svc_create_xprt(serv, "udp", nlm_udpport, |
219 | err = svc_create_xprt(serv, "udp", nlm_udpport, | 210 | SVC_SOCK_DEFAULTS); |
220 | SVC_SOCK_DEFAULTS); | 211 | else |
221 | else | 212 | svc_xprt_put(xprt); |
222 | svc_xprt_put(xprt); | 213 | if (err >= 0) { |
223 | } | ||
224 | if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) { | ||
225 | xprt = svc_find_xprt(serv, "tcp", 0, 0); | 214 | xprt = svc_find_xprt(serv, "tcp", 0, 0); |
226 | if (!xprt) | 215 | if (!xprt) |
227 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, | 216 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, |
@@ -241,8 +230,7 @@ static int make_socks(struct svc_serv *serv, int proto) | |||
241 | /* | 230 | /* |
242 | * Bring up the lockd process if it's not already up. | 231 | * Bring up the lockd process if it's not already up. |
243 | */ | 232 | */ |
244 | int | 233 | int lockd_up(void) |
245 | lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | ||
246 | { | 234 | { |
247 | struct svc_serv *serv; | 235 | struct svc_serv *serv; |
248 | int error = 0; | 236 | int error = 0; |
@@ -251,11 +239,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
251 | /* | 239 | /* |
252 | * Check whether we're already up and running. | 240 | * Check whether we're already up and running. |
253 | */ | 241 | */ |
254 | if (nlmsvc_rqst) { | 242 | if (nlmsvc_rqst) |
255 | if (proto) | ||
256 | error = make_socks(nlmsvc_rqst->rq_server, proto); | ||
257 | goto out; | 243 | goto out; |
258 | } | ||
259 | 244 | ||
260 | /* | 245 | /* |
261 | * Sanity check: if there's no pid, | 246 | * Sanity check: if there's no pid, |
@@ -266,13 +251,14 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
266 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 251 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
267 | 252 | ||
268 | error = -ENOMEM; | 253 | error = -ENOMEM; |
269 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); | 254 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, AF_INET, NULL); |
270 | if (!serv) { | 255 | if (!serv) { |
271 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 256 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
272 | goto out; | 257 | goto out; |
273 | } | 258 | } |
274 | 259 | ||
275 | if ((error = make_socks(serv, proto)) < 0) | 260 | error = make_socks(serv); |
261 | if (error < 0) | ||
276 | goto destroy_and_out; | 262 | goto destroy_and_out; |
277 | 263 | ||
278 | /* | 264 | /* |