xref: /linux/fs/lockd/lockd.h (revision 5829352e568d24dd04ae112128a4f44748d073bc)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
4  */
5 
6 #ifndef _LOCKD_LOCKD_H
7 #define _LOCKD_LOCKD_H
8 
9 #include <linux/exportfs.h>
10 #include <linux/in.h>
11 #include <linux/in6.h>
12 #include <net/ipv6.h>
13 #include <linux/fs.h>
14 #include <linux/kref.h>
15 #include <linux/refcount.h>
16 #include <linux/utsname.h>
17 #include "nlm.h"
18 #include <linux/lockd/bind.h>
19 #include "xdr.h"
20 #include <linux/sunrpc/debug.h>
21 #include <linux/sunrpc/svc.h>
22 
23 /*
24  * Enable lockd debugging.
25  * Requires CONFIG_SUNRPC_DEBUG.
26  */
27 #undef ifdebug
28 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
29 # define ifdebug(flag)		if (unlikely(nlm_debug & NLMDBG_##flag))
30 #else
31 # define ifdebug(flag)		if (0)
32 #endif
33 
34 #define NLMDBG_SVC		0x0001
35 #define NLMDBG_CLIENT		0x0002
36 #define NLMDBG_CLNTLOCK		0x0004
37 #define NLMDBG_SVCLOCK		0x0008
38 #define NLMDBG_MONITOR		0x0010
39 #define NLMDBG_CLNTSUBS		0x0020
40 #define NLMDBG_SVCSUBS		0x0040
41 #define NLMDBG_HOSTCACHE	0x0080
42 #define NLMDBG_XDR		0x0100
43 #define NLMDBG_ALL		0x7fff
44 
45 /*
46  * Version string
47  */
48 #define LOCKD_VERSION		"0.5"
49 
50 /*
51  * Default timeout for RPC calls (seconds)
52  */
53 #define LOCKD_DFLT_TIMEO	10
54 
55 /*
56  * Internal-use status codes, not to be placed on the wire.
57  * Version handlers translate these to appropriate wire values.
58  */
59 #define nlm__int__drop_reply	cpu_to_be32(30000)
60 #define nlm__int__deadlock	cpu_to_be32(30001)
61 #define nlm__int__stale_fh	cpu_to_be32(30002)
62 #define nlm__int__failed	cpu_to_be32(30003)
63 
64 /*
65  * Lockd host handle (used both by the client and server personality).
66  */
67 struct nlm_host {
68 	struct hlist_node	h_hash;		/* doubly linked list */
69 	struct sockaddr_storage	h_addr;		/* peer address */
70 	size_t			h_addrlen;
71 	struct sockaddr_storage	h_srcaddr;	/* our address (optional) */
72 	size_t			h_srcaddrlen;
73 	struct rpc_clnt		*h_rpcclnt;	/* RPC client to talk to peer */
74 	char			*h_name;		/* remote hostname */
75 	u32			h_version;	/* interface version */
76 	unsigned short		h_proto;	/* transport proto */
77 	unsigned short		h_reclaiming : 1,
78 				h_server     : 1, /* server side, not client side */
79 				h_noresvport : 1,
80 				h_inuse      : 1;
81 	wait_queue_head_t	h_gracewait;	/* wait while reclaiming */
82 	struct rw_semaphore	h_rwsem;	/* Reboot recovery lock */
83 	u32			h_state;	/* pseudo-state counter */
84 	u32			h_nsmstate;	/* true remote NSM state */
85 	u32			h_pidcount;	/* Pseudopids */
86 	refcount_t		h_count;	/* reference count */
87 	struct mutex		h_mutex;	/* mutex for pmap binding */
88 	unsigned long		h_nextrebind;	/* next portmap call */
89 	unsigned long		h_expires;	/* eligible for GC */
90 	struct list_head	h_lockowners;	/* Lockowners for the client */
91 	spinlock_t		h_lock;
92 	struct list_head	h_granted;	/* Locks in GRANTED state */
93 	struct list_head	h_reclaim;	/* Locks in RECLAIM state */
94 	struct nsm_handle	*h_nsmhandle;	/* NSM status handle */
95 	char			*h_addrbuf;	/* address eyecatcher */
96 	struct net		*net;		/* host net */
97 	const struct cred	*h_cred;
98 	char			nodename[UNX_MAXNODENAME + 1];
99 	const struct nlmclnt_operations	*h_nlmclnt_ops;	/* Callback ops for NLM users */
100 };
101 
102 /*
103  * The largest string sm_addrbuf should hold is a full-size IPv6 address
104  * (no "::" anywhere) with a scope ID.  The buffer size is computed to
105  * hold eight groups of colon-separated four-hex-digit numbers, a
106  * percent sign, a scope id (at most 32 bits, in decimal), and NUL.
107  */
108 #define NSM_ADDRBUF		((8 * 4 + 7) + (1 + 10) + 1)
109 
110 struct nsm_handle {
111 	struct list_head	sm_link;
112 	refcount_t		sm_count;
113 	char			*sm_mon_name;
114 	char			*sm_name;
115 	struct sockaddr_storage	sm_addr;
116 	size_t			sm_addrlen;
117 	unsigned int		sm_monitored : 1,
118 				sm_sticky : 1;	/* don't unmonitor */
119 	struct nsm_private	sm_priv;
120 	char			sm_addrbuf[NSM_ADDRBUF];
121 };
122 
123 /*
124  * Rigorous type checking on sockaddr type conversions
125  */
126 static inline struct sockaddr *nlm_addr(const struct nlm_host *host)
127 {
128 	return (struct sockaddr *)&host->h_addr;
129 }
130 
131 static inline struct sockaddr *nlm_srcaddr(const struct nlm_host *host)
132 {
133 	return (struct sockaddr *)&host->h_srcaddr;
134 }
135 
136 /*
137  * Map an fl_owner_t into a unique 32-bit "pid"
138  */
139 struct nlm_lockowner {
140 	struct list_head list;
141 	refcount_t count;
142 
143 	struct nlm_host *host;
144 	fl_owner_t owner;
145 	uint32_t pid;
146 };
147 
148 /*
149  * This is the representation of a blocked client lock.
150  */
151 struct nlm_wait {
152 	struct list_head	b_list;		/* linked list */
153 	wait_queue_head_t	b_wait;		/* where to wait on */
154 	struct nlm_host		*b_host;
155 	struct file_lock	*b_lock;	/* local file lock */
156 	__be32			b_status;	/* grant callback status */
157 };
158 
159 /*
160  * Memory chunk for NLM client RPC request.
161  */
162 #define NLMCLNT_OHSIZE		((__NEW_UTS_LEN) + 10u)
163 struct nlm_rqst {
164 	refcount_t		a_count;
165 	unsigned int		a_flags;	/* initial RPC task flags */
166 	struct nlm_host *	a_host;		/* host handle */
167 	struct nlm_args		a_args;		/* arguments */
168 	struct nlm_res		a_res;		/* result */
169 	struct nlm_block *	a_block;
170 	unsigned int		a_retries;	/* Retry count */
171 	u8			a_owner[NLMCLNT_OHSIZE];
172 	void *	a_callback_data; /* sent to nlmclnt_operations callbacks */
173 };
174 
175 struct nlm_share;
176 
177 /*
178  * This struct describes a file held open by lockd on behalf of
179  * an NFS client.
180  */
181 struct nlm_file {
182 	struct hlist_node	f_list;		/* linked list */
183 	struct nfs_fh		f_handle;	/* NFS file handle */
184 	struct file *		f_file[2];	/* VFS file pointers,
185 						   indexed by O_ flags */
186 	struct nlm_share *	f_shares;	/* DOS shares */
187 	struct list_head	f_blocks;	/* blocked locks */
188 	unsigned int		f_locks;	/* guesstimate # of locks */
189 	unsigned int		f_count;	/* reference count */
190 	struct mutex		f_mutex;	/* avoid concurrent access */
191 };
192 
193 /*
194  * This is a server block (i.e. a lock requested by some client which
195  * couldn't be granted because of a conflicting lock).
196  */
197 #define NLM_NEVER		(~(unsigned long) 0)
198 /* timeout on non-blocking call: */
199 #define NLM_TIMEOUT		(7 * HZ)
200 
201 struct nlm_block {
202 	struct kref		b_count;	/* Reference count */
203 	struct list_head	b_list;		/* linked list of all blocks */
204 	struct list_head	b_flist;	/* linked list (per file) */
205 	struct nlm_rqst	*	b_call;		/* RPC args & callback info */
206 	struct svc_serv *	b_daemon;	/* NLM service */
207 	struct nlm_host *	b_host;		/* host handle for RPC clnt */
208 	unsigned long		b_when;		/* next re-xmit */
209 	unsigned int		b_id;		/* block id */
210 	unsigned char		b_granted;	/* VFS granted lock */
211 	struct nlm_file *	b_file;		/* file in question */
212 	struct cache_req *	b_cache_req;	/* deferred request handling */
213 	struct cache_deferred_req * b_deferred_req;
214 	unsigned int		b_flags;	/* block flags */
215 #define B_QUEUED		1	/* lock queued */
216 #define B_GOT_CALLBACK		2	/* got lock or conflicting lock */
217 #define B_TIMED_OUT		4	/* filesystem too slow to respond */
218 };
219 
220 /*
221  * Global variables
222  */
223 extern const struct rpc_program	nlm_program;
224 extern const struct svc_procedure nlmsvc_procedures[24];
225 #ifdef CONFIG_LOCKD_V4
226 extern const struct svc_procedure nlmsvc_procedures4[24];
227 #endif
228 extern int			nlmsvc_grace_period;
229 extern unsigned long		nlm_timeout;
230 extern bool			nsm_use_hostnames;
231 extern u32			nsm_local_state;
232 
233 extern struct timer_list	nlmsvc_retry;
234 
235 /*
236  * Lockd client functions
237  */
238 struct nlm_rqst * nlm_alloc_call(struct nlm_host *host);
239 int		  nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
240 int		  nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
241 void		  nlmclnt_release_call(struct nlm_rqst *);
242 void		  nlmclnt_prepare_block(struct nlm_wait *block, struct nlm_host *host,
243 					struct file_lock *fl);
244 void		  nlmclnt_queue_block(struct nlm_wait *block);
245 __be32		  nlmclnt_dequeue_block(struct nlm_wait *block);
246 int		  nlmclnt_wait(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
247 __be32		  nlmclnt_grant(const struct sockaddr *addr,
248 				const struct nlm_lock *lock);
249 void		  nlmclnt_recovery(struct nlm_host *);
250 int		  nlmclnt_reclaim(struct nlm_host *, struct file_lock *,
251 				  struct nlm_rqst *);
252 void		  nlmclnt_next_cookie(struct nlm_cookie *);
253 
254 #ifdef CONFIG_LOCKD_V4
255 extern const struct rpc_version nlm_version4;
256 #endif
257 
258 /*
259  * Host cache
260  */
261 struct nlm_host  *nlmclnt_lookup_host(const struct sockaddr *sap,
262 					const size_t salen,
263 					const unsigned short protocol,
264 					const u32 version,
265 					const char *hostname,
266 					int noresvport,
267 					struct net *net,
268 					const struct cred *cred);
269 void		  nlmclnt_release_host(struct nlm_host *);
270 struct nlm_host  *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
271 					const char *hostname,
272 					const size_t hostname_len);
273 void		  nlmsvc_release_host(struct nlm_host *);
274 struct rpc_clnt * nlm_bind_host(struct nlm_host *);
275 void		  nlm_rebind_host(struct nlm_host *);
276 struct nlm_host * nlm_get_host(struct nlm_host *);
277 void		  nlm_shutdown_hosts(void);
278 void		  nlm_shutdown_hosts_net(struct net *net);
279 void		  nlm_host_rebooted(const struct net *net,
280 					const struct nlm_reboot *);
281 
282 /*
283  * Host monitoring
284  */
285 int		  nsm_monitor(const struct nlm_host *host);
286 void		  nsm_unmonitor(const struct nlm_host *host);
287 
288 struct nsm_handle *nsm_get_handle(const struct net *net,
289 					const struct sockaddr *sap,
290 					const size_t salen,
291 					const char *hostname,
292 					const size_t hostname_len);
293 struct nsm_handle *nsm_reboot_lookup(const struct net *net,
294 					const struct nlm_reboot *info);
295 void		  nsm_release(struct nsm_handle *nsm);
296 
297 /*
298  * This is used in garbage collection and resource reclaim
299  * A return value != 0 means destroy the lock/block/share
300  */
301 typedef int	  (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
302 
303 /*
304  * Server-side lock handling
305  */
306 int		  lock_to_openmode(struct file_lock *);
307 __be32		  nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
308 			      struct nlm_host *, struct nlm_lock *, int,
309 			      struct nlm_cookie *, int);
310 __be32		  nlmsvc_unlock(struct net *net, struct nlm_file *, struct nlm_lock *);
311 __be32		  nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
312 			struct nlm_host *host, struct nlm_lock *lock,
313 			struct nlm_lock *conflock);
314 __be32		  nlmsvc_cancel_blocked(struct net *net, struct nlm_file *, struct nlm_lock *);
315 void		  nlmsvc_retry_blocked(struct svc_rqst *rqstp);
316 void		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
317 					nlm_host_match_fn_t match);
318 void		  nlmsvc_grant_reply(struct nlm_cookie *, __be32);
319 void		  nlmsvc_release_call(struct nlm_rqst *);
320 void		  nlmsvc_locks_init_private(struct file_lock *, struct nlm_host *, pid_t);
321 
322 /*
323  * File handling for the server personality
324  */
325 __be32		  nlm_lookup_file(struct svc_rqst *, struct nlm_file **,
326 					struct nlm_lock *);
327 void		  nlm_release_file(struct nlm_file *);
328 void		  nlmsvc_put_lockowner(struct nlm_lockowner *);
329 void		  nlmsvc_release_lockowner(struct nlm_lock *);
330 void		  nlmsvc_mark_resources(struct net *);
331 void		  nlmsvc_free_host_resources(struct nlm_host *);
332 void		  nlmsvc_invalidate_all(void);
333 
334 static inline struct file *nlmsvc_file_file(const struct nlm_file *file)
335 {
336 	return file->f_file[O_RDONLY] ?
337 	       file->f_file[O_RDONLY] : file->f_file[O_WRONLY];
338 }
339 
340 static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
341 {
342 	return file_inode(nlmsvc_file_file(file));
343 }
344 
345 static inline bool
346 nlmsvc_file_cannot_lock(const struct nlm_file *file)
347 {
348 	return exportfs_cannot_lock(nlmsvc_file_file(file)->f_path.dentry->d_sb->s_export_op);
349 }
350 
351 static inline int __nlm_privileged_request4(const struct sockaddr *sap)
352 {
353 	const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
354 
355 	if (ntohs(sin->sin_port) > 1023)
356 		return 0;
357 
358 	return ipv4_is_loopback(sin->sin_addr.s_addr);
359 }
360 
361 #if IS_ENABLED(CONFIG_IPV6)
362 static inline int __nlm_privileged_request6(const struct sockaddr *sap)
363 {
364 	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
365 
366 	if (ntohs(sin6->sin6_port) > 1023)
367 		return 0;
368 
369 	if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED)
370 		return ipv4_is_loopback(sin6->sin6_addr.s6_addr32[3]);
371 
372 	return ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK;
373 }
374 #else	/* IS_ENABLED(CONFIG_IPV6) */
375 static inline int __nlm_privileged_request6(const struct sockaddr *sap)
376 {
377 	return 0;
378 }
379 #endif	/* IS_ENABLED(CONFIG_IPV6) */
380 
381 /*
382  * Ensure incoming requests are from local privileged callers.
383  *
384  * Return TRUE if sender is local and is connecting via a privileged port;
385  * otherwise return FALSE.
386  */
387 static inline int nlm_privileged_requester(const struct svc_rqst *rqstp)
388 {
389 	const struct sockaddr *sap = svc_addr(rqstp);
390 
391 	switch (sap->sa_family) {
392 	case AF_INET:
393 		return __nlm_privileged_request4(sap);
394 	case AF_INET6:
395 		return __nlm_privileged_request6(sap);
396 	default:
397 		return 0;
398 	}
399 }
400 
401 /*
402  * Compare two NLM locks.
403  * When the second lock is of type F_UNLCK, this acts like a wildcard.
404  */
405 static inline int nlm_compare_locks(const struct file_lock *fl1,
406 				    const struct file_lock *fl2)
407 {
408 	return file_inode(fl1->c.flc_file) == file_inode(fl2->c.flc_file)
409 	     && fl1->c.flc_pid   == fl2->c.flc_pid
410 	     && fl1->c.flc_owner == fl2->c.flc_owner
411 	     && fl1->fl_start == fl2->fl_start
412 	     && fl1->fl_end   == fl2->fl_end
413 	     &&(fl1->c.flc_type  == fl2->c.flc_type || fl2->c.flc_type == F_UNLCK);
414 }
415 
416 extern const struct lock_manager_operations nlmsvc_lock_operations;
417 
418 #endif /* _LOCKD_LOCKD_H */
419