xref: /dragonfly/sys/sys/devfs.h (revision d56bec7aafcb41e86a641fd56bc4a9c6ab068eb3)
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