xref: /dragonfly/sys/sys/devfs.h (revision 956939d5)
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_QUEUE_H_
40 #include <sys/queue.h>
41 #endif
42 #ifndef _SYS_LOCK_H_
43 #include <sys/lock.h>
44 #endif
45 #ifndef _SYS_CONF_H_
46 #include <sys/conf.h>
47 #endif
48 #ifndef _SYS_MSGPORT_H_
49 #include <sys/msgport.h>
50 #endif
51 #ifndef _SYS_DIRENT_H_
52 #include <sys/dirent.h>
53 #endif
54 #ifndef _SYS_DEVICE_H_
55 #include <sys/device.h>
56 #endif
57 #ifndef _SYS_UCRED_H_
58 #include <sys/ucred.h>
59 #endif
60 
61 
62 typedef enum {
63 	Proot,		/* the filesystem root */
64 	Plink,
65 	Preg,
66 	Pdir,
67 	Pdev
68 } devfs_nodetype;
69 
70 struct devfs_dirent {
71 	ino_t		d_ino;		/* file number of entry */
72 	uint16_t	d_namlen;	/* strlen(d_name) */
73 	uint8_t		d_type;		/* file type */
74 	char		*d_name;
75 };
76 
77 struct devfs_fid {
78 	uint16_t	fid_len;	/* Length of structure. */
79 	uint16_t	fid_pad;	/* Force 32-bit alignment. */
80 	uint32_t	fid_gen;
81 	ino_t		fid_ino;	/* File number (ino). */
82 };
83 
84 struct devfs_node {
85 	cdev_t		d_dev;		/* device assoicated with this node */
86 
87 	struct mount 	*mp;		/* mount point of this node */
88 	struct devfs_dirent d_dir;	/* dirent data (name, inode, ...) */
89 	struct vnode 	*v_node;	/* assoicated vnode */
90 	struct devfs_node *parent;	/* parent of this node */
91 	devfs_nodetype	node_type;	/* devfs node type */
92 
93 	u_int64_t	refs;		/* number of open references */
94 	size_t		nchildren;	/* number of children of a parent */
95 	u_int64_t	cookie_jar;	/* cookie pool for children */
96 	u_int64_t	cookie;		/* directory entry cookie for readdir */
97 
98 	struct devfs_node *link_target;	/* target of this autolink-type node */
99 	size_t		nlinks;		/* hard links */
100 
101 	char		*symlink_name;	/* symlink name for readlink */
102 	size_t		symlink_namelen; /* symlink name length for readlink */
103 
104 	u_short		mode;		/* files access mode and type */
105 	uid_t		uid;		/* owner user id */
106 	gid_t		gid;		/* owner group id */
107 	u_long		flags;
108 
109 	struct timespec	atime;		/* time of last access */
110 	struct timespec	mtime;		/* time of last modification */
111 	struct timespec	ctime;		/* time file changed */
112 
113 	TAILQ_ENTRY(devfs_node) link;
114 	TAILQ_HEAD(, devfs_node) list;	/* linked list of children */
115 };
116 
117 struct devfs_orphan {
118 	struct devfs_node *node;
119 	TAILQ_ENTRY(devfs_orphan) link;
120 };
121 
122 struct devfs_mnt_data {
123 	TAILQ_HEAD(, devfs_orphan) orphan_list;
124 	TAILQ_ENTRY(devfs_mnt_data) link;
125 
126 	struct devfs_node *root_node;
127 	struct mount	*mp;
128 	uint32_t	mnt_type;
129 	long		leak_count;
130 	long		file_count;
131 	int		jailed;
132 	size_t		mntonnamelen;
133 };
134 
135 struct devfs_clone_handler {
136 	char		*name;
137 	u_char		namlen;
138 	d_clone_t	*nhandler;
139 	TAILQ_ENTRY(devfs_clone_handler) link;
140 };
141 
142 
143 struct devfs_alias {
144 	char		*name;
145 	size_t		namlen;
146 	cdev_t		dev_target;
147 	TAILQ_ENTRY(devfs_alias) link;
148 };
149 
150 struct devfs_dev_ops {
151 	struct dev_ops *ops;
152 	int	ref_count;
153 	int id;
154 	TAILQ_ENTRY(devfs_dev_ops) link;
155 };
156 
157 typedef struct devfs_msg {
158 	struct lwkt_msg	hdr;
159 
160 	union {
161 		struct {
162 			cdev_t	dev;
163 			uid_t	uid;
164 			gid_t	gid;
165 			int	perms;
166 		} __m_dev;
167 		struct {
168 			struct devfs_mnt_data *mnt;
169 		} __m_mnt;
170 		struct {
171 			const char	*name;
172 			d_clone_t	*nhandler;
173 		} __m_chandler;
174 		struct {
175 			void *load;
176 		} __m_gen;
177 		struct {
178 			void *resp;
179 		} __m_resp;
180 		struct {
181 			udev_t	udev;
182 		} __m_udev;
183 		struct {
184 			cdev_t	cdev;
185 		} __m_cdev;
186 		struct {
187 			char	*name;
188 		} __m_name;
189 		struct {
190 			char	*basename;
191 			u_char	unit;
192 			struct vnode *vp;
193 		} __m_clone;
194 		struct {
195 			struct devfs_node *node;
196 		} __m_node;
197 		struct {
198 			char	*name;
199 			char	*target;
200 			struct mount *mp;
201 		} __m_link;
202 		struct {
203 			struct dev_ops *ops;
204 			int	minor;
205 		} __m_ops;
206 		struct {
207 			char	*name;
208 			uint32_t	flag;
209 		} __m_flags;
210 		struct {
211 			ino_t	ino;
212 			struct vnode *vp;
213 			struct mount *mp;
214 		} __m_ino;
215 	} __m_u;
216 } *devfs_msg_t;
217 
218 #define mdv_chandler	__m_u.__m_chandler
219 #define mdv_mnt		__m_u.__m_mnt.mnt
220 #define mdv_load	__m_u.__m_gen.load
221 #define mdv_response	__m_u.__m_resp.resp
222 #define mdv_dev		__m_u.__m_dev
223 #define mdv_link	__m_u.__m_link
224 #define mdv_udev	__m_u.__m_udev.udev
225 #define mdv_cdev	__m_u.__m_cdev.cdev
226 #define mdv_name	__m_u.__m_name.name
227 #define mdv_clone	__m_u.__m_clone
228 #define mdv_node	__m_u.__m_node.node
229 #define mdv_ops		__m_u.__m_ops
230 #define mdv_flags	__m_u.__m_flags
231 #define mdv_ino		__m_u.__m_ino
232 
233 
234 typedef struct devfs_core_args {
235 	thread_t     td;
236 } *devfs_core_args_t;
237 
238 TAILQ_HEAD(devfs_node_head, devfs_node);
239 TAILQ_HEAD(devfs_dev_head, cdev);
240 TAILQ_HEAD(devfs_mnt_head, devfs_mnt_data);
241 TAILQ_HEAD(devfs_chandler_head, devfs_clone_handler);
242 TAILQ_HEAD(devfs_alias_head, devfs_alias);
243 TAILQ_HEAD(devfs_dev_ops_head, devfs_dev_ops);
244 
245 typedef void (devfs_scan_t)(cdev_t);
246 typedef void* (devfs_iterate_callback_t)(struct devfs_node *, void *);
247 
248 #define DEVFS_NODE(x)		((struct devfs_node *)((x)->v_data))
249 #define DEVFS_MNTDATA(x)	((struct devfs_mnt_data *)((x)->mnt_data))
250 #define DEVFS_ORPHANLIST(x)	(&(DEVFS_MNTDATA(x)->orphan_list))
251 #define DEVFS_DENODE_HEAD(x)	(&((x)->list))
252 #define DEVFS_ISDIGIT(x)	((x >= '0') && (x <= '9'))
253 
254 /*
255  * -rwxr-xr-x
256  */
257 #define DEVFS_DEFAULT_MODE	((VREAD|VWRITE|VEXEC) | ((VREAD|VEXEC)>>3) | \
258 				 ((VREAD|VEXEC)>>6));
259 
260 #define DEVFS_DEFAULT_UID	0	/* root */
261 #define DEVFS_DEFAULT_GID	0	/* wheel */
262 
263 /*
264  * debug levels
265  */
266 #define DEVFS_DEBUG_SHOW	0x00
267 #define DEVFS_DEBUG_WARNING	0x01
268 #define DEVFS_DEBUG_INFO	0x02
269 #define DEVFS_DEBUG_DEBUG	0x03
270 
271 /*
272  * Message ids
273  */
274 #define DEVFS_TERMINATE_CORE		0x01
275 #define DEVFS_DEVICE_CREATE		0x02
276 #define DEVFS_DEVICE_DESTROY		0x03
277 #define DEVFS_MOUNT_ADD			0x04
278 #define DEVFS_MOUNT_DEL			0x05
279 #define DEVFS_CREATE_ALL_DEV		0x06
280 #define DEVFS_DESTROY_SUBNAMES		0x07
281 #define DEVFS_DESTROY_DEV_BY_OPS	0x08
282 #define DEVFS_CHANDLER_ADD		0x09
283 #define DEVFS_CHANDLER_DEL		0x0A
284 #define DEVFS_FIND_DEVICE_BY_UDEV	0x0B
285 #define DEVFS_FIND_DEVICE_BY_NAME	0x0C
286 #define DEVFS_MAKE_ALIAS		0x0D
287 #define DEVFS_APPLY_RULES		0x0F
288 #define	DEVFS_RESET_RULES		0x10
289 #define DEVFS_SCAN_CALLBACK		0x11
290 #define DEVFS_CLR_SUBNAMES_FLAG		0x12
291 #define DEVFS_DESTROY_SUBNAMES_WO_FLAG	0x13
292 #define DEVFS_INODE_TO_VNODE		0x14
293 #define DEVFS_SYNC			0x99
294 
295 /*
296  * Node flags
297  *
298  * HIDDEN	Makes node inaccessible, apart from already allocated vnodes
299  * INVISIBLE	Makes node invisible in a readdir()
300  */
301 #define DEVFS_NODE_LINKED		0x001	/* Linked into topology */
302 #define	DEVFS_USER_CREATED		0x002	/* Node was user-created */
303 #define DEVFS_ORPHANED			0x004	/* on orphan list */
304 #define DEVFS_CLONED			0x008	/* Created by cloning code */
305 #define DEVFS_HIDDEN			0x010	/* Makes node inaccessible */
306 #define DEVFS_INVISIBLE			0x020	/* Makes node invisible */
307 #define	DEVFS_PTY			0x040	/* PTY device */
308 #define DEVFS_DESTROYED			0x080	/* Sanity check */
309 #define DEVFS_RULE_CREATED		0x100	/* Node was rule-created */
310 #define DEVFS_RULE_HIDDEN		0x200	/* Node was hidden by a rule */
311 
312 /*
313  * Clone helper stuff
314  */
315 #define DEVFS_BITMAP_INITIAL_SIZE	1
316 #define DEVFS_CLONE_BITMAP(name)	devfs_ ## name ## _clone_bitmap
317 #define DEVFS_DECLARE_CLONE_BITMAP(name) \
318 				struct devfs_bitmap DEVFS_CLONE_BITMAP(name)
319 #define devfs_clone_bitmap_put		devfs_clone_bitmap_rst
320 
321 struct devfs_bitmap {
322 	int		chunks;
323 	unsigned long	*bitmap;
324 };
325 
326 struct devfs_unit_hash {
327         struct devfs_unit_hash *next;
328         int		unit_no;
329 	cdev_t		dev;
330 };
331 
332 void devfs_clone_bitmap_init(struct devfs_bitmap *);
333 void devfs_clone_bitmap_uninit(struct devfs_bitmap *);
334 void devfs_clone_bitmap_resize(struct devfs_bitmap *, int);
335 int devfs_clone_bitmap_fff(struct devfs_bitmap *);
336 void devfs_clone_bitmap_set(struct devfs_bitmap *, int);
337 void devfs_clone_bitmap_rst(struct devfs_bitmap *, int);
338 int devfs_clone_bitmap_get(struct devfs_bitmap *, int);
339 int devfs_clone_bitmap_chk(struct devfs_bitmap *, int);
340 
341 /*
342  * Prototypes
343  */
344 int devfs_debug(int level, char *fmt, ...);
345 int devfs_allocv(struct vnode **, struct devfs_node *);
346 struct devfs_node *devfs_allocp(devfs_nodetype, char *, struct devfs_node *,
347 				struct mount *, cdev_t);
348 int devfs_allocvp(struct mount *, struct vnode **, devfs_nodetype, char *,
349 				struct devfs_node *, cdev_t);
350 
351 int devfs_freep(struct devfs_node *);
352 
353 int devfs_unlinkp(struct devfs_node *);
354 
355 void devfs_tracer_add_orphan(struct devfs_node *);
356 void devfs_tracer_del_orphan(struct devfs_node *);
357 size_t devfs_tracer_orphan_count(struct mount *, int);
358 
359 int devfs_set_perms(struct devfs_node *, uid_t, gid_t, u_short, u_long);
360 int devfs_gc(struct devfs_node *);
361 
362 int devfs_create_dev(cdev_t, uid_t, gid_t, int);
363 int devfs_destroy_dev(cdev_t);
364 
365 devfs_msg_t devfs_msg_send_sync(uint32_t, devfs_msg_t);
366 void devfs_msg_send(uint32_t, devfs_msg_t);
367 void devfs_msg_send_dev(uint32_t, cdev_t dev, uid_t, gid_t, int);
368 void devfs_msg_send_mount(uint32_t, struct devfs_mnt_data *);
369 void devfs_msg_send_ops(uint32_t, struct dev_ops *, int);
370 void devfs_msg_send_chandler(uint32_t, char *, d_clone_t);
371 void devfs_msg_send_generic(uint32_t, void *);
372 void devfs_msg_send_name(uint32_t, char *);
373 void devfs_msg_send_link(uint32_t, char *, char *, struct mount *);
374 
375 devfs_msg_t devfs_msg_get(void);
376 int devfs_msg_put(devfs_msg_t);
377 
378 int devfs_mount_add(struct devfs_mnt_data *);
379 int devfs_mount_del(struct devfs_mnt_data *);
380 
381 int devfs_create_all_dev(struct devfs_node *);
382 
383 struct devfs_node *devfs_resolve_or_create_path(
384 				struct devfs_node *, char *, int);
385 int devfs_resolve_name_path(char *, char *, char **, char **);
386 struct devfs_node *devfs_create_device_node(struct devfs_node *, cdev_t,
387 				char *, char *, ...);
388 
389 int devfs_destroy_device_node(struct devfs_node *, cdev_t);
390 int devfs_destroy_subnames(char *);
391 int devfs_destroy_dev_by_ops(struct dev_ops *, int);
392 struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *);
393 
394 cdev_t devfs_new_cdev(struct dev_ops *, int, struct dev_ops *);
395 
396 cdev_t devfs_find_device_by_name(const char *, ...);
397 cdev_t devfs_find_device_by_udev(udev_t);
398 
399 struct vnode *devfs_inode_to_vnode(struct mount *, ino_t);
400 
401 int devfs_clone_handler_add(const char *, d_clone_t *);
402 int devfs_clone_handler_del(const char *);
403 cdev_t devfs_clone(cdev_t, const char *, size_t, int, struct ucred *);
404 
405 int devfs_link_dev(cdev_t);
406 
407 int devfs_make_alias(const char *, cdev_t);
408 
409 int devfs_alias_create(char *, struct devfs_node *, int);
410 
411 int devfs_apply_rules(char *);
412 int devfs_reset_rules(char *);
413 
414 int devfs_scan_callback(devfs_scan_t *);
415 
416 int devfs_clr_subnames_flag(char *, uint32_t);
417 int devfs_destroy_subnames_without_flag(char *, uint32_t);
418 int devfs_node_is_accessible(struct devfs_node *);
419 
420 int devfs_reference_ops(struct dev_ops *);
421 void devfs_release_ops(struct dev_ops *);
422 
423 void devfs_config(void);
424 
425 void *devfs_iterate_topology(struct devfs_node *node,
426 		devfs_iterate_callback_t *callback, void *arg1);
427 
428 void *devfs_find_device_node_callback(struct devfs_node *, cdev_t);
429 
430 #endif /* KERNEL */
431 
432 #define DEVFS_MNT_RULESET	0x01
433 #define DEVFS_MNT_JAIL		0x02
434 
435 struct devfs_mount_info {
436 	int flags;
437 };
438 
439 #endif /* _SYS_DEVFS_H_ */
440