xref: /dragonfly/sys/sys/devfs.h (revision 7d3e9a5b)
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Alex Hornung <ahornung@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #ifndef _SYS_DEVFS_H_
35 #define	_SYS_DEVFS_H_
36 
37 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
38 
39 #ifndef _SYS_TYPES_H_
40 #include <sys/types.h>
41 #endif
42 #ifndef _SYS_QUEUE_H_
43 #include <sys/queue.h>
44 #endif
45 #ifdef _KERNEL
46 #ifndef _SYS_LOCK_H_
47 #include <sys/lock.h>
48 #endif
49 #ifndef _SYS_CONF_H_
50 #include <sys/conf.h>
51 #endif
52 #ifndef _SYS_MSGPORT_H_
53 #include <sys/msgport.h>
54 #endif
55 #endif	/* _KERNEL */
56 #ifndef _SYS_DIRENT_H_
57 #include <sys/dirent.h>
58 #endif
59 #ifndef _SYS_DEVICE_H_
60 #include <sys/device.h>
61 #endif
62 #ifdef _KERNEL
63 #ifndef _SYS_UCRED_H_
64 #include <sys/ucred.h>
65 #endif
66 #endif	/* _KERNEL */
67 
68 
69 typedef enum {
70 	Nroot,		/* the filesystem root */
71 	Nlink,
72 	Nreg,
73 	Ndir,
74 	Ndev
75 } devfs_nodetype;
76 
77 struct devfs_dirent {
78 	ino_t		d_ino;		/* file number of entry */
79 	uint16_t	d_namlen;	/* strlen(d_name) */
80 	uint8_t		d_type;		/* file type */
81 	char		*d_name;
82 };
83 
84 struct devfs_fid {
85 	uint16_t	fid_len;	/* Length of structure. */
86 	uint16_t	fid_pad;	/* Force 32-bit alignment. */
87 	uint32_t	fid_gen;
88 	ino_t		fid_ino;	/* File number (ino). */
89 };
90 
91 struct devfs_node {
92 	cdev_t		d_dev;		/* device associated with this node */
93 
94 	struct mount 	*mp;		/* mount point of this node */
95 	struct devfs_dirent d_dir;	/* dirent data (name, inode, ...) */
96 	struct vnode 	*v_node;	/* associated vnode */
97 	struct devfs_node *parent;	/* parent of this node */
98 	devfs_nodetype	node_type;	/* devfs node type */
99 
100 	u_int64_t	refs;		/* currently unused */
101 	size_t		nchildren;	/* number of children of a parent */
102 	u_int64_t	cookie_jar;	/* cookie pool for children */
103 	u_int64_t	cookie;		/* directory entry cookie for readdir */
104 
105 	struct devfs_node *link_target;	/* target of this autolink-type node */
106 	size_t		nlinks;		/* hard links */
107 
108 	char		*symlink_name;	/* symlink name for readlink */
109 	size_t		symlink_namelen; /* symlink name length for readlink */
110 
111 	u_short		mode;		/* files access mode and type */
112 	uid_t		uid;		/* owner user id */
113 	gid_t		gid;		/* owner group id */
114 	u_long		flags;
115 
116 	struct timespec	atime;		/* time of last access */
117 	struct timespec	mtime;		/* time of last modification */
118 	struct timespec	ctime;		/* time file changed */
119 
120 	TAILQ_ENTRY(devfs_node) link;
121 	TAILQ_HEAD(, devfs_node) list;	/* linked list of children */
122 };
123 
124 #ifdef _KERNEL
125 struct devfs_orphan {
126 	struct devfs_node *node;
127 	TAILQ_ENTRY(devfs_orphan) link;
128 };
129 
130 struct devfs_mnt_data {
131 	TAILQ_HEAD(, devfs_orphan) orphan_list;
132 	TAILQ_ENTRY(devfs_mnt_data) link;
133 
134 	struct devfs_node *root_node;
135 	struct mount	*mp;
136 	uint32_t	mnt_type;
137 	long		leak_count;
138 	long		file_count;
139 	int		jailed;
140 	size_t		mntonnamelen;
141 };
142 
143 struct devfs_clone_handler {
144 	char		*name;
145 	u_char		namlen;
146 	d_clone_t	*nhandler;
147 	TAILQ_ENTRY(devfs_clone_handler) link;
148 };
149 
150 
151 struct devfs_alias {
152 	char		*name;
153 	size_t		namlen;
154 	cdev_t		dev_target;
155 	TAILQ_ENTRY(devfs_alias) link;
156 };
157 
158 struct devfs_dev_ops {
159 	struct dev_ops *ops;
160 	int	ref_count;
161 	int id;
162 	TAILQ_ENTRY(devfs_dev_ops) link;
163 };
164 
165 typedef struct devfs_msg {
166 	struct lwkt_msg	hdr;
167 
168 	union {
169 		struct {
170 			cdev_t	dev;
171 			uid_t	uid;
172 			gid_t	gid;
173 			int	perms;
174 		} __m_dev;
175 		struct {
176 			struct devfs_mnt_data *mnt;
177 		} __m_mnt;
178 		struct {
179 			const char	*name;
180 			d_clone_t	*nhandler;
181 		} __m_chandler;
182 		struct {
183 			void *load;
184 			void *load2;
185 		} __m_gen;
186 		struct {
187 			void *resp;
188 		} __m_resp;
189 		struct {
190 			dev_t	udev;
191 		} __m_udev;
192 		struct {
193 			cdev_t	cdev;
194 		} __m_cdev;
195 		struct {
196 			char	*name;
197 		} __m_name;
198 		struct {
199 			char	*basename;
200 			u_char	unit;
201 			struct vnode *vp;
202 		} __m_clone;
203 		struct {
204 			struct devfs_node *node;
205 		} __m_node;
206 		struct {
207 			char	*name;
208 			char	*target;
209 			struct mount *mp;
210 		} __m_link;
211 		struct {
212 			struct dev_ops *ops;
213 			int	minor;
214 		} __m_ops;
215 		struct {
216 			cdev_t		dev;
217 			uint32_t	flag;
218 		} __m_flags;
219 		struct {
220 			ino_t	ino;
221 			struct vnode *vp;
222 			struct mount *mp;
223 		} __m_ino;
224 	} __m_u;
225 } *devfs_msg_t;
226 
227 #define mdv_chandler	__m_u.__m_chandler
228 #define mdv_mnt		__m_u.__m_mnt.mnt
229 #define mdv_load	__m_u.__m_gen.load
230 #define mdv_load2	__m_u.__m_gen.load2
231 #define mdv_response	__m_u.__m_resp.resp
232 #define mdv_dev		__m_u.__m_dev
233 #define mdv_link	__m_u.__m_link
234 #define mdv_udev	__m_u.__m_udev.udev
235 #define mdv_cdev	__m_u.__m_cdev.cdev
236 #define mdv_name	__m_u.__m_name.name
237 #define mdv_clone	__m_u.__m_clone
238 #define mdv_node	__m_u.__m_node.node
239 #define mdv_ops		__m_u.__m_ops
240 #define mdv_flags	__m_u.__m_flags
241 #define mdv_ino		__m_u.__m_ino
242 
243 
244 typedef struct devfs_core_args {
245 	thread_t     td;
246 } *devfs_core_args_t;
247 
248 TAILQ_HEAD(devfs_node_head, devfs_node);
249 TAILQ_HEAD(devfs_dev_head, cdev);
250 TAILQ_HEAD(devfs_mnt_head, devfs_mnt_data);
251 TAILQ_HEAD(devfs_chandler_head, devfs_clone_handler);
252 TAILQ_HEAD(devfs_alias_head, devfs_alias);
253 TAILQ_HEAD(devfs_dev_ops_head, devfs_dev_ops);
254 
255 typedef void (devfs_scan_t)(char *, cdev_t, bool, void *);
256 typedef void* (devfs_iterate_callback_t)(struct devfs_node *, void *);
257 
258 #define DEVFS_NODE(x)		((struct devfs_node *)((x)->v_data))
259 #define DEVFS_MNTDATA(x)	((struct devfs_mnt_data *)((x)->mnt_data))
260 #define DEVFS_ORPHANLIST(x)	(&(DEVFS_MNTDATA(x)->orphan_list))
261 #define DEVFS_DENODE_HEAD(x)	(&((x)->list))
262 #if 0
263 #define DEVFS_ISDIGIT(x)	((x >= '0') && (x <= '9'))
264 #endif
265 
266 /*
267  * -rwxr-xr-x
268  */
269 #define DEVFS_DEFAULT_MODE	((VREAD|VWRITE|VEXEC) | ((VREAD|VEXEC)>>3) | \
270 				 ((VREAD|VEXEC)>>6));
271 
272 #define DEVFS_DEFAULT_UID	0	/* root */
273 #define DEVFS_DEFAULT_GID	0	/* wheel */
274 
275 /*
276  * debug levels
277  */
278 #define DEVFS_DEBUG_SHOW	0x00
279 #define DEVFS_DEBUG_WARNING	0x01
280 #define DEVFS_DEBUG_INFO	0x02
281 #define DEVFS_DEBUG_DEBUG	0x03
282 
283 /*
284  * Message ids
285  */
286 #define DEVFS_TERMINATE_CORE		0x01
287 #define DEVFS_DEVICE_CREATE		0x02
288 #define DEVFS_DEVICE_DESTROY		0x03
289 #define DEVFS_MOUNT_ADD			0x04
290 #define DEVFS_MOUNT_DEL			0x05
291 #define DEVFS_CREATE_ALL_DEV		0x06
292 #define DEVFS_DESTROY_RELATED		0x07
293 #define DEVFS_DESTROY_DEV_BY_OPS	0x08
294 #define DEVFS_CHANDLER_ADD		0x09
295 #define DEVFS_CHANDLER_DEL		0x0A
296 #define DEVFS_FIND_DEVICE_BY_DEVID	0x0B
297 #define DEVFS_FIND_DEVICE_BY_NAME	0x0C
298 #define DEVFS_MAKE_ALIAS		0x0D
299 #define DEVFS_DESTROY_ALIAS		0x0E
300 #define DEVFS_APPLY_RULES		0x0F
301 #define	DEVFS_RESET_RULES		0x10
302 #define DEVFS_SCAN_CALLBACK		0x11
303 #define DEVFS_CLR_RELATED_FLAG		0x12
304 #define DEVFS_DESTROY_RELATED_WO_FLAG	0x13
305 #define DEVFS_INODE_TO_VNODE		0x14
306 #define DEVFS_SYNC			0x99
307 
308 /*
309  * Node flags
310  *
311  * HIDDEN	Makes node inaccessible, apart from already allocated vnodes
312  * INVISIBLE	Makes node invisible in a readdir()
313  */
314 #define DEVFS_NODE_LINKED		0x001	/* Linked into topology */
315 #define	DEVFS_USER_CREATED		0x002	/* Node was user-created */
316 #define DEVFS_ORPHANED			0x004	/* on orphan list */
317 #define DEVFS_CLONED			0x008	/* Created by cloning code */
318 #define DEVFS_HIDDEN			0x010	/* Makes node inaccessible */
319 #define DEVFS_INVISIBLE			0x020	/* Makes node invisible */
320 #define	DEVFS_PTY			0x040	/* PTY device */
321 #define DEVFS_DESTROYED			0x080	/* Destroy attempt */
322 #define DEVFS_RULE_CREATED		0x100	/* Node was rule-created */
323 #define DEVFS_RULE_HIDDEN		0x200	/* Node was hidden by a rule */
324 #define DEVFS_NLINKSWAIT		0x400	/* NLinks final */
325 
326 /*
327  * Clone helper stuff
328  */
329 #define DEVFS_BITMAP_INITIAL_SIZE	1
330 #define DEVFS_CLONE_BITMAP(name)	devfs_ ## name ## _clone_bitmap
331 #define DEVFS_DEFINE_CLONE_BITMAP(name) \
332 			struct devfs_bitmap DEVFS_CLONE_BITMAP(name)
333 #define DEVFS_DECLARE_CLONE_BITMAP(name) \
334 			extern struct devfs_bitmap DEVFS_CLONE_BITMAP(name)
335 
336 struct devfs_bitmap {
337 	int		chunks;
338 	unsigned long	*bitmap;
339 };
340 #endif /* _KERNEL */
341 
342 #if 0
343 struct devfs_unit_hash {
344         struct devfs_unit_hash *next;
345         int		unit_no;
346 	cdev_t		dev;
347 };
348 #endif
349 
350 #ifdef _KERNEL
351 void devfs_clone_bitmap_init(struct devfs_bitmap *);
352 void devfs_clone_bitmap_uninit(struct devfs_bitmap *);
353 int devfs_clone_bitmap_set(struct devfs_bitmap *, int);
354 int devfs_clone_bitmap_get(struct devfs_bitmap *, int);
355 int devfs_clone_bitmap_chk(struct devfs_bitmap *, int);
356 void devfs_clone_bitmap_put(struct devfs_bitmap *, int);
357 
358 /*
359  * Prototypes
360  */
361 int devfs_debug(int level, char *fmt, ...) __printflike(2, 3);
362 int devfs_allocv(struct vnode **, struct devfs_node *);
363 struct devfs_node *devfs_allocp(devfs_nodetype, char *, struct devfs_node *,
364 				struct mount *, cdev_t);
365 int devfs_allocvp(struct mount *, struct vnode **, devfs_nodetype, char *,
366 				struct devfs_node *, cdev_t);
367 
368 void devfs_freep(struct devfs_node *);
369 void devfs_unlinkp(struct devfs_node *);
370 
371 void devfs_tracer_add_orphan(struct devfs_node *);
372 void devfs_tracer_del_orphan(struct devfs_node *);
373 size_t devfs_tracer_orphan_count(struct mount *, int);
374 
375 int devfs_set_perms(struct devfs_node *, uid_t, gid_t, u_short, u_long);
376 int devfs_gc(struct devfs_node *);
377 
378 int devfs_create_dev(cdev_t, uid_t, gid_t, int);
379 int devfs_destroy_dev(cdev_t);
380 
381 int  devfs_msg_send_sync(uint32_t, devfs_msg_t);
382 void devfs_msg_send(uint32_t, devfs_msg_t);
383 void devfs_msg_send_dev(uint32_t, cdev_t dev, uid_t, gid_t, int);
384 void devfs_msg_send_mount(uint32_t, struct devfs_mnt_data *);
385 void devfs_msg_send_ops(uint32_t, struct dev_ops *, int);
386 void devfs_msg_send_chandler(uint32_t, char *, d_clone_t);
387 void devfs_msg_send_generic(uint32_t, void *);
388 void devfs_msg_send_name(uint32_t, char *);
389 void devfs_msg_send_link(uint32_t, char *, char *, struct mount *);
390 
391 devfs_msg_t devfs_msg_get(void);
392 int devfs_msg_put(devfs_msg_t);
393 
394 int devfs_mount_add(struct devfs_mnt_data *);
395 int devfs_mount_del(struct devfs_mnt_data *);
396 
397 int devfs_create_all_dev(struct devfs_node *);
398 
399 struct devfs_node *devfs_resolve_or_create_path(
400 				struct devfs_node *, char *, int);
401 int devfs_resolve_name_path(char *, char *, char **, char **);
402 struct devfs_node *devfs_create_device_node(struct devfs_node *, cdev_t, int *,
403 		      char *, char *, ...) __printf0like(5, 6);
404 
405 int devfs_destroy_device_node(struct devfs_node *, cdev_t);
406 int devfs_destroy_node(struct devfs_node *, char *);
407 int devfs_destroy_related(cdev_t);
408 int devfs_destroy_dev_by_ops(struct dev_ops *, int);
409 struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *);
410 
411 cdev_t devfs_new_cdev(struct dev_ops *, int, struct dev_ops *);
412 void devfs_assume_knotes(cdev_t dev, struct kqinfo *kqi);
413 
414 cdev_t devfs_find_device_by_name(const char *, ...) __printf0like(1, 2);
415 cdev_t devfs_find_device_by_devid(dev_t);
416 
417 struct vnode *devfs_inode_to_vnode(struct mount *, ino_t);
418 
419 int devfs_clone_handler_add(const char *, d_clone_t *);
420 int devfs_clone_handler_del(const char *);
421 cdev_t devfs_clone(cdev_t, const char *, size_t, int, struct ucred *);
422 
423 int devfs_link_dev(cdev_t);
424 
425 int devfs_make_alias(const char *, cdev_t);
426 int devfs_destroy_alias(const char *, cdev_t);
427 
428 int devfs_alias_create(char *, struct devfs_node *, int);
429 
430 int devfs_apply_rules(char *);
431 int devfs_reset_rules(char *);
432 
433 int devfs_scan_callback(devfs_scan_t *, void *);
434 
435 int devfs_clr_related_flag(cdev_t, uint32_t);
436 int devfs_destroy_related_without_flag(cdev_t, uint32_t);
437 int devfs_node_is_accessible(struct devfs_node *);
438 
439 void devfs_config(void);
440 
441 void *devfs_iterate_topology(struct devfs_node *node,
442 		devfs_iterate_callback_t *callback, void *arg1);
443 
444 void *devfs_find_device_node_callback(struct devfs_node *, cdev_t);
445 
446 typedef void d_priv_dtor_t(void *data);
447 int devfs_get_cdevpriv(struct file *fp, void **datap);
448 int devfs_set_cdevpriv(struct file *fp, void *priv, d_priv_dtor_t *dtr);
449 void devfs_clear_cdevpriv(struct file *fp);
450 
451 int devfs_WildCmp(const char *w, const char *s);
452 int devfs_WildCaseCmp(const char *w, const char *s);
453 #endif	/* _KERNEL */
454 
455 #endif /* KERNEL || _KERNEL_STRUCTURES */
456 
457 #define DEVFS_MNT_RULESET	0x01
458 #define DEVFS_MNT_JAIL		0x02
459 
460 struct devfs_mount_info {
461 	int flags;
462 };
463 
464 #endif /* _SYS_DEVFS_H_ */
465