aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/svc.c')
-rw-r--r--fs/lockd/svc.c88
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);
51static unsigned int nlmsvc_users; 51static unsigned int nlmsvc_users;
52static struct task_struct *nlmsvc_task; 52static struct task_struct *nlmsvc_task;
53static struct svc_rqst *nlmsvc_rqst; 53static struct svc_rqst *nlmsvc_rqst;
54int nlmsvc_grace_period;
55unsigned long nlmsvc_timeout; 54unsigned 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
88unsigned long get_nfs_grace_period(void) 87static 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}
98EXPORT_SYMBOL(get_nfs_grace_period);
99 89
100static unsigned long set_grace_period(void) 90static 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
106static inline void clear_grace_period(void) 95static DECLARE_DELAYED_WORK(grace_period_end, grace_ender);
96
97static 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 */
210static int make_socks(struct svc_serv *serv, int proto) 201static 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 */
244int 233int lockd_up(void)
245lockd_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 /*