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