1 /* devfs (Device FileSystem) driver.
3 Copyright (C) 1998-2000 Richard Gooch
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 Richard Gooch may be reached by email at rgooch@atnf.csiro.au
20 The postal address is:
21 Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
25 19980110 Richard Gooch <rgooch@atnf.csiro.au>
28 19980111 Richard Gooch <rgooch@atnf.csiro.au>
29 Created per-fs inode table rather than using inode->u.generic_ip
31 19980111 Richard Gooch <rgooch@atnf.csiro.au>
32 Created .epoch inode which has a ctime of 0.
33 Fixed loss of named pipes when dentries lost.
34 Fixed loss of inode data when devfs_register() follows mknod().
36 19980111 Richard Gooch <rgooch@atnf.csiro.au>
37 Fix for when compiling with CONFIG_KERNELD.
38 19980112 Richard Gooch <rgooch@atnf.csiro.au>
39 Fix for readdir() which sometimes didn't show entries.
40 Added <<tolerant>> option to <devfs_register>.
42 19980113 Richard Gooch <rgooch@atnf.csiro.au>
43 Created <devfs_fill_file> function.
45 19980115 Richard Gooch <rgooch@atnf.csiro.au>
46 Added subdirectory support. Major restructuring.
47 19980116 Richard Gooch <rgooch@atnf.csiro.au>
48 Fixed <find_by_dev> to not search major=0,minor=0.
49 Added symlink support.
51 19980120 Richard Gooch <rgooch@atnf.csiro.au>
52 Created <devfs_mk_dir> function and support directory unregister
53 19980120 Richard Gooch <rgooch@atnf.csiro.au>
54 Auto-ownership uses real uid/gid rather than effective uid/gid.
56 19980121 Richard Gooch <rgooch@atnf.csiro.au>
57 Supported creation of sockets.
59 19980122 Richard Gooch <rgooch@atnf.csiro.au>
60 Added DEVFS_FL_HIDE_UNREG flag.
61 Interface change to <devfs_mk_symlink>.
62 Created <devfs_symlink> to support symlink(2).
64 19980123 Richard Gooch <rgooch@atnf.csiro.au>
65 Added check to <devfs_fill_file> to check inode is in devfs.
66 Added optional traversal of symlinks.
68 19980124 Richard Gooch <rgooch@atnf.csiro.au>
69 Created <devfs_get_flags> and <devfs_set_flags>.
71 19980125 C. Scott Ananian <cananian@alumni.princeton.edu>
72 Created <devfs_find_handle>.
73 19980125 Richard Gooch <rgooch@atnf.csiro.au>
74 Allow removal of symlinks.
76 19980125 Richard Gooch <rgooch@atnf.csiro.au>
77 Created <devfs_set_symlink_destination>.
78 19980126 Richard Gooch <rgooch@atnf.csiro.au>
79 Moved DEVFS_SUPER_MAGIC into header file.
80 Added DEVFS_FL_HIDE flag.
81 Created <devfs_get_maj_min>.
82 Created <devfs_get_handle_from_inode>.
83 Fixed minor bug in <find_by_dev>.
84 19980127 Richard Gooch <rgooch@atnf.csiro.au>
85 Changed interface to <find_by_dev>, <find_entry>,
86 <devfs_unregister>, <devfs_fill_file> and <devfs_find_handle>.
87 Fixed inode times when symlink created with symlink(2).
89 19980129 C. Scott Ananian <cananian@alumni.princeton.edu>
90 Exported <devfs_set_symlink_destination>, <devfs_get_maj_min>
91 and <devfs_get_handle_from_inode>.
92 19980129 Richard Gooch <rgooch@atnf.csiro.au>
93 Created <devfs_unlink> to support unlink(2).
95 19980129 Richard Gooch <rgooch@atnf.csiro.au>
96 Fixed kerneld support for entries in devfs subdirectories.
97 19980130 Richard Gooch <rgooch@atnf.csiro.au>
98 Bugfixes in <call_kerneld>.
100 19980207 Richard Gooch <rgooch@atnf.csiro.au>
101 Call kerneld when looking up unregistered entries.
103 19980326 Richard Gooch <rgooch@atnf.csiro.au>
104 Modified interface to <devfs_find_handle> for symlink traversal.
106 19980331 Richard Gooch <rgooch@atnf.csiro.au>
107 Fixed persistence bug with device numbers for manually created
109 Fixed problem with recreating symlinks with different content.
111 19980401 Richard Gooch <rgooch@atnf.csiro.au>
112 Changed to CONFIG_KMOD.
113 Hide entries which are manually unlinked.
114 Always invalidate devfs dentry cache when registering entries.
115 Created <devfs_rmdir> to support rmdir(2).
116 Ensure directories created by <devfs_mk_dir> are visible.
118 19980402 Richard Gooch <rgooch@atnf.csiro.au>
119 Invalidate devfs dentry cache when making directories.
120 Invalidate devfs dentry cache when removing entries.
121 Fixed persistence bug with fifos.
123 19980421 Richard Gooch <rgooch@atnf.csiro.au>
124 Print process command when debugging kerneld/kmod.
125 Added debugging for register/unregister/change operations.
126 19980422 Richard Gooch <rgooch@atnf.csiro.au>
127 Added "devfs=" boot options.
129 19980426 Richard Gooch <rgooch@atnf.csiro.au>
130 No longer lock/unlock superblock in <devfs_put_super>.
131 Drop negative dentries when they are released.
132 Manage dcache more efficiently.
134 19980427 Richard Gooch <rgooch@atnf.csiro.au>
135 Added DEVFS_FL_AUTO_DEVNUM flag.
137 19980430 Richard Gooch <rgooch@atnf.csiro.au>
138 No longer set unnecessary methods.
140 19980504 Richard Gooch <rgooch@atnf.csiro.au>
141 Added PID display to <call_kerneld> debugging message.
142 Added "after" debugging message to <call_kerneld>.
143 19980519 Richard Gooch <rgooch@atnf.csiro.au>
144 Added "diread" and "diwrite" boot options.
145 19980520 Richard Gooch <rgooch@atnf.csiro.au>
146 Fixed persistence problem with permissions.
148 19980602 Richard Gooch <rgooch@atnf.csiro.au>
149 Support legacy device nodes.
150 Fixed bug where recreated inodes were hidden.
152 19980602 Richard Gooch <rgooch@atnf.csiro.au>
153 Improved debugging in <get_vfs_inode>.
154 19980607 Richard Gooch <rgooch@atnf.csiro.au>
155 No longer free old dentries in <devfs_mk_dir>.
156 Free all dentries for a given entry when deleting inodes.
158 19980627 Richard Gooch <rgooch@atnf.csiro.au>
159 Limit auto-device numbering to majors 128 to 239.
161 19980629 Richard Gooch <rgooch@atnf.csiro.au>
162 Fixed inode times persistence problem.
164 19980704 Richard Gooch <rgooch@atnf.csiro.au>
165 Fixed spelling in <devfs_readlink> debug.
166 Fixed bug in <devfs_setup> parsing "dilookup".
168 19980705 Richard Gooch <rgooch@atnf.csiro.au>
169 Fixed devfs inode leak when manually recreating inodes.
170 Fixed permission persistence problem when recreating inodes.
172 19980727 Richard Gooch <rgooch@atnf.csiro.au>
173 Removed harmless "unused variable" compiler warning.
174 Fixed modes for manually recreated device nodes.
176 19980728 Richard Gooch <rgooch@atnf.csiro.au>
177 Added NULL devfs inode warning in <devfs_read_inode>.
178 Force all inode nlink values to 1.
180 19980730 Richard Gooch <rgooch@atnf.csiro.au>
181 Added "dimknod" boot option.
182 Set inode nlink to 0 when freeing dentries.
183 Fixed modes for manually recreated symlinks.
185 19980802 Richard Gooch <rgooch@atnf.csiro.au>
186 Fixed bugs in recreated directories and symlinks.
188 19980806 Richard Gooch <rgooch@atnf.csiro.au>
189 Fixed bugs in recreated device nodes.
190 19980807 Richard Gooch <rgooch@atnf.csiro.au>
191 Fixed bug in currently unused <devfs_get_handle_from_inode>.
192 Defined new <devfs_handle_t> type.
193 Improved debugging when getting entries.
194 Fixed bug where directories could be emptied.
196 19980809 Richard Gooch <rgooch@atnf.csiro.au>
197 Replaced dummy .epoch inode with .devfsd character device.
198 19980810 Richard Gooch <rgooch@atnf.csiro.au>
199 Implemented devfsd protocol revision 0.
201 19980819 Richard Gooch <rgooch@atnf.csiro.au>
202 Added soothing message to warning in <devfs_d_iput>.
204 19980829 Richard Gooch <rgooch@atnf.csiro.au>
205 Use GCC extensions for structure initialisations.
206 Implemented async open notification.
207 Incremented devfsd protocol revision to 1.
209 19980908 Richard Gooch <rgooch@atnf.csiro.au>
210 Moved async open notification to end of <devfs_open>.
212 19980910 Richard Gooch <rgooch@atnf.csiro.au>
213 Prepended "/dev/" to module load request.
214 Renamed <call_kerneld> to <call_kmod>.
216 19980910 Richard Gooch <rgooch@atnf.csiro.au>
217 Fixed typo "AYSNC" -> "ASYNC".
219 19980910 Richard Gooch <rgooch@atnf.csiro.au>
220 Added open flag for files.
222 19980927 Richard Gooch <rgooch@atnf.csiro.au>
223 Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>.
225 19981005 Richard Gooch <rgooch@atnf.csiro.au>
226 Added test for empty <<name>> in <devfs_find_handle>.
227 Renamed <generate_path> to <devfs_generate_path> and published.
229 19981006 Richard Gooch <rgooch@atnf.csiro.au>
230 Created <devfs_get_fops>.
232 19981007 Richard Gooch <rgooch@atnf.csiro.au>
233 Limit auto-device numbering to majors 144 to 239.
235 19981010 Richard Gooch <rgooch@atnf.csiro.au>
236 Updated <devfs_follow_link> for VFS change in 2.1.125.
238 19981022 Richard Gooch <rgooch@atnf.csiro.au>
239 Created DEVFS_ FL_COMPAT flag.
241 19981023 Richard Gooch <rgooch@atnf.csiro.au>
242 Created "nocompat" boot option.
244 19981025 Richard Gooch <rgooch@atnf.csiro.au>
245 Replaced "mount" boot option with "nomount".
247 19981110 Richard Gooch <rgooch@atnf.csiro.au>
248 Created "only" boot option.
250 19981112 Richard Gooch <rgooch@atnf.csiro.au>
251 Added DEVFS_FL_REMOVABLE flag.
253 19981114 Richard Gooch <rgooch@atnf.csiro.au>
254 Only call <scan_dir_for_removable> on first call to
257 19981205 Richard Gooch <rgooch@atnf.csiro.au>
258 Updated <devfs_rmdir> for VFS change in 2.1.131.
260 19981218 Richard Gooch <rgooch@atnf.csiro.au>
261 Created <devfs_mk_compat>.
262 19981220 Richard Gooch <rgooch@atnf.csiro.au>
263 Check for partitions on removable media in <devfs_lookup>.
265 19990118 Richard Gooch <rgooch@atnf.csiro.au>
266 Added support for registering regular files.
267 Created <devfs_set_file_size>.
268 Update devfs inodes from entries if not changed through FS.
270 19990124 Richard Gooch <rgooch@atnf.csiro.au>
271 Fixed <devfs_fill_file> to only initialise temporary inodes.
272 Trap for NULL fops in <devfs_register>.
273 Return -ENODEV in <devfs_fill_file> for non-driver inodes.
275 19990126 Richard Gooch <rgooch@atnf.csiro.au>
276 Switched from PATH_MAX to DEVFS_PATHLEN.
278 19990127 Richard Gooch <rgooch@atnf.csiro.au>
279 Created "nottycompat" boot option.
281 19990318 Richard Gooch <rgooch@atnf.csiro.au>
282 Fixed <devfsd_read> to not overrun event buffer.
284 19990329 Richard Gooch <rgooch@atnf.csiro.au>
285 Created <devfs_auto_unregister>.
287 19990330 Richard Gooch <rgooch@atnf.csiro.au>
288 Don't return unregistred entries in <devfs_find_handle>.
289 Panic in <devfs_unregister> if entry unregistered.
290 19990401 Richard Gooch <rgooch@atnf.csiro.au>
291 Don't panic in <devfs_auto_unregister> for duplicates.
293 19990402 Richard Gooch <rgooch@atnf.csiro.au>
294 Don't unregister already unregistered entries in <unregister>.
296 19990510 Richard Gooch <rgooch@atnf.csiro.au>
297 Disable warning messages when unable to read partition table for
300 19990512 Richard Gooch <rgooch@atnf.csiro.au>
301 Updated <devfs_lookup> for VFS change in 2.3.1-pre1.
302 Created "oops-on-panic" boot option.
303 Improved debugging in <devfs_register> and <devfs_unregister>.
305 19990519 Richard Gooch <rgooch@atnf.csiro.au>
306 Added documentation for some functions.
307 19990525 Richard Gooch <rgooch@atnf.csiro.au>
308 Removed "oops-on-panic" boot option: now always Oops.
310 19990531 Richard Gooch <rgooch@atnf.csiro.au>
311 Improved debugging in <devfs_register>.
313 19990604 Richard Gooch <rgooch@atnf.csiro.au>
314 Added "diunlink" and "nokmod" boot options.
315 Removed superfluous warning message in <devfs_d_iput>.
317 19990611 Richard Gooch <rgooch@atnf.csiro.au>
318 Took account of change to <d_alloc_root>.
320 19990614 Richard Gooch <rgooch@atnf.csiro.au>
321 Created separate event queue for each mounted devfs.
322 Removed <devfs_invalidate_dcache>.
323 Created new ioctl()s.
324 Incremented devfsd protocol revision to 3.
325 Fixed bug when re-creating directories: contents were lost.
326 Block access to inodes until devfsd updates permissions.
327 19990615 Richard Gooch <rgooch@atnf.csiro.au>
328 Support 2.2.x kernels.
330 19990623 Richard Gooch <rgooch@atnf.csiro.au>
331 Switched to sending process uid/gid to devfsd.
332 Renamed <call_kmod> to <try_modload>.
333 Added DEVFSD_NOTIFY_LOOKUP event.
334 19990624 Richard Gooch <rgooch@atnf.csiro.au>
335 Added DEVFSD_NOTIFY_CHANGE event.
336 Incremented devfsd protocol revision to 4.
338 19990713 Richard Gooch <rgooch@atnf.csiro.au>
339 Return EISDIR rather than EINVAL for read(2) on directories.
341 19990809 Richard Gooch <rgooch@atnf.csiro.au>
342 Changed <devfs_setup> to new __init scheme.
344 19990901 Richard Gooch <rgooch@atnf.csiro.au>
345 Changed remaining function declarations to new __init scheme.
347 19991013 Richard Gooch <rgooch@atnf.csiro.au>
348 Created <devfs_get_info>, <devfs_set_info>,
349 <devfs_get_first_child> and <devfs_get_next_sibling>.
350 Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>,
351 <devfs_mk_dir> and <devfs_find_handle>.
352 Work sponsored by SGI.
354 19991017 Richard Gooch <rgooch@atnf.csiro.au>
355 Allow multiple unregistrations.
356 Work sponsored by SGI.
358 19991026 Richard Gooch <rgooch@atnf.csiro.au>
359 Added major and minor number to devfsd protocol.
360 Incremented devfsd protocol revision to 5.
361 Work sponsored by SGI.
363 19991030 Richard Gooch <rgooch@atnf.csiro.au>
364 Support info pointer for all devfs entry types.
365 Added <<info>> parameter to <devfs_mk_dir> and
367 Work sponsored by SGI.
369 19991031 Richard Gooch <rgooch@atnf.csiro.au>
370 Support "../" when searching devfs namespace.
371 Work sponsored by SGI.
373 19991101 Richard Gooch <rgooch@atnf.csiro.au>
374 Created <devfs_get_unregister_slave>.
375 Work sponsored by SGI.
377 19991103 Richard Gooch <rgooch@atnf.csiro.au>
378 Exported <devfs_get_parent>.
379 Work sponsored by SGI.
381 19991104 Richard Gooch <rgooch@atnf.csiro.au>
382 Removed unused <devfs_set_symlink_destination>.
383 19991105 Richard Gooch <rgooch@atnf.csiro.au>
384 Do not hide entries from devfsd or children.
385 Removed DEVFS_ FL_TTY_COMPAT flag.
386 Removed "nottycompat" boot option.
387 Removed <devfs_mk_compat>.
388 Work sponsored by SGI.
390 19991107 Richard Gooch <rgooch@atnf.csiro.au>
391 Added DEVFS_ FL_WAIT flag.
392 Work sponsored by SGI.
394 19991107 Richard Gooch <rgooch@atnf.csiro.au>
395 Support new "disc" naming scheme in <get_removable_partition>.
396 Allow NULL fops in <devfs_register>.
397 Work sponsored by SGI.
399 19991110 Richard Gooch <rgooch@atnf.csiro.au>
400 Fall back to major table if NULL fops given to <devfs_register>.
401 Work sponsored by SGI.
403 19991204 Richard Gooch <rgooch@atnf.csiro.au>
404 Support fifos when unregistering.
405 Work sponsored by SGI.
407 19991209 Richard Gooch <rgooch@atnf.csiro.au>
408 Removed obsolete DEVFS_ FL_COMPAT and DEVFS_ FL_TOLERANT flags.
409 Work sponsored by SGI.
411 19991214 Richard Gooch <rgooch@atnf.csiro.au>
412 Removed kmod support.
413 Work sponsored by SGI.
415 19991216 Richard Gooch <rgooch@atnf.csiro.au>
416 Improved debugging in <get_vfs_inode>.
417 Ensure dentries created by devfsd will be cleaned up.
418 Work sponsored by SGI.
420 19991223 Richard Gooch <rgooch@atnf.csiro.au>
421 Created <devfs_get_name>.
422 Work sponsored by SGI.
424 20000203 Richard Gooch <rgooch@atnf.csiro.au>
425 Ported to kernel 2.3.42.
426 Removed <devfs_fill_file>.
427 Work sponsored by SGI.
429 20000306 Richard Gooch <rgooch@atnf.csiro.au>
430 Added DEVFS_FL_NO_PERSISTENCE flag.
431 Removed unnecessary call to <update_devfs_inode_from_entry> in
433 Work sponsored by SGI.
435 20000413 Richard Gooch <rgooch@atnf.csiro.au>
436 Set inode->i_size to correct size for symlinks.
437 20000414 Richard Gooch <rgooch@atnf.csiro.au>
438 Only give lookup() method to directories to comply with new VFS
440 Work sponsored by SGI.
441 20000415 Richard Gooch <rgooch@atnf.csiro.au>
442 Remove unnecessary tests in symlink methods.
443 Don't kill existing block ops in <devfs_read_inode>.
444 Work sponsored by SGI.
446 20000424 Richard Gooch <rgooch@atnf.csiro.au>
447 Don't create missing directories in <devfs_find_handle>.
448 Work sponsored by SGI.
450 20000430 Richard Gooch <rgooch@atnf.csiro.au>
451 Added CONFIG_DEVFS_MOUNT.
452 Work sponsored by SGI.
454 20000608 Richard Gooch <rgooch@atnf.csiro.au>
455 Disabled multi-mount capability (use VFS bindings instead).
456 Work sponsored by SGI.
458 20000610 Richard Gooch <rgooch@atnf.csiro.au>
459 Switched to FS_SINGLE to disable multi-mounts.
460 20000612 Richard Gooch <rgooch@atnf.csiro.au>
461 Removed module support.
462 Removed multi-mount code.
463 Removed compatibility macros: VFS has changed too much.
464 Work sponsored by SGI.
466 20000614 Richard Gooch <rgooch@atnf.csiro.au>
467 Merged devfs inode into devfs entry.
468 Work sponsored by SGI.
470 20000619 Richard Gooch <rgooch@atnf.csiro.au>
471 Removed dead code in <devfs_register> which used to call
473 Work sponsored by SGI.
476 #include <linux/types.h>
477 #include <linux/errno.h>
478 #include <linux/sched.h>
479 #include <linux/tty.h>
480 #include <linux/timer.h>
481 #include <linux/config.h>
482 #include <linux/kernel.h>
483 #include <linux/wait.h>
484 #include <linux/string.h>
485 #include <linux/malloc.h>
486 #include <linux/ioport.h>
487 #include <linux/delay.h>
488 #include <linux/ctype.h>
489 #include <linux/mm.h>
490 #include <linux/module.h>
491 #include <linux/init.h>
492 #include <linux/locks.h>
493 #include <linux/kdev_t.h>
494 #include <linux/devfs_fs.h>
495 #include <linux/devfs_fs_kernel.h>
496 #include <linux/smp_lock.h>
497 #include <linux/smp.h>
498 #include <linux/version.h>
500 #include <asm/uaccess.h>
502 #include <asm/processor.h>
503 #include <asm/system.h>
504 #include <asm/pgtable.h>
505 #include <asm/segment.h>
506 #include <asm/bitops.h>
507 #include <asm/atomic.h>
509 #define DEVFS_VERSION "0.100 (20000619)"
511 #define DEVFS_NAME "devfs"
513 #define INODE_TABLE_INC 250
514 #define FIRST_INODE 1
516 #define STRING_LENGTH 256
518 #define MIN_DEVNUM 36864 /* Use major numbers 144 */
519 #define MAX_DEVNUM 61439 /* through 239, inclusive */
526 #define IS_HIDDEN(de) (( ((de)->hide && !is_devfsd_or_child(fs_info)) || (!(de)->registered&& !(de)->show_unreg)))
528 #define DEBUG_NONE 0x00000
529 #define DEBUG_MODULE_LOAD 0x00001
530 #define DEBUG_REGISTER 0x00002
531 #define DEBUG_UNREGISTER 0x00004
532 #define DEBUG_SET_FLAGS 0x00008
533 #define DEBUG_S_PUT 0x00010
534 #define DEBUG_I_LOOKUP 0x00020
535 #define DEBUG_I_CREATE 0x00040
536 #define DEBUG_I_READ 0x00080
537 #define DEBUG_I_WRITE 0x00100
538 #define DEBUG_I_UNLINK 0x00200
539 #define DEBUG_I_RLINK 0x00400
540 #define DEBUG_I_FLINK 0x00800
541 #define DEBUG_I_MKNOD 0x01000
542 #define DEBUG_F_READDIR 0x02000
543 #define DEBUG_D_DELETE 0x04000
544 #define DEBUG_D_RELEASE 0x08000
545 #define DEBUG_D_IPUT 0x10000
546 #define DEBUG_ALL (DEBUG_MODULE_LOAD | DEBUG_REGISTER | \
547 DEBUG_SET_FLAGS | DEBUG_I_LOOKUP | \
548 DEBUG_I_UNLINK | DEBUG_I_MKNOD | \
549 DEBUG_D_RELEASE | DEBUG_D_IPUT)
550 #define DEBUG_DISABLED DEBUG_NONE
552 #define OPTION_NONE 0x00
553 #define OPTION_SHOW 0x01
554 #define OPTION_NOMOUNT 0x02
555 #define OPTION_ONLY 0x04
557 #define OOPS(format, args...) {printk (format, ## args); \
558 printk ("Forcing Oops\n"); \
561 struct directory_type
563 struct devfs_entry
*first
;
564 struct devfs_entry
*last
;
565 unsigned int num_removable
;
575 unsigned short major
;
576 unsigned short minor
;
579 struct fcb_type
/* File, char, block type */
586 struct file_type file
;
587 struct device_type device
;
590 unsigned char auto_owner
:1;
591 unsigned char aopen_notify
:1;
592 unsigned char removable
:1; /* Belongs in device_type, but save space */
593 unsigned char open
:1; /* Not entirely correct */
598 unsigned int length
; /* Not including the NULL-termimator */
599 char *linkname
; /* This is NULL-terminated */
608 struct devfs_inode
/* This structure is for "persistent" inode storage */
613 unsigned int ino
; /* Inode number as seen in the VFS */
614 struct dentry
*dentry
;
626 struct directory_type dir
;
628 struct symlink_type symlink
;
629 struct fifo_type fifo
;
632 struct devfs_entry
*prev
; /* Previous entry in the parent directory */
633 struct devfs_entry
*next
; /* Next entry in the parent directory */
634 struct devfs_entry
*parent
; /* The parent directory */
635 struct devfs_entry
*slave
; /* Another entry to unregister */
636 struct devfs_inode inode
;
638 unsigned short namelen
; /* I think 64k+ filenames are a way off... */
639 unsigned char registered
:1;
640 unsigned char show_unreg
:1;
641 unsigned char hide
:1;
642 unsigned char no_persistence
:1;
643 char name
[1]; /* This is just a dummy: the allocated array is
644 bigger. This is NULL-terminated */
647 /* The root of the device tree */
648 static struct devfs_entry
*root_entry
= NULL
;
650 struct devfsd_buf_entry
659 struct fs_info
/* This structure is for each mounted devfs */
661 unsigned int num_inodes
; /* Number of inodes created */
662 unsigned int table_size
; /* Size of the inode pointer table */
663 struct devfs_entry
**table
;
664 struct super_block
*sb
;
665 volatile struct devfsd_buf_entry
*devfsd_buffer
;
666 volatile unsigned int devfsd_buf_in
;
667 volatile unsigned int devfsd_buf_out
;
668 volatile int devfsd_sleeping
;
669 volatile int devfsd_buffer_in_use
;
670 volatile struct task_struct
*devfsd_task
;
671 volatile struct file
*devfsd_file
;
672 volatile unsigned long devfsd_event_mask
;
673 atomic_t devfsd_overrun_count
;
674 wait_queue_head_t devfsd_wait_queue
;
675 wait_queue_head_t revalidate_wait_queue
;
678 static struct fs_info fs_info
;
679 static unsigned int next_devnum_char
= MIN_DEVNUM
;
680 static unsigned int next_devnum_block
= MIN_DEVNUM
;
681 static const int devfsd_buf_size
= PAGE_SIZE
/ sizeof(struct devfsd_buf_entry
);
682 #ifdef CONFIG_DEVFS_DEBUG
683 static unsigned int devfs_debug_init __initdata
= DEBUG_NONE
;
684 static unsigned int devfs_debug
= DEBUG_NONE
;
687 #ifdef CONFIG_DEVFS_MOUNT
688 static unsigned int boot_options
= OPTION_NONE
;
690 static unsigned int boot_options
= OPTION_NOMOUNT
;
693 /* Forward function declarations */
694 static struct devfs_entry
*search_for_entry (struct devfs_entry
*dir
,
696 unsigned int namelen
, int mkdir
,
697 int mkfile
, int *is_new
,
698 int traverse_symlink
);
699 static ssize_t
devfsd_read (struct file
*file
, char *buf
, size_t len
,
701 static int devfsd_ioctl (struct inode
*inode
, struct file
*file
,
702 unsigned int cmd
, unsigned long arg
);
703 static int devfsd_close (struct inode
*inode
, struct file
*file
);
706 /* Devfs daemon file operations */
707 static struct file_operations devfsd_fops
=
711 release
: devfsd_close
,
715 /* Support functions follow */
719 * search_for_entry_in_dir - Search for a devfs entry inside another devfs entry.
720 * @parent: The parent devfs entry.
721 * @name: The name of the entry.
722 * @namelen: The number of characters in @name.
723 * @traverse_symlink: If %TRUE then the entry is traversed if it is a symlink.
725 * Search for a devfs entry inside another devfs entry and returns a pointer
726 * to the entry on success, else %NULL.
729 static struct devfs_entry
*search_for_entry_in_dir (struct devfs_entry
*parent
,
731 unsigned int namelen
,
732 int traverse_symlink
)
734 struct devfs_entry
*curr
;
736 if ( !S_ISDIR (parent
->mode
) )
738 printk ("%s: entry is not a directory\n", DEVFS_NAME
);
741 for (curr
= parent
->u
.dir
.first
; curr
!= NULL
; curr
= curr
->next
)
743 if (curr
->namelen
!= namelen
) continue;
744 if (memcmp (curr
->name
, name
, namelen
) == 0) break;
745 /* Not found: try the next one */
747 if (curr
== NULL
) return NULL
;
748 if (!S_ISLNK (curr
->mode
) || !traverse_symlink
) return curr
;
749 /* Need to follow the link: this is a stack chomper */
750 return search_for_entry (parent
,
751 curr
->u
.symlink
.linkname
, curr
->u
.symlink
.length
,
752 FALSE
, FALSE
, NULL
, TRUE
);
753 } /* End Function search_for_entry_in_dir */
755 static struct devfs_entry
*create_entry (struct devfs_entry
*parent
,
756 const char *name
,unsigned int namelen
)
758 struct devfs_entry
*new, **table
;
760 /* First ensure table size is enough */
761 if (fs_info
.num_inodes
>= fs_info
.table_size
)
763 if ( ( table
= kmalloc (sizeof *table
*
764 (fs_info
.table_size
+ INODE_TABLE_INC
),
765 GFP_KERNEL
) ) == NULL
) return NULL
;
766 fs_info
.table_size
+= INODE_TABLE_INC
;
767 #ifdef CONFIG_DEVFS_DEBUG
768 if (devfs_debug
& DEBUG_I_CREATE
)
769 printk ("%s: create_entry(): grew inode table to: %u entries\n",
770 DEVFS_NAME
, fs_info
.table_size
);
774 memcpy (table
, fs_info
.table
, sizeof *table
*fs_info
.num_inodes
);
775 kfree (fs_info
.table
);
777 fs_info
.table
= table
;
779 if ( name
&& (namelen
< 1) ) namelen
= strlen (name
);
780 if ( ( new = kmalloc (sizeof *new + namelen
, GFP_KERNEL
) ) == NULL
)
782 /* Magic: this will set the ctime to zero, thus subsequent lookups will
783 trigger the call to <update_devfs_inode_from_entry> */
784 memset (new, 0, sizeof *new + namelen
);
785 new->parent
= parent
;
786 if (name
) memcpy (new->name
, name
, namelen
);
787 new->namelen
= namelen
;
788 new->inode
.ino
= fs_info
.num_inodes
+ FIRST_INODE
;
789 new->inode
.nlink
= 1;
790 fs_info
.table
[fs_info
.num_inodes
] = new;
791 ++fs_info
.num_inodes
;
792 if (parent
== NULL
) return new;
793 new->prev
= parent
->u
.dir
.last
;
794 /* Insert into the parent directory's list of children */
795 if (parent
->u
.dir
.first
== NULL
) parent
->u
.dir
.first
= new;
796 else parent
->u
.dir
.last
->next
= new;
797 parent
->u
.dir
.last
= new;
799 } /* End Function create_entry */
801 static void update_devfs_inode_from_entry (struct devfs_entry
*de
)
803 if (de
== NULL
) return;
804 if ( S_ISDIR (de
->mode
) )
806 de
->inode
.mode
= S_IFDIR
| S_IRWXU
| S_IRUGO
| S_IXUGO
;
810 else if ( S_ISLNK (de
->mode
) )
812 de
->inode
.mode
= S_IFLNK
| S_IRUGO
| S_IXUGO
;
816 else if ( S_ISFIFO (de
->mode
) )
818 de
->inode
.mode
= de
->mode
;
819 de
->inode
.uid
= de
->u
.fifo
.uid
;
820 de
->inode
.gid
= de
->u
.fifo
.gid
;
824 if (de
->u
.fcb
.auto_owner
)
825 de
->inode
.mode
= (de
->mode
& ~S_IALLUGO
) | S_IRUGO
| S_IWUGO
;
826 else de
->inode
.mode
= de
->mode
;
827 de
->inode
.uid
= de
->u
.fcb
.default_uid
;
828 de
->inode
.gid
= de
->u
.fcb
.default_gid
;
830 } /* End Function update_devfs_inode_from_entry */
833 * get_root_entry - Get the root devfs entry.
835 * Returns the root devfs entry on success, else %NULL.
838 static struct devfs_entry
*get_root_entry (void)
840 struct devfs_entry
*new;
842 /* Always ensure the root is created */
843 if (root_entry
!= NULL
) return root_entry
;
844 if ( ( root_entry
= create_entry (NULL
, NULL
, 0) ) == NULL
) return NULL
;
845 root_entry
->registered
= TRUE
;
846 root_entry
->mode
= S_IFDIR
;
847 /* Force an inode update, because lookup() is never done for the root */
848 update_devfs_inode_from_entry (root_entry
);
849 /* And create the entry for ".devfsd" */
850 if ( ( new = create_entry (root_entry
, ".devfsd", 0) ) == NULL
)
852 new->registered
= TRUE
;
853 new->u
.fcb
.u
.device
.major
= next_devnum_char
>> 8;
854 new->u
.fcb
.u
.device
.minor
= next_devnum_char
& 0xff;
856 new->mode
= S_IFCHR
| S_IRUSR
| S_IWUSR
;
857 new->u
.fcb
.default_uid
= 0;
858 new->u
.fcb
.default_gid
= 0;
859 new->u
.fcb
.ops
= &devfsd_fops
;
861 } /* End Function get_root_entry */
865 * search_for_entry - Search for an entry in the devfs tree.
866 * @dir: The parent directory to search from. If this is %NULL the root is used
867 * @name: The name of the entry.
868 * @namelen: The number of characters in @name.
869 * @mkdir: If %TRUE intermediate directories are created as needed.
870 * @mkfile: If %TRUE the file entry is created if it doesn't exist.
871 * @is_new: If the returned entry was newly made, %TRUE is written here. If
872 * this is %NULL nothing is written here.
873 * @traverse_symlink: If %TRUE then symbolic links are traversed.
875 * If the entry is created, then it will be in the unregistered state.
876 * Returns a pointer to the entry on success, else %NULL.
879 static struct devfs_entry
*search_for_entry (struct devfs_entry
*dir
,
881 unsigned int namelen
, int mkdir
,
882 int mkfile
, int *is_new
,
883 int traverse_symlink
)
886 const char *subname
, *stop
, *ptr
;
887 struct devfs_entry
*entry
;
889 if (is_new
) *is_new
= FALSE
;
890 if (dir
== NULL
) dir
= get_root_entry ();
891 if (dir
== NULL
) return NULL
;
892 /* Extract one filename component */
894 stop
= name
+ namelen
;
895 while (subname
< stop
)
897 /* Search for a possible '/' */
898 for (ptr
= subname
; (ptr
< stop
) && (*ptr
!= '/'); ++ptr
);
901 /* Look for trailing component */
902 len
= stop
- subname
;
903 entry
= search_for_entry_in_dir (dir
, subname
, len
,
905 if (entry
!= NULL
) return entry
;
906 if (!mkfile
) return NULL
;
907 entry
= create_entry (dir
, subname
, len
);
908 if (entry
&& is_new
) *is_new
= TRUE
;
911 /* Found '/': search for directory */
912 if (strncmp (subname
, "../", 3) == 0)
916 if (dir
== NULL
) return NULL
; /* Cannot escape from devfs */
921 entry
= search_for_entry_in_dir (dir
, subname
, len
, traverse_symlink
);
922 if (!entry
&& !mkdir
) return NULL
;
926 if ( ( entry
= create_entry (dir
, subname
, len
) ) == NULL
)
928 entry
->mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
| S_IWUSR
;
929 if (is_new
) *is_new
= TRUE
;
931 if ( !S_ISDIR (entry
->mode
) )
933 printk ("%s: existing non-directory entry\n", DEVFS_NAME
);
936 /* Ensure an unregistered entry is re-registered and visible */
937 entry
->registered
= TRUE
;
943 } /* End Function search_for_entry */
947 * find_by_dev - Find a devfs entry in a directory.
948 * @dir: The directory where to search
949 * @major: The major number to search for.
950 * @minor: The minor number to search for.
951 * @type: The type of special file to search for. This may be either
952 * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
954 * Returns the devfs_entry pointer on success, else %NULL.
957 static struct devfs_entry
*find_by_dev (struct devfs_entry
*dir
,
958 unsigned int major
, unsigned int minor
,
961 struct devfs_entry
*entry
, *de
;
963 if (dir
== NULL
) return NULL
;
964 if ( !S_ISDIR (dir
->mode
) )
966 printk ("%s: find_by_dev(): not a directory\n", DEVFS_NAME
);
969 /* First search files in this directory */
970 for (entry
= dir
->u
.dir
.first
; entry
!= NULL
; entry
= entry
->next
)
972 if ( !S_ISCHR (entry
->mode
) && !S_ISBLK (entry
->mode
) ) continue;
973 if ( S_ISCHR (entry
->mode
) && (type
!= DEVFS_SPECIAL_CHR
) ) continue;
974 if ( S_ISBLK (entry
->mode
) && (type
!= DEVFS_SPECIAL_BLK
) ) continue;
975 if ( (entry
->u
.fcb
.u
.device
.major
== major
) &&
976 (entry
->u
.fcb
.u
.device
.minor
== minor
) ) return entry
;
977 /* Not found: try the next one */
979 /* Now recursively search the subdirectories: this is a stack chomper */
980 for (entry
= dir
->u
.dir
.first
; entry
!= NULL
; entry
= entry
->next
)
982 if ( !S_ISDIR (entry
->mode
) ) continue;
983 de
= find_by_dev (entry
, major
, minor
, type
);
987 } /* End Function find_by_dev */
991 * find_entry - Find a devfs entry.
992 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
993 * name is relative to the root of the devfs.
994 * @name: The name of the entry. This is ignored if @handle is not %NULL.
995 * @namelen: The number of characters in @name, not including a %NULL
996 * terminator. If this is 0, then @name must be %NULL-terminated and the
997 * length is computed internally.
998 * @major: The major number. This is used if @handle and @name are %NULL.
999 * @minor: The minor number. This is used if @handle and @name are %NULL.
1000 * NOTE: If @major and @minor are both 0, searching by major and minor
1001 * numbers is disabled.
1002 * @type: The type of special file to search for. This may be either
1003 * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
1004 * @traverse_symlink: If %TRUE then symbolic links are traversed.
1006 * FIXME: What the hell is @handle? - ch
1007 * Returns the devfs_entry pointer on success, else %NULL.
1010 static struct devfs_entry
*find_entry (devfs_handle_t dir
,
1011 const char *name
, unsigned int namelen
,
1012 unsigned int major
, unsigned int minor
,
1013 char type
, int traverse_symlink
)
1015 struct devfs_entry
*entry
;
1019 if (namelen
< 1) namelen
= strlen (name
);
1022 /* Skip leading pathname component */
1025 printk ("%s: find_entry(%s): too short\n", DEVFS_NAME
, name
);
1028 for (++name
, --namelen
; (*name
!= '/') && (namelen
> 0);
1032 printk ("%s: find_entry(%s): too short\n", DEVFS_NAME
, name
);
1038 entry
= search_for_entry (dir
, name
, namelen
, FALSE
, FALSE
, NULL
,
1040 if (entry
!= NULL
) return entry
;
1042 /* Have to search by major and minor: slow */
1043 if ( (major
== 0) && (minor
== 0) ) return NULL
;
1044 return find_by_dev (root_entry
, major
, minor
, type
);
1045 } /* End Function find_entry */
1047 static struct devfs_entry
*get_devfs_entry_from_vfs_inode (struct inode
*inode
)
1049 struct fs_info
*fs_info
;
1051 if (inode
== NULL
) return NULL
;
1052 if (inode
->i_ino
< FIRST_INODE
) return NULL
;
1053 fs_info
= inode
->i_sb
->u
.generic_sbp
;
1054 if (fs_info
== NULL
) return NULL
;
1055 if (inode
->i_ino
- FIRST_INODE
>= fs_info
->num_inodes
) return NULL
;
1056 return fs_info
->table
[inode
->i_ino
- FIRST_INODE
];
1057 } /* End Function get_devfs_entry_from_vfs_inode */
1061 * free_dentries - Free the dentries for a device entry and invalidate inodes.
1065 static void free_dentries (struct devfs_entry
*de
)
1067 struct dentry
*dentry
;
1069 dentry
= de
->inode
.dentry
;
1073 de
->inode
.dentry
= NULL
;
1074 /* Forcefully remove the inode */
1075 if (dentry
->d_inode
!= NULL
) dentry
->d_inode
->i_nlink
= 0;
1079 } /* End Function free_dentries */
1083 * is_devfsd_or_child - Test if the current process is devfsd or one of its children.
1084 * fs_info: The filesystem information.
1086 * Returns %TRUE if devfsd or child, else %FALSE.
1089 static int is_devfsd_or_child (struct fs_info
*fs_info
)
1091 struct task_struct
*p
;
1093 for (p
= current
; p
!= &init_task
; p
= p
->p_opptr
)
1095 if (p
== fs_info
->devfsd_task
) return (TRUE
);
1098 } /* End Function is_devfsd_or_child */
1102 * devfsd_queue_empty - Test if devfsd has work pending in its event queue.
1103 * @fs_info: The filesystem information.
1105 * Returns %TRUE if the queue is empty, else %FALSE.
1108 static inline int devfsd_queue_empty (struct fs_info
*fs_info
)
1110 return (fs_info
->devfsd_buf_out
== fs_info
->devfsd_buf_in
) ? TRUE
: FALSE
;
1111 } /* End Function devfsd_queue_empty */
1115 * wait_for_devfsd_finished - Wait for devfsd to finish processing its event queue.
1116 * @fs_info: The filesystem information.
1118 * Returns %TRUE if no more waiting will be required, else %FALSE.
1121 static int wait_for_devfsd_finished (struct fs_info
*fs_info
)
1123 DECLARE_WAITQUEUE (wait
, current
);
1125 if (fs_info
->devfsd_task
== NULL
) return (TRUE
);
1126 if (devfsd_queue_empty (fs_info
) && fs_info
->devfsd_sleeping
) return TRUE
;
1127 if ( is_devfsd_or_child (fs_info
) ) return (FALSE
);
1128 add_wait_queue (&fs_info
->revalidate_wait_queue
, &wait
);
1129 current
->state
= TASK_UNINTERRUPTIBLE
;
1130 if (!devfsd_queue_empty (fs_info
) || !fs_info
->devfsd_sleeping
)
1131 if (fs_info
->devfsd_task
) schedule();
1132 remove_wait_queue (&fs_info
->revalidate_wait_queue
, &wait
);
1133 current
->state
= TASK_RUNNING
;
1135 } /* End Function wait_for_devfsd_finished */
1139 * devfsd_notify_one - Notify a single devfsd daemon of a change.
1140 * @data: Data to be passed.
1141 * @type: The type of change.
1142 * @mode: The mode of the entry.
1143 * @uid: The user ID.
1144 * @gid: The group ID.
1145 * @fs_info: The filesystem info.
1147 * Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
1150 static int devfsd_notify_one (void *data
, unsigned int type
, umode_t mode
,
1151 uid_t uid
, gid_t gid
, struct fs_info
*fs_info
)
1153 unsigned int next_pos
;
1154 unsigned long flags
;
1155 struct devfsd_buf_entry
*entry
;
1156 static spinlock_t lock
= SPIN_LOCK_UNLOCKED
;
1158 if ( !( fs_info
->devfsd_event_mask
& (1 << type
) ) ) return (FALSE
);
1159 next_pos
= fs_info
->devfsd_buf_in
+ 1;
1160 if (next_pos
>= devfsd_buf_size
) next_pos
= 0;
1161 if (next_pos
== fs_info
->devfsd_buf_out
)
1163 /* Running up the arse of the reader: drop it */
1164 atomic_inc (&fs_info
->devfsd_overrun_count
);
1167 spin_lock_irqsave (&lock
, flags
);
1168 fs_info
->devfsd_buffer_in_use
= TRUE
;
1169 next_pos
= fs_info
->devfsd_buf_in
+ 1;
1170 if (next_pos
>= devfsd_buf_size
) next_pos
= 0;
1171 entry
= (struct devfsd_buf_entry
*) fs_info
->devfsd_buffer
+
1172 fs_info
->devfsd_buf_in
;
1178 fs_info
->devfsd_buf_in
= next_pos
;
1179 fs_info
->devfsd_buffer_in_use
= FALSE
;
1180 spin_unlock_irqrestore (&lock
, flags
);
1181 wake_up_interruptible (&fs_info
->devfsd_wait_queue
);
1183 } /* End Function devfsd_notify_one */
1187 * devfsd_notify - Notify all devfsd daemons of a change.
1188 * @de: The devfs entry that has changed.
1189 * @type: The type of change event.
1190 * @wait: If TRUE, the functions waits for all daemons to finish processing
1194 static void devfsd_notify (struct devfs_entry
*de
, unsigned int type
, int wait
)
1196 if (devfsd_notify_one (de
, type
, de
->mode
, current
->euid
,
1197 current
->egid
, &fs_info
) && wait
)
1198 wait_for_devfsd_finished (&fs_info
);
1199 } /* End Function devfsd_notify */
1203 * devfs_register - Register a device entry.
1204 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1205 * new name is relative to the root of the devfs.
1206 * @name: The name of the entry.
1207 * @namelen: The number of characters in @name, not including a %NULL
1208 * terminator. If this is 0, then @name must be %NULL-terminated and the
1209 * length is computed internally.
1210 * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
1211 * @major: The major number. Not needed for regular files.
1212 * @minor: The minor number. Not needed for regular files.
1213 * @mode: The default file mode.
1214 * @uid: The default UID of the file.
1215 * @guid: The default GID of the file.
1216 * @ops: The &file_operations or &block_device_operations structure.
1217 * This must not be externally deallocated.
1218 * @info: An arbitrary pointer which will be written to the @private_data
1219 * field of the &file structure passed to the device driver. You can set
1220 * this to whatever you like, and change it once the file is opened (the next
1221 * file opened will not see this change).
1223 * Returns a handle which may later be used in a call to devfs_unregister().
1224 * On failure %NULL is returned.
1227 devfs_handle_t
devfs_register (devfs_handle_t dir
,
1228 const char *name
, unsigned int namelen
,
1230 unsigned int major
, unsigned int minor
,
1231 umode_t mode
, uid_t uid
, gid_t gid
,
1232 void *ops
, void *info
)
1235 struct devfs_entry
*de
;
1239 printk ("%s: devfs_register(): NULL name pointer\n", DEVFS_NAME
);
1244 if ( S_ISCHR (mode
) ) ops
= get_chrfops (major
, 0);
1245 else if ( S_ISBLK (mode
) ) ops
= (void *) get_blkfops (major
);
1248 printk ("%s: devfs_register(%s): NULL ops pointer\n",
1252 printk ("%s: devfs_register(%s): NULL ops, got %p from major table\n",
1253 DEVFS_NAME
, name
, ops
);
1255 if ( S_ISDIR (mode
) )
1257 printk("%s: devfs_register(%s): creating directories is not allowed\n",
1261 if ( S_ISLNK (mode
) )
1263 printk ("%s: devfs_register(%s): creating symlinks is not allowed\n",
1267 if (namelen
< 1) namelen
= strlen (name
);
1268 if ( S_ISCHR (mode
) && (flags
& DEVFS_FL_AUTO_DEVNUM
) )
1270 if (next_devnum_char
>= MAX_DEVNUM
)
1272 printk ("%s: devfs_register(%s): exhausted char device numbers\n",
1276 major
= next_devnum_char
>> 8;
1277 minor
= next_devnum_char
& 0xff;
1280 if ( S_ISBLK (mode
) && (flags
& DEVFS_FL_AUTO_DEVNUM
) )
1282 if (next_devnum_block
>= MAX_DEVNUM
)
1284 printk ("%s: devfs_register(%s): exhausted block device numbers\n",
1288 major
= next_devnum_block
>> 8;
1289 minor
= next_devnum_block
& 0xff;
1290 ++next_devnum_block
;
1292 de
= search_for_entry (dir
, name
, namelen
, TRUE
, TRUE
, &is_new
, FALSE
);
1295 printk ("%s: devfs_register(): could not create entry: \"%s\"\n",
1299 #ifdef CONFIG_DEVFS_DEBUG
1300 if (devfs_debug
& DEBUG_REGISTER
)
1301 printk ("%s: devfs_register(%s): de: %p %s\n",
1302 DEVFS_NAME
, name
, de
, is_new
? "new" : "existing");
1306 /* Existing entry */
1307 if ( !S_ISCHR (de
->mode
) && !S_ISBLK (de
->mode
) &&
1308 !S_ISREG (de
->mode
) )
1310 printk ("%s: devfs_register(): existing non-device/file entry: \"%s\"\n",
1316 printk("%s: devfs_register(): device already registered: \"%s\"\n",
1321 de
->registered
= TRUE
;
1322 if ( S_ISCHR (mode
) || S_ISBLK (mode
) )
1324 de
->u
.fcb
.u
.device
.major
= major
;
1325 de
->u
.fcb
.u
.device
.minor
= minor
;
1327 else if ( S_ISREG (mode
) ) de
->u
.fcb
.u
.file
.size
= 0;
1330 printk ("%s: devfs_register(): illegal mode: %x\n",
1336 de
->u
.fcb
.default_uid
= uid
;
1337 de
->u
.fcb
.default_gid
= gid
;
1338 de
->registered
= TRUE
;
1339 de
->u
.fcb
.ops
= ops
;
1340 de
->u
.fcb
.auto_owner
= (flags
& DEVFS_FL_AUTO_OWNER
) ? TRUE
: FALSE
;
1341 de
->u
.fcb
.aopen_notify
= (flags
& DEVFS_FL_AOPEN_NOTIFY
) ? TRUE
: FALSE
;
1342 if (flags
& DEVFS_FL_REMOVABLE
)
1344 de
->u
.fcb
.removable
= TRUE
;
1345 ++de
->parent
->u
.dir
.num_removable
;
1347 de
->u
.fcb
.open
= FALSE
;
1348 de
->show_unreg
= ( (boot_options
& OPTION_SHOW
)
1349 || (flags
& DEVFS_FL_SHOW_UNREG
) ) ? TRUE
: FALSE
;
1350 de
->hide
= (flags
& DEVFS_FL_HIDE
) ? TRUE
: FALSE
;
1351 de
->no_persistence
= (flags
& DEVFS_FL_NO_PERSISTENCE
) ? TRUE
: FALSE
;
1352 devfsd_notify (de
, DEVFSD_NOTIFY_REGISTERED
, flags
& DEVFS_FL_WAIT
);
1354 } /* End Function devfs_register */
1358 * unregister - Unregister a device entry.
1359 * @de: The entry to unregister.
1362 static void unregister (struct devfs_entry
*de
)
1364 struct devfs_entry
*child
;
1366 if ( (child
= de
->slave
) != NULL
)
1368 de
->slave
= NULL
; /* Unhook first in case slave is parent directory */
1373 devfsd_notify (de
, DEVFSD_NOTIFY_UNREGISTERED
, 0);
1377 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1379 de
->registered
= FALSE
;
1380 de
->u
.fcb
.ops
= NULL
;
1383 if ( S_ISLNK (de
->mode
) )
1385 de
->registered
= FALSE
;
1386 if (de
->u
.symlink
.linkname
!= NULL
) kfree (de
->u
.symlink
.linkname
);
1387 de
->u
.symlink
.linkname
= NULL
;
1390 if ( S_ISFIFO (de
->mode
) )
1392 de
->registered
= FALSE
;
1395 if (!de
->registered
) return;
1396 if ( !S_ISDIR (de
->mode
) )
1398 printk ("%s: unregister(): unsupported type\n", DEVFS_NAME
);
1401 de
->registered
= FALSE
;
1402 /* Now recursively search the subdirectories: this is a stack chomper */
1403 for (child
= de
->u
.dir
.first
; child
!= NULL
; child
= child
->next
)
1405 #ifdef CONFIG_DEVFS_DEBUG
1406 if (devfs_debug
& DEBUG_UNREGISTER
)
1407 printk ("%s: unregister(): child->name: \"%s\" child: %p\n",
1408 DEVFS_NAME
, child
->name
, child
);
1412 } /* End Function unregister */
1416 * devfs_unregister - Unregister a device entry.
1417 * de: A handle previously created by devfs_register() or returned from
1418 * devfs_find_handle(). If this is %NULL the routine does nothing.
1421 void devfs_unregister (devfs_handle_t de
)
1423 if (de
== NULL
) return;
1424 #ifdef CONFIG_DEVFS_DEBUG
1425 if (devfs_debug
& DEBUG_UNREGISTER
)
1426 printk ("%s: devfs_unregister(): de->name: \"%s\" de: %p\n",
1427 DEVFS_NAME
, de
->name
, de
);
1430 } /* End Function devfs_unregister */
1434 * devfs_mk_symlink Create a symbolic link in the devfs namespace.
1435 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1436 * new name is relative to the root of the devfs.
1437 * @name: The name of the entry.
1438 * @namelen: The number of characters in @name, not including a %NULL
1439 * terminator. If this is 0, then @name must be %NULL-terminated and the
1440 * length is computed internally.
1441 * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
1442 * @link: The destination name.
1443 * @linklength: The number of characters in @link, not including a %NULL
1444 * terminator. If this is 0, then @link must be %NULL-terminated and the
1445 * length is computed internally.
1446 * @handle: The handle to the symlink entry is written here. This may be %NULL.
1447 * @info: An arbitrary pointer which will be associated with the entry.
1449 * Returns 0 on success, else a negative error code is returned.
1452 int devfs_mk_symlink (devfs_handle_t dir
,
1453 const char *name
, unsigned int namelen
,
1455 const char *link
, unsigned int linklength
,
1456 devfs_handle_t
*handle
, void *info
)
1460 struct devfs_entry
*de
;
1462 if (handle
!= NULL
) *handle
= NULL
;
1465 printk ("%s: devfs_mk_symlink(): NULL name pointer\n", DEVFS_NAME
);
1468 #ifdef CONFIG_DEVFS_DEBUG
1469 if (devfs_debug
& DEBUG_REGISTER
)
1470 printk ("%s: devfs_mk_symlink(%s)\n", DEVFS_NAME
, name
);
1472 if (namelen
< 1) namelen
= strlen (name
);
1475 printk ("%s: devfs_mk_symlink(): NULL link pointer\n", DEVFS_NAME
);
1478 if (linklength
< 1) linklength
= strlen (link
);
1479 de
= search_for_entry (dir
, name
, namelen
, TRUE
, TRUE
, &is_new
, FALSE
);
1480 if (de
== NULL
) return -ENOMEM
;
1481 if (!S_ISLNK (de
->mode
) && de
->registered
)
1483 printk ("%s: devfs_mk_symlink(): non-link entry already exists\n",
1487 if (handle
!= NULL
) *handle
= de
;
1488 de
->mode
= S_IFLNK
| S_IRUGO
| S_IXUGO
;
1490 de
->show_unreg
= ( (boot_options
& OPTION_SHOW
)
1491 || (flags
& DEVFS_FL_SHOW_UNREG
) ) ? TRUE
: FALSE
;
1492 de
->hide
= (flags
& DEVFS_FL_HIDE
) ? TRUE
: FALSE
;
1493 /* Note there is no need to fiddle the dentry cache if the symlink changes
1494 as the symlink follow method is called every time it's needed */
1495 if ( de
->registered
&& (linklength
== de
->u
.symlink
.length
) )
1497 /* New link is same length as old link */
1498 if (memcmp (link
, de
->u
.symlink
.linkname
, linklength
) == 0) return 0;
1499 return -EEXIST
; /* Contents would change */
1501 /* Have to create/update */
1502 if (de
->registered
) return -EEXIST
;
1503 de
->registered
= TRUE
;
1504 if ( ( newname
= kmalloc (linklength
+ 1, GFP_KERNEL
) ) == NULL
)
1506 struct devfs_entry
*parent
= de
->parent
;
1508 if (!is_new
) return -ENOMEM
;
1509 /* Have to clean up */
1510 if (de
->prev
== NULL
) parent
->u
.dir
.first
= de
->next
;
1511 else de
->prev
->next
= de
->next
;
1512 if (de
->next
== NULL
) parent
->u
.dir
.last
= de
->prev
;
1513 else de
->next
->prev
= de
->prev
;
1517 if (de
->u
.symlink
.linkname
!= NULL
) kfree (de
->u
.symlink
.linkname
);
1518 de
->u
.symlink
.linkname
= newname
;
1519 memcpy (de
->u
.symlink
.linkname
, link
, linklength
);
1520 de
->u
.symlink
.linkname
[linklength
] = '\0';
1521 de
->u
.symlink
.length
= linklength
;
1523 } /* End Function devfs_mk_symlink */
1527 * devfs_mk_dir - Create a directory in the devfs namespace.
1528 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1529 * new name is relative to the root of the devfs.
1530 * @name: The name of the entry.
1531 * @namelen: The number of characters in @name, not including a %NULL
1532 * terminator. If this is 0, then @name must be %NULL-terminated and the
1533 * length is computed internally.
1534 * @info: An arbitrary pointer which will be associated with the entry.
1536 * Use of this function is optional. The devfs_register() function
1537 * will automatically create intermediate directories as needed. This function
1538 * is provided for efficiency reasons, as it provides a handle to a directory.
1539 * Returns a handle which may later be used in a call to devfs_unregister().
1540 * On failure %NULL is returned.
1543 devfs_handle_t
devfs_mk_dir (devfs_handle_t dir
, const char *name
,
1544 unsigned int namelen
, void *info
)
1547 struct devfs_entry
*de
;
1551 printk ("%s: devfs_mk_dir(): NULL name pointer\n", DEVFS_NAME
);
1554 if (namelen
< 1) namelen
= strlen (name
);
1555 de
= search_for_entry (dir
, name
, namelen
, TRUE
, TRUE
, &is_new
, FALSE
);
1558 printk ("%s: devfs_mk_dir(): could not create entry: \"%s\"\n",
1562 if (!S_ISDIR (de
->mode
) && de
->registered
)
1564 printk ("%s: devfs_mk_dir(): existing non-directory entry: \"%s\"\n",
1568 #ifdef CONFIG_DEVFS_DEBUG
1569 if (devfs_debug
& DEBUG_REGISTER
)
1570 printk ("%s: devfs_mk_dir(%s): de: %p %s\n",
1571 DEVFS_NAME
, name
, de
, is_new
? "new" : "existing");
1573 if (!S_ISDIR (de
->mode
) && !is_new
)
1575 /* Transmogrifying an old entry */
1576 de
->u
.dir
.first
= NULL
;
1577 de
->u
.dir
.last
= NULL
;
1579 de
->mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
;
1581 if (!de
->registered
) de
->u
.dir
.num_removable
= 0;
1582 de
->registered
= TRUE
;
1583 de
->show_unreg
= (boot_options
& OPTION_SHOW
) ? TRUE
: FALSE
;
1586 } /* End Function devfs_mk_dir */
1590 * devfs_find_handle - Find the handle of a devfs entry.
1591 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1592 * name is relative to the root of the devfs.
1593 * @name: The name of the entry.
1594 * @namelen: The number of characters in @name, not including a %NULL
1595 * terminator. If this is 0, then @name must be %NULL-terminated and the
1596 * length is computed internally.
1597 * @major: The major number. This is used if @name is %NULL.
1598 * @minor: The minor number. This is used if @name is %NULL.
1599 * @type: The type of special file to search for. This may be either
1600 * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
1601 * @traverse_symlinks: If %TRUE then symlink entries in the devfs namespace are
1602 * traversed. Symlinks pointing out of the devfs namespace will cause a
1603 * failure. Symlink traversal consumes stack space.
1605 * Returns a handle which may later be used in a call to devfs_unregister(),
1606 * devfs_get_flags(), or devfs_set_flags(). On failure %NULL is returned.
1609 devfs_handle_t
devfs_find_handle (devfs_handle_t dir
,
1610 const char *name
, unsigned int namelen
,
1611 unsigned int major
, unsigned int minor
,
1612 char type
, int traverse_symlinks
)
1616 if ( (name
!= NULL
) && (name
[0] == '\0') ) name
= NULL
;
1617 de
= find_entry (dir
, name
, namelen
, major
, minor
, type
,
1619 if (de
== NULL
) return NULL
;
1620 if (!de
->registered
) return NULL
;
1622 } /* End Function devfs_find_handle */
1626 * devfs_get_flags - Get the flags for a devfs entry.
1627 * @de: The handle to the device entry.
1628 * @flags: The flags are written here.
1630 * Returns 0 on success, else a negative error code.
1633 int devfs_get_flags (devfs_handle_t de
, unsigned int *flags
)
1635 unsigned int fl
= 0;
1637 if (de
== NULL
) return -EINVAL
;
1638 if (!de
->registered
) return -ENODEV
;
1639 if (de
->show_unreg
) fl
|= DEVFS_FL_SHOW_UNREG
;
1640 if (de
->hide
) fl
|= DEVFS_FL_HIDE
;
1641 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1643 if (de
->u
.fcb
.auto_owner
) fl
|= DEVFS_FL_AUTO_OWNER
;
1644 if (de
->u
.fcb
.aopen_notify
) fl
|= DEVFS_FL_AOPEN_NOTIFY
;
1645 if (de
->u
.fcb
.removable
) fl
|= DEVFS_FL_REMOVABLE
;
1649 } /* End Function devfs_get_flags */
1653 * devfs_set_flags - Set the flags for a devfs entry.
1654 * @de: The handle to the device entry.
1655 * @flags: The flags to set. Unset flags are cleared.
1657 * Returns 0 on success, else a negative error code.
1660 int devfs_set_flags (devfs_handle_t de
, unsigned int flags
)
1662 if (de
== NULL
) return -EINVAL
;
1663 if (!de
->registered
) return -ENODEV
;
1664 #ifdef CONFIG_DEVFS_DEBUG
1665 if (devfs_debug
& DEBUG_SET_FLAGS
)
1666 printk ("%s: devfs_set_flags(): de->name: \"%s\"\n",
1667 DEVFS_NAME
, de
->name
);
1669 de
->show_unreg
= (flags
& DEVFS_FL_SHOW_UNREG
) ? TRUE
: FALSE
;
1670 de
->hide
= (flags
& DEVFS_FL_HIDE
) ? TRUE
: FALSE
;
1671 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1673 de
->u
.fcb
.auto_owner
= (flags
& DEVFS_FL_AUTO_OWNER
) ? TRUE
: FALSE
;
1674 de
->u
.fcb
.aopen_notify
= (flags
& DEVFS_FL_AOPEN_NOTIFY
) ? TRUE
:FALSE
;
1675 if ( de
->u
.fcb
.removable
&& !(flags
& DEVFS_FL_REMOVABLE
) )
1677 de
->u
.fcb
.removable
= FALSE
;
1678 --de
->parent
->u
.dir
.num_removable
;
1680 else if ( !de
->u
.fcb
.removable
&& (flags
& DEVFS_FL_REMOVABLE
) )
1682 de
->u
.fcb
.removable
= TRUE
;
1683 ++de
->parent
->u
.dir
.num_removable
;
1687 } /* End Function devfs_set_flags */
1691 * devfs_get_maj_min - Get the major and minor numbers for a devfs entry.
1692 * @de: The handle to the device entry.
1693 * @major: The major number is written here. This may be %NULL.
1694 * @minor: The minor number is written here. This may be %NULL.
1696 * Returns 0 on success, else a negative error code.
1699 int devfs_get_maj_min (devfs_handle_t de
, unsigned int *major
,
1700 unsigned int *minor
)
1702 if (de
== NULL
) return -EINVAL
;
1703 if (!de
->registered
) return -ENODEV
;
1704 if ( S_ISDIR (de
->mode
) ) return -EISDIR
;
1705 if ( !S_ISCHR (de
->mode
) && !S_ISBLK (de
->mode
) ) return -EINVAL
;
1706 if (major
!= NULL
) *major
= de
->u
.fcb
.u
.device
.major
;
1707 if (minor
!= NULL
) *minor
= de
->u
.fcb
.u
.device
.minor
;
1709 } /* End Function devfs_get_maj_min */
1713 * devfs_get_handle_from_inode - Get the devfs handle for a VFS inode.
1714 * @inode: The VFS inode.
1716 * Returns the devfs handle on success, else %NULL.
1719 devfs_handle_t
devfs_get_handle_from_inode (struct inode
*inode
)
1721 if (!inode
|| !inode
->i_sb
) return NULL
;
1722 if (inode
->i_sb
->s_magic
!= DEVFS_SUPER_MAGIC
) return NULL
;
1723 return get_devfs_entry_from_vfs_inode (inode
);
1724 } /* End Function devfs_get_handle_from_inode */
1728 * devfs_generate_path - Generate a pathname for an entry, relative to the devfs root.
1729 * @de: The devfs entry.
1730 * @path: The buffer to write the pathname to. The pathname and '\0'
1731 * terminator will be written at the end of the buffer.
1732 * @buflen: The length of the buffer.
1734 * Returns the offset in the buffer where the pathname starts on success,
1735 * else a negative error code.
1738 int devfs_generate_path (devfs_handle_t de
, char *path
, int buflen
)
1742 if (de
== NULL
) return -EINVAL
;
1743 if (de
->namelen
>= buflen
) return -ENAMETOOLONG
; /* Must be first */
1744 if (de
->parent
== NULL
) return buflen
; /* Don't prepend root */
1745 pos
= buflen
- de
->namelen
- 1;
1746 memcpy (path
+ pos
, de
->name
, de
->namelen
);
1747 path
[buflen
- 1] = '\0';
1748 for (de
= de
->parent
; de
->parent
!= NULL
; de
= de
->parent
)
1750 if (pos
- de
->namelen
- 1 < 0) return -ENAMETOOLONG
;
1753 memcpy (path
+ pos
, de
->name
, de
->namelen
);
1756 } /* End Function devfs_generate_path */
1760 * devfs_get_ops - Get the device operations for a devfs entry.
1761 * @de: The handle to the device entry.
1763 * Returns a pointer to the device operations on success, else NULL.
1766 void *devfs_get_ops (devfs_handle_t de
)
1768 if (de
== NULL
) return NULL
;
1769 if (!de
->registered
) return NULL
;
1770 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1771 return de
->u
.fcb
.ops
;
1773 } /* End Function devfs_get_ops */
1777 * devfs_set_file_size - Set the file size for a devfs regular file.
1778 * @de: The handle to the device entry.
1779 * @size: The new file size.
1781 * Returns 0 on success, else a negative error code.
1784 int devfs_set_file_size (devfs_handle_t de
, unsigned long size
)
1786 if (de
== NULL
) return -EINVAL
;
1787 if (!de
->registered
) return -EINVAL
;
1788 if ( !S_ISREG (de
->mode
) ) return -EINVAL
;
1789 if (de
->u
.fcb
.u
.file
.size
== size
) return 0;
1790 de
->u
.fcb
.u
.file
.size
= size
;
1791 if (de
->inode
.dentry
== NULL
) return 0;
1792 if (de
->inode
.dentry
->d_inode
== NULL
) return 0;
1793 de
->inode
.dentry
->d_inode
->i_size
= size
;
1795 } /* End Function devfs_set_file_size */
1799 * devfs_get_info - Get the info pointer written to private_data of @de upon open.
1800 * @de: The handle to the device entry.
1802 * Returns the info pointer.
1804 void *devfs_get_info (devfs_handle_t de
)
1806 if (de
== NULL
) return NULL
;
1807 if (!de
->registered
) return NULL
;
1809 } /* End Function devfs_get_info */
1813 * devfs_set_info - Set the info pointer written to private_data upon open.
1814 * @de: The handle to the device entry.
1815 * @info: pointer to the data
1817 * Returns 0 on success, else a negative error code.
1819 int devfs_set_info (devfs_handle_t de
, void *info
)
1821 if (de
== NULL
) return -EINVAL
;
1822 if (!de
->registered
) return -EINVAL
;
1825 } /* End Function devfs_set_info */
1829 * devfs_get_parent - Get the parent device entry.
1830 * @de: The handle to the device entry.
1832 * Returns the parent device entry if it exists, else %NULL.
1834 devfs_handle_t
devfs_get_parent (devfs_handle_t de
)
1836 if (de
== NULL
) return NULL
;
1837 if (!de
->registered
) return NULL
;
1839 } /* End Function devfs_get_parent */
1843 * devfs_get_first_child - Get the first leaf node in a directory.
1844 * @de: The handle to the device entry.
1846 * Returns the leaf node device entry if it exists, else %NULL.
1849 devfs_handle_t
devfs_get_first_child (devfs_handle_t de
)
1851 if (de
== NULL
) return NULL
;
1852 if (!de
->registered
) return NULL
;
1853 if ( !S_ISDIR (de
->mode
) ) return NULL
;
1854 return de
->u
.dir
.first
;
1855 } /* End Function devfs_get_first_child */
1859 * devfs_get_next_sibling - Get the next sibling leaf node. for a device entry.
1860 * @de: The handle to the device entry.
1862 * Returns the leaf node device entry if it exists, else %NULL.
1865 devfs_handle_t
devfs_get_next_sibling (devfs_handle_t de
)
1867 if (de
== NULL
) return NULL
;
1868 if (!de
->registered
) return NULL
;
1870 } /* End Function devfs_get_next_sibling */
1874 * devfs_auto_unregister - Configure a devfs entry to be automatically unregistered.
1875 * @master: The master devfs entry. Only one slave may be registered.
1876 * @slave: The devfs entry which will be automatically unregistered when the
1877 * master entry is unregistered. It is illegal to call devfs_unregister()
1881 void devfs_auto_unregister (devfs_handle_t master
, devfs_handle_t slave
)
1883 if (master
== NULL
) return;
1884 if (master
->slave
!= NULL
)
1886 /* Because of the dumbness of the layers above, ignore duplicates */
1887 if (master
->slave
== slave
) return;
1888 printk ("%s: devfs_auto_unregister(): only one slave allowed\n",
1890 OOPS (" master: \"%s\" old slave: \"%s\" new slave: \"%s\"\n",
1891 master
->name
, master
->slave
->name
, slave
->name
);
1893 master
->slave
= slave
;
1894 } /* End Function devfs_auto_unregister */
1898 * devfs_get_unregister_slave - Get the slave entry which will be automatically unregistered.
1899 * @master: The master devfs entry.
1901 * Returns the slave which will be unregistered when @master is unregistered.
1904 devfs_handle_t
devfs_get_unregister_slave (devfs_handle_t master
)
1906 if (master
== NULL
) return NULL
;
1907 return master
->slave
;
1908 } /* End Function devfs_get_unregister_slave */
1912 * devfs_get_name - Get the name for a device entry in its parent directory.
1913 * @de: The handle to the device entry.
1914 * @namelen: The length of the name is written here. This may be %NULL.
1916 * Returns the name on success, else %NULL.
1919 const char *devfs_get_name (devfs_handle_t de
, unsigned int *namelen
)
1921 if (de
== NULL
) return NULL
;
1922 if (!de
->registered
) return NULL
;
1923 if (namelen
!= NULL
) *namelen
= de
->namelen
;
1925 } /* End Function devfs_get_name */
1929 * devfs_register_chrdev - Optionally register a conventional character driver.
1930 * @major: The major number for the driver.
1931 * @name: The name of the driver (as seen in /proc/devices).
1932 * @fops: The &file_operations structure pointer.
1934 * This function will register a character driver provided the "devfs=only"
1935 * option was not provided at boot time.
1936 * Returns 0 on success, else a negative error code on failure.
1939 int devfs_register_chrdev (unsigned int major
, const char *name
,
1940 struct file_operations
*fops
)
1942 if (boot_options
& OPTION_ONLY
) return 0;
1943 return register_chrdev (major
, name
, fops
);
1944 } /* End Function devfs_register_chrdev */
1948 * devfs_register_blkdev - Optionally register a conventional block driver.
1949 * @major: The major number for the driver.
1950 * @name: The name of the driver (as seen in /proc/devices).
1951 * @bdops: The &block_device_operations structure pointer.
1953 * This function will register a block driver provided the "devfs=only"
1954 * option was not provided at boot time.
1955 * Returns 0 on success, else a negative error code on failure.
1958 int devfs_register_blkdev (unsigned int major
, const char *name
,
1959 struct block_device_operations
*bdops
)
1961 if (boot_options
& OPTION_ONLY
) return 0;
1962 return register_blkdev (major
, name
, bdops
);
1963 } /* End Function devfs_register_blkdev */
1967 * devfs_unregister_chrdev - Optionally unregister a conventional character driver.
1968 * @major: The major number for the driver.
1969 * @name: The name of the driver (as seen in /proc/devices).
1971 * This function will unregister a character driver provided the "devfs=only"
1972 * option was not provided at boot time.
1973 * Returns 0 on success, else a negative error code on failure.
1976 int devfs_unregister_chrdev (unsigned int major
, const char *name
)
1978 if (boot_options
& OPTION_ONLY
) return 0;
1979 return unregister_chrdev (major
, name
);
1980 } /* End Function devfs_unregister_chrdev */
1984 * devfs_unregister_blkdev - Optionally unregister a conventional block driver.
1985 * @major: The major number for the driver.
1986 * @name: The name of the driver (as seen in /proc/devices).
1988 * This function will unregister a block driver provided the "devfs=only"
1989 * option was not provided at boot time.
1990 * Returns 0 on success, else a negative error code on failure.
1993 int devfs_unregister_blkdev (unsigned int major
, const char *name
)
1995 if (boot_options
& OPTION_ONLY
) return 0;
1996 return unregister_blkdev (major
, name
);
1997 } /* End Function devfs_unregister_blkdev */
2000 * devfs_setup - Process kernel boot options.
2001 * @str: The boot options after the "devfs=".
2004 static int __init
devfs_setup (char *str
)
2006 while ( (*str
!= '\0') && !isspace (*str
) )
2008 #ifdef CONFIG_DEVFS_DEBUG
2009 if (strncmp (str
, "dall", 4) == 0)
2011 devfs_debug_init
|= DEBUG_ALL
;
2014 else if (strncmp (str
, "dmod", 4) == 0)
2016 devfs_debug_init
|= DEBUG_MODULE_LOAD
;
2019 else if (strncmp (str
, "dreg", 4) == 0)
2021 devfs_debug_init
|= DEBUG_REGISTER
;
2024 else if (strncmp (str
, "dunreg", 6) == 0)
2026 devfs_debug_init
|= DEBUG_UNREGISTER
;
2029 else if (strncmp (str
, "diread", 6) == 0)
2031 devfs_debug_init
|= DEBUG_I_READ
;
2034 else if (strncmp (str
, "dchange", 7) == 0)
2036 devfs_debug_init
|= DEBUG_SET_FLAGS
;
2039 else if (strncmp (str
, "diwrite", 7) == 0)
2041 devfs_debug_init
|= DEBUG_I_WRITE
;
2044 else if (strncmp (str
, "dimknod", 7) == 0)
2046 devfs_debug_init
|= DEBUG_I_MKNOD
;
2049 else if (strncmp (str
, "dilookup", 8) == 0)
2051 devfs_debug_init
|= DEBUG_I_LOOKUP
;
2054 else if (strncmp (str
, "diunlink", 8) == 0)
2056 devfs_debug_init
|= DEBUG_I_UNLINK
;
2060 #endif /* CONFIG_DEVFS_DEBUG */
2061 if (strncmp (str
, "show", 4) == 0)
2063 boot_options
|= OPTION_SHOW
;
2066 else if (strncmp (str
, "only", 4) == 0)
2068 boot_options
|= OPTION_ONLY
;
2071 else if (strncmp (str
, "mount", 5) == 0)
2073 boot_options
&= ~OPTION_NOMOUNT
;
2076 else if (strncmp (str
, "nomount", 7) == 0)
2078 boot_options
|= OPTION_NOMOUNT
;
2083 if (*str
!= ',') return 0;
2087 } /* End Function devfs_setup */
2089 __setup("devfs=", devfs_setup
);
2091 EXPORT_SYMBOL(devfs_register
);
2092 EXPORT_SYMBOL(devfs_unregister
);
2093 EXPORT_SYMBOL(devfs_mk_symlink
);
2094 EXPORT_SYMBOL(devfs_mk_dir
);
2095 EXPORT_SYMBOL(devfs_find_handle
);
2096 EXPORT_SYMBOL(devfs_get_flags
);
2097 EXPORT_SYMBOL(devfs_set_flags
);
2098 EXPORT_SYMBOL(devfs_get_maj_min
);
2099 EXPORT_SYMBOL(devfs_get_handle_from_inode
);
2100 EXPORT_SYMBOL(devfs_generate_path
);
2101 EXPORT_SYMBOL(devfs_get_ops
);
2102 EXPORT_SYMBOL(devfs_set_file_size
);
2103 EXPORT_SYMBOL(devfs_get_info
);
2104 EXPORT_SYMBOL(devfs_set_info
);
2105 EXPORT_SYMBOL(devfs_get_parent
);
2106 EXPORT_SYMBOL(devfs_get_first_child
);
2107 EXPORT_SYMBOL(devfs_get_next_sibling
);
2108 EXPORT_SYMBOL(devfs_auto_unregister
);
2109 EXPORT_SYMBOL(devfs_get_unregister_slave
);
2110 EXPORT_SYMBOL(devfs_register_chrdev
);
2111 EXPORT_SYMBOL(devfs_register_blkdev
);
2112 EXPORT_SYMBOL(devfs_unregister_chrdev
);
2113 EXPORT_SYMBOL(devfs_unregister_blkdev
);
2117 * try_modload - Notify devfsd of an inode lookup.
2118 * @parent: The parent devfs entry.
2119 * @fs_info: The filesystem info.
2120 * @name: The device name.
2121 * @namelen: The number of characters in @name.
2122 * @buf: A working area that will be used. This must not go out of scope until
2123 * devfsd is idle again.
2125 * Returns 0 on success, else a negative error code.
2128 static int try_modload (struct devfs_entry
*parent
, struct fs_info
*fs_info
,
2129 const char *name
, unsigned namelen
,
2130 char buf
[STRING_LENGTH
])
2134 if ( !( fs_info
->devfsd_event_mask
& (1 << DEVFSD_NOTIFY_LOOKUP
) ) )
2136 if ( is_devfsd_or_child (fs_info
) ) return -ENOENT
;
2137 if (namelen
>= STRING_LENGTH
) return -ENAMETOOLONG
;
2138 memcpy (buf
+ STRING_LENGTH
- namelen
- 1, name
, namelen
);
2139 buf
[STRING_LENGTH
- 1] = '\0';
2140 pos
= devfs_generate_path (parent
, buf
, STRING_LENGTH
- namelen
- 1);
2141 if (pos
< 0) return pos
;
2142 buf
[STRING_LENGTH
- namelen
- 2] = '/';
2143 if ( !devfsd_notify_one (buf
+ pos
, DEVFSD_NOTIFY_LOOKUP
, 0,
2144 current
->euid
, current
->egid
, fs_info
) )
2146 /* Possible success */
2148 } /* End Function try_modload */
2152 * check_disc_changed - Check if a removable disc was changed.
2155 * Returns 1 if the media was changed, else 0.
2158 static int check_disc_changed (struct devfs_entry
*de
)
2161 kdev_t dev
= MKDEV (de
->u
.fcb
.u
.device
.major
, de
->u
.fcb
.u
.device
.minor
);
2162 struct block_device_operations
*bdops
= de
->u
.fcb
.ops
;
2163 struct super_block
* sb
;
2164 extern int warn_no_part
;
2166 if ( !S_ISBLK (de
->mode
) ) return 0;
2167 if (bdops
== NULL
) return 0;
2168 if (bdops
->check_media_change
== NULL
) return 0;
2169 if ( !bdops
->check_media_change (dev
) ) return 0;
2170 printk ( KERN_DEBUG
"VFS: Disk change detected on device %s\n",
2172 sb
= get_super (dev
);
2173 if ( sb
&& invalidate_inodes (sb
) )
2174 printk("VFS: busy inodes on changed media..\n");
2175 invalidate_buffers (dev
);
2176 /* Ugly hack to disable messages about unable to read partition table */
2179 if (bdops
->revalidate
) bdops
->revalidate (dev
);
2182 } /* End Function check_disc_changed */
2186 * scan_dir_for_removable - Scan a directory for removable media devices and check media.
2187 * @dir: The directory.
2190 static void scan_dir_for_removable (struct devfs_entry
*dir
)
2192 struct devfs_entry
*de
;
2194 if (dir
->u
.dir
.num_removable
< 1) return;
2195 for (de
= dir
->u
.dir
.first
; de
!= NULL
; de
= de
->next
)
2197 if (!de
->registered
) continue;
2198 if ( !S_ISBLK (de
->mode
) ) continue;
2199 if (!de
->u
.fcb
.removable
) continue;
2200 check_disc_changed (de
);
2202 } /* End Function scan_dir_for_removable */
2205 * get_removable_partition - Get removable media partition.
2206 * @dir: The parent directory.
2207 * @name: The name of the entry.
2208 * @namelen: The number of characters in <<name>>.
2210 * Returns 1 if the media was changed, else 0.
2213 static int get_removable_partition (struct devfs_entry
*dir
, const char *name
,
2214 unsigned int namelen
)
2216 struct devfs_entry
*de
;
2218 for (de
= dir
->u
.dir
.first
; de
!= NULL
; de
= de
->next
)
2220 if (!de
->registered
) continue;
2221 if ( !S_ISBLK (de
->mode
) ) continue;
2222 if (!de
->u
.fcb
.removable
) continue;
2223 if (strcmp (de
->name
, "disc") == 0) return check_disc_changed (de
);
2224 /* Support for names where the partition is appended to the disc name
2226 if (de
->namelen
>= namelen
) continue;
2227 if (strncmp (de
->name
, name
, de
->namelen
) != 0) continue;
2228 return check_disc_changed (de
);
2231 } /* End Function get_removable_partition */
2234 /* Superblock operations follow */
2236 static struct inode_operations devfs_iops
;
2237 static struct inode_operations devfs_dir_iops
;
2238 static struct file_operations devfs_fops
;
2239 static struct inode_operations devfs_symlink_iops
;
2241 static void devfs_read_inode (struct inode
*inode
)
2243 struct devfs_entry
*de
;
2245 de
= get_devfs_entry_from_vfs_inode (inode
);
2248 printk ("%s: read_inode(%d): VFS inode: %p NO devfs_entry\n",
2249 DEVFS_NAME
, (int) inode
->i_ino
, inode
);
2252 #ifdef CONFIG_DEVFS_DEBUG
2253 if (devfs_debug
& DEBUG_I_READ
)
2254 printk ("%s: read_inode(%d): VFS inode: %p devfs_entry: %p\n",
2255 DEVFS_NAME
, (int) inode
->i_ino
, inode
, de
);
2258 inode
->i_blocks
= 0;
2259 inode
->i_blksize
= 1024;
2260 inode
->i_op
= &devfs_iops
;
2261 inode
->i_fop
= &devfs_fops
;
2262 inode
->i_rdev
= NODEV
;
2263 if ( S_ISCHR (de
->inode
.mode
) )
2265 inode
->i_rdev
= MKDEV (de
->u
.fcb
.u
.device
.major
,
2266 de
->u
.fcb
.u
.device
.minor
);
2268 else if ( S_ISBLK (de
->inode
.mode
) )
2270 inode
->i_rdev
= MKDEV (de
->u
.fcb
.u
.device
.major
,
2271 de
->u
.fcb
.u
.device
.minor
);
2272 inode
->i_bdev
= bdget (inode
->i_rdev
);
2275 if (!inode
->i_bdev
->bd_op
&& de
->u
.fcb
.ops
)
2276 inode
->i_bdev
->bd_op
= de
->u
.fcb
.ops
;
2278 else printk ("%s: read_inode(%d): no block device from bdget()\n",
2279 DEVFS_NAME
, (int) inode
->i_ino
);
2281 else if ( S_ISFIFO (de
->inode
.mode
) ) inode
->i_fop
= &def_fifo_fops
;
2282 else if ( S_ISREG (de
->inode
.mode
) ) inode
->i_size
= de
->u
.fcb
.u
.file
.size
;
2283 else if ( S_ISDIR (de
->inode
.mode
) ) inode
->i_op
= &devfs_dir_iops
;
2284 else if ( S_ISLNK (de
->inode
.mode
) )
2286 inode
->i_op
= &devfs_symlink_iops
;
2287 inode
->i_size
= de
->u
.symlink
.length
;
2289 inode
->i_mode
= de
->inode
.mode
;
2290 inode
->i_uid
= de
->inode
.uid
;
2291 inode
->i_gid
= de
->inode
.gid
;
2292 inode
->i_atime
= de
->inode
.atime
;
2293 inode
->i_mtime
= de
->inode
.mtime
;
2294 inode
->i_ctime
= de
->inode
.ctime
;
2295 inode
->i_nlink
= de
->inode
.nlink
;
2296 #ifdef CONFIG_DEVFS_DEBUG
2297 if (devfs_debug
& DEBUG_I_READ
)
2298 printk ("%s: mode: 0%o uid: %d gid: %d\n",
2299 DEVFS_NAME
, (int) inode
->i_mode
,
2300 (int) inode
->i_uid
, (int) inode
->i_gid
);
2302 } /* End Function devfs_read_inode */
2304 static void devfs_write_inode (struct inode
*inode
, int unused
)
2307 struct devfs_entry
*de
;
2308 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
2310 if (inode
->i_ino
< FIRST_INODE
) return;
2311 index
= inode
->i_ino
- FIRST_INODE
;
2312 if (index
>= fs_info
->num_inodes
)
2314 printk ("%s: writing inode: %lu for which there is no entry!\n",
2315 DEVFS_NAME
, inode
->i_ino
);
2318 de
= fs_info
->table
[index
];
2319 #ifdef CONFIG_DEVFS_DEBUG
2320 if (devfs_debug
& DEBUG_I_WRITE
)
2322 printk ("%s: write_inode(%d): VFS inode: %p devfs_entry: %p\n",
2323 DEVFS_NAME
, (int) inode
->i_ino
, inode
, de
);
2324 printk ("%s: mode: 0%o uid: %d gid: %d\n",
2325 DEVFS_NAME
, (int) inode
->i_mode
,
2326 (int) inode
->i_uid
, (int) inode
->i_gid
);
2329 de
->inode
.mode
= inode
->i_mode
;
2330 de
->inode
.uid
= inode
->i_uid
;
2331 de
->inode
.gid
= inode
->i_gid
;
2332 de
->inode
.atime
= inode
->i_atime
;
2333 de
->inode
.mtime
= inode
->i_mtime
;
2334 de
->inode
.ctime
= inode
->i_ctime
;
2335 } /* End Function devfs_write_inode */
2337 static int devfs_notify_change (struct dentry
*dentry
, struct iattr
*iattr
)
2340 struct devfs_entry
*de
;
2341 struct inode
*inode
= dentry
->d_inode
;
2342 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
2344 de
= get_devfs_entry_from_vfs_inode (inode
);
2345 if (de
== NULL
) return -ENODEV
;
2346 retval
= inode_change_ok (inode
, iattr
);
2347 if (retval
!= 0) return retval
;
2348 inode_setattr (inode
, iattr
);
2349 if ( iattr
->ia_valid
& (ATTR_MODE
| ATTR_UID
| ATTR_GID
) )
2350 devfsd_notify_one (de
, DEVFSD_NOTIFY_CHANGE
, inode
->i_mode
,
2351 inode
->i_uid
, inode
->i_gid
, fs_info
);
2353 } /* End Function devfs_notify_change */
2355 static int devfs_statfs (struct super_block
*sb
, struct statfs
*buf
)
2357 buf
->f_type
= DEVFS_SUPER_MAGIC
;
2358 buf
->f_bsize
= PAGE_SIZE
/ sizeof (long);
2362 buf
->f_namelen
= NAME_MAX
;
2364 } /* End Function devfs_statfs */
2366 static struct super_operations devfs_sops
=
2368 read_inode
: devfs_read_inode
,
2369 write_inode
: devfs_write_inode
,
2370 statfs
: devfs_statfs
,
2375 * get_vfs_inode - Get a VFS inode.
2376 * @sb: The super block.
2377 * @di: The devfs inode.
2378 * @dentry The dentry to register with the devfs inode.
2380 * Returns the inode on success, else %NULL.
2383 static struct inode
*get_vfs_inode (struct super_block
*sb
,
2384 struct devfs_entry
*de
,
2385 struct dentry
*dentry
)
2387 struct inode
*inode
;
2389 if (de
->inode
.dentry
!= NULL
)
2391 printk ("%s: get_vfs_inode(%u): old de->inode.dentry: %p \"%s\" new dentry: %p \"%s\"\n",
2392 DEVFS_NAME
, de
->inode
.ino
,
2393 de
->inode
.dentry
, de
->inode
.dentry
->d_name
.name
,
2394 dentry
, dentry
->d_name
.name
);
2395 printk (" old inode: %p\n", de
->inode
.dentry
->d_inode
);
2398 if ( ( inode
= iget (sb
, de
->inode
.ino
) ) == NULL
) return NULL
;
2399 de
->inode
.dentry
= dentry
;
2401 } /* End Function get_vfs_inode */
2404 /* File operations for device entries follow */
2406 static ssize_t
devfs_read (struct file
*file
, char *buf
, size_t len
, loff_t
*ppos
)
2408 if ( S_ISDIR (file
->f_dentry
->d_inode
->i_mode
) ) return -EISDIR
;
2410 } /* End Function devfs_read */
2412 static int devfs_readdir (struct file
*file
, void *dirent
, filldir_t filldir
)
2416 struct fs_info
*fs_info
;
2417 struct devfs_entry
*parent
, *de
;
2418 struct inode
*inode
= file
->f_dentry
->d_inode
;
2422 printk ("%s: readdir(): NULL inode\n", DEVFS_NAME
);
2425 if ( !S_ISDIR (inode
->i_mode
) )
2427 printk ("%s: readdir(): inode is not a directory\n", DEVFS_NAME
);
2430 fs_info
= inode
->i_sb
->u
.generic_sbp
;
2431 parent
= get_devfs_entry_from_vfs_inode (file
->f_dentry
->d_inode
);
2432 if ( (long) file
->f_pos
< 0 ) return -EINVAL
;
2433 #ifdef CONFIG_DEVFS_DEBUG
2434 if (devfs_debug
& DEBUG_F_READDIR
)
2435 printk ("%s: readdir(): fs_info: %p pos: %ld\n", DEVFS_NAME
,
2436 fs_info
, (long) file
->f_pos
);
2438 switch ( (long) file
->f_pos
)
2441 scan_dir_for_removable (parent
);
2442 err
= (*filldir
) (dirent
, "..", 2, file
->f_pos
,
2443 file
->f_dentry
->d_parent
->d_inode
->i_ino
);
2444 if (err
== -EINVAL
) break;
2445 if (err
< 0) return err
;
2450 err
= (*filldir
) (dirent
, ".", 1, file
->f_pos
, inode
->i_ino
);
2451 if (err
== -EINVAL
) break;
2452 if (err
< 0) return err
;
2458 count
= file
->f_pos
- 2;
2459 for (de
= parent
->u
.dir
.first
; (de
!= NULL
) && (count
> 0);
2461 if ( !IS_HIDDEN (de
) ) --count
;
2462 /* Now add all remaining entries */
2463 for (; de
!= NULL
; de
= de
->next
)
2465 if ( IS_HIDDEN (de
) ) continue;
2466 err
= (*filldir
) (dirent
, de
->name
, de
->namelen
,
2467 file
->f_pos
, de
->inode
.ino
);
2468 if (err
== -EINVAL
) break;
2469 if (err
< 0) return err
;
2476 } /* End Function devfs_readdir */
2478 static int devfs_open (struct inode
*inode
, struct file
*file
)
2481 struct fcb_type
*df
;
2482 struct devfs_entry
*de
;
2483 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
2485 de
= get_devfs_entry_from_vfs_inode (inode
);
2486 if (de
== NULL
) return -ENODEV
;
2487 if ( S_ISDIR (de
->mode
) ) return 0;
2489 if (!de
->registered
) return -ENODEV
;
2490 file
->private_data
= de
->info
;
2491 if ( S_ISBLK (inode
->i_mode
) )
2493 file
->f_op
= &def_blk_fops
;
2494 if (df
->ops
) inode
->i_bdev
->bd_op
= df
->ops
;
2496 else file
->f_op
= fops_get((struct file_operations
*)df
->ops
);
2498 err
= file
->f_op
->open
? (*file
->f_op
->open
) (inode
, file
) : 0;
2501 /* Fallback to legacy scheme */
2502 if ( S_ISCHR (inode
->i_mode
) ) err
= chrdev_open (inode
, file
);
2505 if (err
< 0) return err
;
2506 /* Open was successful */
2507 if (df
->open
) return 0;
2508 df
->open
= TRUE
; /* This is the first open */
2511 /* Change the ownership/protection */
2512 de
->inode
.mode
= (de
->inode
.mode
& ~S_IALLUGO
) |(de
->mode
& S_IRWXUGO
);
2513 de
->inode
.uid
= current
->euid
;
2514 de
->inode
.gid
= current
->egid
;
2515 inode
->i_mode
= de
->inode
.mode
;
2516 inode
->i_uid
= de
->inode
.uid
;
2517 inode
->i_gid
= de
->inode
.gid
;
2519 if (df
->aopen_notify
)
2520 devfsd_notify_one (de
, DEVFSD_NOTIFY_ASYNC_OPEN
, inode
->i_mode
,
2521 current
->euid
, current
->egid
, fs_info
);
2523 } /* End Function devfs_open */
2525 static struct file_operations devfs_fops
=
2528 readdir
: devfs_readdir
,
2533 /* Dentry operations for device entries follow */
2537 * devfs_d_release - Callback for when a dentry is freed.
2538 * @dentry: The dentry.
2541 static void devfs_d_release (struct dentry
*dentry
)
2543 #ifdef CONFIG_DEVFS_DEBUG
2544 struct inode
*inode
= dentry
->d_inode
;
2546 if (devfs_debug
& DEBUG_D_RELEASE
)
2547 printk ("%s: d_release(): dentry: %p inode: %p\n",
2548 DEVFS_NAME
, dentry
, inode
);
2550 } /* End Function devfs_d_release */
2553 * devfs_d_iput - Callback for when a dentry loses its inode.
2554 * @dentry: The dentry.
2555 * @inode: The inode.
2558 static void devfs_d_iput (struct dentry
*dentry
, struct inode
*inode
)
2560 struct devfs_entry
*de
;
2562 de
= get_devfs_entry_from_vfs_inode (inode
);
2563 #ifdef CONFIG_DEVFS_DEBUG
2564 if (devfs_debug
& DEBUG_D_IPUT
)
2565 printk ("%s: d_iput(): dentry: %p inode: %p de: %p de->dentry: %p\n",
2566 DEVFS_NAME
, dentry
, inode
, de
, de
->inode
.dentry
);
2568 if (de
->inode
.dentry
== dentry
)
2570 de
->inode
.dentry
= NULL
;
2573 } /* End Function devfs_d_iput */
2575 static int devfs_d_delete (struct dentry
*dentry
);
2577 static struct dentry_operations devfs_dops
=
2579 d_delete
: devfs_d_delete
,
2580 d_release
: devfs_d_release
,
2581 d_iput
: devfs_d_iput
,
2584 static int devfs_d_revalidate_wait (struct dentry
*dentry
, int flags
);
2586 static struct dentry_operations devfs_wait_dops
=
2588 d_delete
: devfs_d_delete
,
2589 d_release
: devfs_d_release
,
2590 d_iput
: devfs_d_iput
,
2591 d_revalidate
: devfs_d_revalidate_wait
,
2595 * devfs_d_delete - Callback for when all files for a dentry are closed.
2596 * @detry: The dentry.
2599 static int devfs_d_delete (struct dentry
*dentry
)
2601 struct inode
*inode
= dentry
->d_inode
;
2602 struct devfs_entry
*de
;
2603 struct fs_info
*fs_info
;
2605 if (dentry
->d_op
== &devfs_wait_dops
) dentry
->d_op
= &devfs_dops
;
2606 /* Unhash dentry if negative (has no inode) */
2609 #ifdef CONFIG_DEVFS_DEBUG
2610 if (devfs_debug
& DEBUG_D_DELETE
)
2611 printk ("%s: d_delete(): dropping negative dentry: %p\n",
2612 DEVFS_NAME
, dentry
);
2616 fs_info
= inode
->i_sb
->u
.generic_sbp
;
2617 de
= get_devfs_entry_from_vfs_inode (inode
);
2618 #ifdef CONFIG_DEVFS_DEBUG
2619 if (devfs_debug
& DEBUG_D_DELETE
)
2620 printk ("%s: d_delete(): dentry: %p inode: %p devfs_entry: %p\n",
2621 DEVFS_NAME
, dentry
, inode
, de
);
2623 if (de
== NULL
) return 0;
2624 if ( !S_ISCHR (de
->mode
) && !S_ISBLK (de
->mode
) && !S_ISREG (de
->mode
) )
2626 if (!de
->u
.fcb
.open
) return 0;
2627 de
->u
.fcb
.open
= FALSE
;
2628 if (de
->u
.fcb
.aopen_notify
)
2629 devfsd_notify_one (de
, DEVFSD_NOTIFY_CLOSE
, inode
->i_mode
,
2630 current
->euid
, current
->egid
, fs_info
);
2631 if (!de
->u
.fcb
.auto_owner
) return 0;
2632 /* Change the ownership/protection back */
2633 de
->inode
.mode
= (de
->inode
.mode
& ~S_IALLUGO
) | S_IRUGO
| S_IWUGO
;
2634 de
->inode
.uid
= de
->u
.fcb
.default_uid
;
2635 de
->inode
.gid
= de
->u
.fcb
.default_gid
;
2636 inode
->i_mode
= de
->inode
.mode
;
2637 inode
->i_uid
= de
->inode
.uid
;
2638 inode
->i_gid
= de
->inode
.gid
;
2640 } /* End Function devfs_d_delete */
2642 static int devfs_d_revalidate_wait (struct dentry
*dentry
, int flags
)
2644 devfs_handle_t de
= dentry
->d_fsdata
;
2645 struct inode
*dir
= dentry
->d_parent
->d_inode
;
2646 struct fs_info
*fs_info
= dir
->i_sb
->u
.generic_sbp
;
2648 if (!de
|| de
->registered
)
2650 if ( !dentry
->d_inode
&& is_devfsd_or_child (fs_info
) )
2652 struct inode
*inode
;
2654 #ifdef CONFIG_DEVFS_DEBUG
2655 char txt
[STRING_LENGTH
];
2657 memset (txt
, 0, STRING_LENGTH
);
2658 memcpy (txt
, dentry
->d_name
.name
,
2659 (dentry
->d_name
.len
>= STRING_LENGTH
) ?
2660 (STRING_LENGTH
- 1) : dentry
->d_name
.len
);
2661 if (devfs_debug
& DEBUG_I_LOOKUP
)
2662 printk ("%s: d_revalidate(): dentry: %p name: \"%s\" by: \"%s\"\n",
2663 DEVFS_NAME
, dentry
, txt
, current
->comm
);
2667 devfs_handle_t parent
;
2669 parent
= get_devfs_entry_from_vfs_inode (dir
);
2670 de
= search_for_entry_in_dir (parent
, dentry
->d_name
.name
,
2671 dentry
->d_name
.len
, FALSE
);
2673 if (de
== NULL
) return 1;
2674 /* Create an inode, now that the driver information is available
2676 if (de
->no_persistence
) update_devfs_inode_from_entry (de
);
2677 else if (de
->inode
.ctime
== 0) update_devfs_inode_from_entry (de
);
2678 else de
->inode
.mode
=
2679 (de
->mode
& ~S_IALLUGO
) | (de
->inode
.mode
& S_IALLUGO
);
2680 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2682 #ifdef CONFIG_DEVFS_DEBUG
2683 if (devfs_debug
& DEBUG_I_LOOKUP
)
2684 printk ("%s: d_revalidate(): new VFS inode(%u): %p devfs_entry: %p\n",
2685 DEVFS_NAME
, de
->inode
.ino
, inode
, de
);
2687 d_instantiate (dentry
, inode
);
2691 if ( wait_for_devfsd_finished (fs_info
) ) dentry
->d_op
= &devfs_dops
;
2693 } /* End Function devfs_d_revalidate_wait */
2696 /* Inode operations for device entries follow */
2698 static struct dentry
*devfs_lookup (struct inode
*dir
, struct dentry
*dentry
)
2700 struct fs_info
*fs_info
;
2701 struct devfs_entry
*parent
, *de
;
2702 struct inode
*inode
;
2703 char txt
[STRING_LENGTH
];
2705 /* Set up the dentry operations before anything else, to ensure cleaning
2707 dentry
->d_op
= &devfs_dops
;
2710 printk ("%s: lookup(): NULL directory inode\n", DEVFS_NAME
);
2711 return ERR_PTR (-ENOTDIR
);
2713 if ( !S_ISDIR (dir
->i_mode
) ) return ERR_PTR (-ENOTDIR
);
2714 memset (txt
, 0, STRING_LENGTH
);
2715 memcpy (txt
, dentry
->d_name
.name
,
2716 (dentry
->d_name
.len
>= STRING_LENGTH
) ?
2717 (STRING_LENGTH
- 1) : dentry
->d_name
.len
);
2718 #ifdef CONFIG_DEVFS_DEBUG
2719 if (devfs_debug
& DEBUG_I_LOOKUP
)
2720 printk ("%s: lookup(%s): dentry: %p by: \"%s\"\n",
2721 DEVFS_NAME
, txt
, dentry
, current
->comm
);
2723 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2724 /* First try to get the devfs entry for this directory */
2725 parent
= get_devfs_entry_from_vfs_inode (dir
);
2726 if (parent
== NULL
) return ERR_PTR (-EINVAL
);
2727 if (!parent
->registered
) return ERR_PTR (-ENOENT
);
2728 /* Try to reclaim an existing devfs entry */
2729 de
= search_for_entry_in_dir (parent
,
2730 dentry
->d_name
.name
, dentry
->d_name
.len
,
2732 if ( ( (de
== NULL
) || !de
->registered
) &&
2733 (parent
->u
.dir
.num_removable
> 0) &&
2734 get_removable_partition (parent
, dentry
->d_name
.name
,
2735 dentry
->d_name
.len
) )
2738 de
= search_for_entry_in_dir (parent
, dentry
->d_name
.name
,
2739 dentry
->d_name
.len
, FALSE
);
2741 if ( (de
== NULL
) || !de
->registered
)
2743 /* Try with devfsd. For any kind of failure, leave a negative dentry
2744 so someone else can deal with it (in the case where the sysadmin
2745 does a mknod()). It's important to do this before hashing the
2746 dentry, so that the devfsd queue is filled before revalidates
2748 if (try_modload (parent
, fs_info
,
2749 dentry
->d_name
.name
, dentry
->d_name
.len
, txt
) < 0)
2751 d_add (dentry
, NULL
);
2754 /* devfsd claimed success */
2755 dentry
->d_op
= &devfs_wait_dops
;
2756 dentry
->d_fsdata
= de
;
2757 d_add (dentry
, NULL
); /* Open the floodgates */
2758 /* Unlock directory semaphore, which will release any waiters. They
2759 will get the hashed dentry, and may be forced to wait for
2762 devfs_d_revalidate_wait (dentry
, 0); /* I might have to wait too */
2763 down (&dir
->i_sem
); /* Grab it again because them's the rules */
2764 /* If someone else has been so kind as to make the inode, we go home
2766 if (dentry
->d_inode
) return NULL
;
2767 if (de
&& !de
->registered
) return NULL
;
2769 de
= search_for_entry_in_dir (parent
, dentry
->d_name
.name
,
2770 dentry
->d_name
.len
, FALSE
);
2771 if (de
== NULL
) return NULL
;
2772 /* OK, there's an entry now, but no VFS inode yet */
2776 dentry
->d_op
= &devfs_wait_dops
;
2777 d_add (dentry
, NULL
); /* Open the floodgates */
2779 /* Create an inode, now that the driver information is available */
2780 if (de
->no_persistence
) update_devfs_inode_from_entry (de
);
2781 else if (de
->inode
.ctime
== 0) update_devfs_inode_from_entry (de
);
2782 else de
->inode
.mode
=
2783 (de
->mode
& ~S_IALLUGO
) | (de
->inode
.mode
& S_IALLUGO
);
2784 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2785 return ERR_PTR (-ENOMEM
);
2786 #ifdef CONFIG_DEVFS_DEBUG
2787 if (devfs_debug
& DEBUG_I_LOOKUP
)
2788 printk ("%s: lookup(): new VFS inode(%u): %p devfs_entry: %p\n",
2789 DEVFS_NAME
, de
->inode
.ino
, inode
, de
);
2791 d_instantiate (dentry
, inode
);
2792 /* Unlock directory semaphore, which will release any waiters. They will
2793 get the hashed dentry, and may be forced to wait for revalidation */
2795 if (dentry
->d_op
== &devfs_wait_dops
)
2796 devfs_d_revalidate_wait (dentry
, 0); /* I might have to wait too */
2797 down (&dir
->i_sem
); /* Grab it again because them's the rules */
2799 } /* End Function devfs_lookup */
2801 static int devfs_link (struct dentry
*old_dentry
, struct inode
*dir
,
2802 struct dentry
*dentry
)
2804 /*struct inode *inode = old_dentry->d_inode;*/
2805 char txt
[STRING_LENGTH
];
2807 memset (txt
, 0, STRING_LENGTH
);
2808 memcpy (txt
, old_dentry
->d_name
.name
, old_dentry
->d_name
.len
);
2809 txt
[STRING_LENGTH
- 1] = '\0';
2810 printk ("%s: link of \"%s\"\n", DEVFS_NAME
, txt
);
2812 } /* End Function devfs_link */
2814 static int devfs_unlink (struct inode
*dir
, struct dentry
*dentry
)
2816 struct devfs_entry
*de
;
2818 #ifdef CONFIG_DEVFS_DEBUG
2819 char txt
[STRING_LENGTH
];
2821 if (devfs_debug
& DEBUG_I_UNLINK
)
2823 memset (txt
, 0, STRING_LENGTH
);
2824 memcpy (txt
, dentry
->d_name
.name
, dentry
->d_name
.len
);
2825 txt
[STRING_LENGTH
- 1] = '\0';
2826 printk ("%s: unlink(%s)\n", DEVFS_NAME
, txt
);
2830 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2831 if (!dentry
|| !dentry
->d_inode
) return -ENOENT
;
2832 de
= get_devfs_entry_from_vfs_inode (dentry
->d_inode
);
2833 if (de
== NULL
) return -ENOENT
;
2834 if (!de
->registered
) return -ENOENT
;
2835 de
->registered
= FALSE
;
2839 } /* End Function devfs_unlink */
2841 static int devfs_symlink (struct inode
*dir
, struct dentry
*dentry
,
2842 const char *symname
)
2845 struct fs_info
*fs_info
;
2846 struct devfs_entry
*parent
, *de
;
2847 struct inode
*inode
;
2849 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2850 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2851 /* First try to get the devfs entry for this directory */
2852 parent
= get_devfs_entry_from_vfs_inode (dir
);
2853 if (parent
== NULL
) return -EINVAL
;
2854 if (!parent
->registered
) return -ENOENT
;
2855 err
= devfs_mk_symlink (parent
, dentry
->d_name
.name
, dentry
->d_name
.len
,
2856 DEVFS_FL_NONE
, symname
, 0, &de
, NULL
);
2857 #ifdef CONFIG_DEVFS_DEBUG
2858 if (devfs_debug
& DEBUG_DISABLED
)
2859 printk ("%s: symlink(): errcode from <devfs_mk_symlink>: %d\n",
2862 if (err
< 0) return err
;
2863 de
->inode
.mode
= de
->mode
;
2864 de
->inode
.atime
= CURRENT_TIME
;
2865 de
->inode
.mtime
= CURRENT_TIME
;
2866 de
->inode
.ctime
= CURRENT_TIME
;
2867 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2869 #ifdef CONFIG_DEVFS_DEBUG
2870 if (devfs_debug
& DEBUG_DISABLED
)
2871 printk ("%s: symlink(): new VFS inode(%u): %p dentry: %p\n",
2872 DEVFS_NAME
, de
->inode
.ino
, inode
, dentry
);
2875 d_instantiate (dentry
, inode
);
2876 devfsd_notify_one (de
, DEVFSD_NOTIFY_CREATE
, inode
->i_mode
,
2877 inode
->i_uid
, inode
->i_gid
, fs_info
);
2879 } /* End Function devfs_symlink */
2881 static int devfs_mkdir (struct inode
*dir
, struct dentry
*dentry
, int mode
)
2884 struct fs_info
*fs_info
;
2885 struct devfs_entry
*parent
, *de
;
2886 struct inode
*inode
;
2888 mode
= (mode
& ~S_IFMT
) | S_IFDIR
;
2889 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2890 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2891 /* We are allowed to create the directory */
2892 /* First try to get the devfs entry for this directory */
2893 parent
= get_devfs_entry_from_vfs_inode (dir
);
2894 if (parent
== NULL
) return -EINVAL
;
2895 if (!parent
->registered
) return -ENOENT
;
2896 /* Try to reclaim an existing devfs entry, create if there isn't one */
2897 de
= search_for_entry (parent
, dentry
->d_name
.name
, dentry
->d_name
.len
,
2898 FALSE
, TRUE
, &is_new
, FALSE
);
2899 if (de
== NULL
) return -ENOMEM
;
2902 printk ("%s: mkdir(): existing entry\n", DEVFS_NAME
);
2905 de
->registered
= TRUE
;
2907 if (!S_ISDIR (de
->mode
) && !is_new
)
2909 /* Transmogrifying an old entry */
2910 de
->u
.dir
.first
= NULL
;
2911 de
->u
.dir
.last
= NULL
;
2914 de
->u
.dir
.num_removable
= 0;
2915 de
->inode
.mode
= mode
;
2916 de
->inode
.uid
= current
->euid
;
2917 de
->inode
.gid
= current
->egid
;
2918 de
->inode
.atime
= CURRENT_TIME
;
2919 de
->inode
.mtime
= CURRENT_TIME
;
2920 de
->inode
.ctime
= CURRENT_TIME
;
2921 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2923 #ifdef CONFIG_DEVFS_DEBUG
2924 if (devfs_debug
& DEBUG_DISABLED
)
2925 printk ("%s: mkdir(): new VFS inode(%u): %p dentry: %p\n",
2926 DEVFS_NAME
, de
->inode
.ino
, inode
, dentry
);
2928 d_instantiate (dentry
, inode
);
2929 devfsd_notify_one (de
, DEVFSD_NOTIFY_CREATE
, inode
->i_mode
,
2930 inode
->i_uid
, inode
->i_gid
, fs_info
);
2932 } /* End Function devfs_mkdir */
2934 static int devfs_rmdir (struct inode
*dir
, struct dentry
*dentry
)
2936 int has_children
= FALSE
;
2937 struct fs_info
*fs_info
;
2938 struct devfs_entry
*de
, *child
;
2939 struct inode
*inode
= dentry
->d_inode
;
2941 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2942 if (dir
->i_sb
->u
.generic_sbp
!= inode
->i_sb
->u
.generic_sbp
) return -EINVAL
;
2943 if (inode
== dir
) return -EPERM
;
2944 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2945 de
= get_devfs_entry_from_vfs_inode (inode
);
2946 if (de
== NULL
) return -ENOENT
;
2947 if (!de
->registered
) return -ENOENT
;
2948 if ( !S_ISDIR (de
->mode
) ) return -ENOTDIR
;
2949 for (child
= de
->u
.dir
.first
; child
!= NULL
; child
= child
->next
)
2951 if (child
->registered
)
2953 has_children
= TRUE
;
2957 if (has_children
) return -ENOTEMPTY
;
2958 de
->registered
= FALSE
;
2962 } /* End Function devfs_rmdir */
2964 static int devfs_mknod (struct inode
*dir
, struct dentry
*dentry
, int mode
,
2968 struct fs_info
*fs_info
;
2969 struct devfs_entry
*parent
, *de
;
2970 struct inode
*inode
;
2972 #ifdef CONFIG_DEVFS_DEBUG
2973 char txt
[STRING_LENGTH
];
2975 if (devfs_debug
& DEBUG_I_MKNOD
)
2977 memset (txt
, 0, STRING_LENGTH
);
2978 memcpy (txt
, dentry
->d_name
.name
, dentry
->d_name
.len
);
2979 txt
[STRING_LENGTH
- 1] = '\0';
2980 printk ("%s: mknod(%s): mode: 0%o dev: %d\n",
2981 DEVFS_NAME
, txt
, mode
, rdev
);
2985 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2986 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2987 if ( !S_ISBLK (mode
) && !S_ISCHR (mode
) && !S_ISFIFO (mode
) &&
2988 !S_ISSOCK (mode
) ) return -EPERM
;
2989 /* We are allowed to create the node */
2990 /* First try to get the devfs entry for this directory */
2991 parent
= get_devfs_entry_from_vfs_inode (dir
);
2992 if (parent
== NULL
) return -EINVAL
;
2993 if (!parent
->registered
) return -ENOENT
;
2994 /* Try to reclaim an existing devfs entry, create if there isn't one */
2995 de
= search_for_entry (parent
, dentry
->d_name
.name
, dentry
->d_name
.len
,
2996 FALSE
, TRUE
, &is_new
, FALSE
);
2997 if (de
== NULL
) return -ENOMEM
;
2998 if (!de
->registered
)
3000 /* Since we created the devfs entry we get to choose things */
3003 if ( S_ISBLK (mode
) || S_ISCHR (mode
) )
3005 de
->u
.fcb
.u
.device
.major
= MAJOR (rdev
);
3006 de
->u
.fcb
.u
.device
.minor
= MINOR (rdev
);
3007 de
->u
.fcb
.default_uid
= current
->euid
;
3008 de
->u
.fcb
.default_gid
= current
->egid
;
3009 de
->u
.fcb
.ops
= NULL
;
3010 de
->u
.fcb
.auto_owner
= FALSE
;
3011 de
->u
.fcb
.aopen_notify
= FALSE
;
3012 de
->u
.fcb
.open
= FALSE
;
3014 else if ( S_ISFIFO (mode
) )
3016 de
->u
.fifo
.uid
= current
->euid
;
3017 de
->u
.fifo
.gid
= current
->egid
;
3020 de
->registered
= TRUE
;
3021 de
->show_unreg
= FALSE
;
3023 de
->inode
.mode
= mode
;
3024 de
->inode
.uid
= current
->euid
;
3025 de
->inode
.gid
= current
->egid
;
3026 de
->inode
.atime
= CURRENT_TIME
;
3027 de
->inode
.mtime
= CURRENT_TIME
;
3028 de
->inode
.ctime
= CURRENT_TIME
;
3029 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
3031 #ifdef CONFIG_DEVFS_DEBUG
3032 if (devfs_debug
& DEBUG_I_MKNOD
)
3033 printk ("%s: new VFS inode(%u): %p dentry: %p\n",
3034 DEVFS_NAME
, de
->inode
.ino
, inode
, dentry
);
3036 d_instantiate (dentry
, inode
);
3037 devfsd_notify_one (de
, DEVFSD_NOTIFY_CREATE
, inode
->i_mode
,
3038 inode
->i_uid
, inode
->i_gid
, fs_info
);
3040 } /* End Function devfs_mknod */
3042 static int devfs_readlink (struct dentry
*dentry
, char *buffer
, int buflen
)
3044 struct devfs_entry
*de
= get_devfs_entry_from_vfs_inode (dentry
->d_inode
);
3046 return vfs_readlink (dentry
, buffer
, buflen
, de
->u
.symlink
.linkname
);
3047 } /* End Function devfs_readlink */
3049 static int devfs_follow_link (struct dentry
*dentry
, struct nameidata
*nd
)
3051 struct devfs_entry
*de
= get_devfs_entry_from_vfs_inode (dentry
->d_inode
);
3053 return vfs_follow_link (nd
, de
->u
.symlink
.linkname
);
3054 } /* End Function devfs_follow_link */
3056 static struct inode_operations devfs_iops
=
3059 unlink
: devfs_unlink
,
3060 symlink
: devfs_symlink
,
3064 setattr
: devfs_notify_change
,
3067 static struct inode_operations devfs_dir_iops
=
3069 lookup
: devfs_lookup
,
3071 unlink
: devfs_unlink
,
3072 symlink
: devfs_symlink
,
3076 setattr
: devfs_notify_change
,
3079 static struct inode_operations devfs_symlink_iops
=
3081 readlink
: devfs_readlink
,
3082 follow_link
: devfs_follow_link
,
3083 setattr
: devfs_notify_change
,
3086 static struct super_block
*devfs_read_super (struct super_block
*sb
,
3087 void *data
, int silent
)
3089 struct inode
*root_inode
= NULL
;
3091 if (get_root_entry () == NULL
) goto out_no_root
;
3092 atomic_set (&fs_info
.devfsd_overrun_count
, 0);
3093 init_waitqueue_head (&fs_info
.devfsd_wait_queue
);
3094 init_waitqueue_head (&fs_info
.revalidate_wait_queue
);
3096 sb
->u
.generic_sbp
= &fs_info
;
3097 sb
->s_blocksize
= 1024;
3098 sb
->s_blocksize_bits
= 10;
3099 sb
->s_magic
= DEVFS_SUPER_MAGIC
;
3100 sb
->s_op
= &devfs_sops
;
3101 if ( ( root_inode
= get_vfs_inode (sb
, root_entry
, NULL
) ) == NULL
)
3103 sb
->s_root
= d_alloc_root (root_inode
);
3104 if (!sb
->s_root
) goto out_no_root
;
3105 #ifdef CONFIG_DEVFS_DEBUG
3106 if (devfs_debug
& DEBUG_DISABLED
)
3107 printk ("%s: read super, made devfs ptr: %p\n",
3108 DEVFS_NAME
, sb
->u
.generic_sbp
);
3113 printk ("devfs_read_super: get root inode failed\n");
3114 if (root_inode
) iput (root_inode
);
3116 } /* End Function devfs_read_super */
3119 static DECLARE_FSTYPE (devfs_fs_type
, DEVFS_NAME
, devfs_read_super
, FS_SINGLE
);
3122 /* File operations for devfsd follow */
3124 static ssize_t
devfsd_read (struct file
*file
, char *buf
, size_t len
,
3129 loff_t pos
, devname_offset
, tlen
, rpos
;
3130 struct devfsd_notify_struct info
;
3131 struct devfsd_buf_entry
*entry
;
3132 struct fs_info
*fs_info
= file
->f_dentry
->d_inode
->i_sb
->u
.generic_sbp
;
3133 DECLARE_WAITQUEUE (wait
, current
);
3135 /* Can't seek (pread) on this device */
3136 if (ppos
!= &file
->f_pos
) return -ESPIPE
;
3137 /* Verify the task has grabbed the queue */
3138 if (fs_info
->devfsd_task
!= current
) return -EPERM
;
3141 /* Block for a new entry */
3142 add_wait_queue (&fs_info
->devfsd_wait_queue
, &wait
);
3143 current
->state
= TASK_INTERRUPTIBLE
;
3144 while ( devfsd_queue_empty (fs_info
) )
3146 fs_info
->devfsd_sleeping
= TRUE
;
3147 wake_up (&fs_info
->revalidate_wait_queue
);
3149 fs_info
->devfsd_sleeping
= FALSE
;
3150 if ( signal_pending (current
) )
3152 remove_wait_queue (&fs_info
->devfsd_wait_queue
, &wait
);
3153 current
->state
= TASK_RUNNING
;
3157 remove_wait_queue (&fs_info
->devfsd_wait_queue
, &wait
);
3158 current
->state
= TASK_RUNNING
;
3159 /* Now play with the data */
3160 ival
= atomic_read (&fs_info
->devfsd_overrun_count
);
3161 if (ival
> 0) atomic_sub (ival
, &fs_info
->devfsd_overrun_count
);
3162 info
.overrun_count
= ival
;
3163 entry
= (struct devfsd_buf_entry
*) fs_info
->devfsd_buffer
+
3164 fs_info
->devfsd_buf_out
;
3165 info
.type
= entry
->type
;
3166 info
.mode
= entry
->mode
;
3167 info
.uid
= entry
->uid
;
3168 info
.gid
= entry
->gid
;
3169 if (entry
->type
== DEVFSD_NOTIFY_LOOKUP
)
3171 info
.namelen
= strlen (entry
->data
);
3173 memcpy (info
.devname
, entry
->data
, info
.namelen
+ 1);
3177 devfs_handle_t de
= entry
->data
;
3179 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
3181 info
.major
= de
->u
.fcb
.u
.device
.major
;
3182 info
.minor
= de
->u
.fcb
.u
.device
.minor
;
3184 pos
= devfs_generate_path (de
, info
.devname
, DEVFS_PATHLEN
);
3185 if (pos
< 0) return pos
;
3186 info
.namelen
= DEVFS_PATHLEN
- pos
- 1;
3187 if (info
.mode
== 0) info
.mode
= de
->mode
;
3189 devname_offset
= info
.devname
- (char *) &info
;
3191 if (rpos
< devname_offset
)
3193 /* Copy parts of the header */
3194 tlen
= devname_offset
- rpos
;
3195 if (tlen
> len
) tlen
= len
;
3196 if ( copy_to_user (buf
, (char *) &info
+ rpos
, tlen
) )
3204 if ( (rpos
>= devname_offset
) && (len
> 0) )
3207 tlen
= info
.namelen
+ 1;
3208 if (tlen
> len
) tlen
= len
;
3210 if ( copy_to_user (buf
, info
.devname
+ pos
+ rpos
- devname_offset
,
3217 tlen
= rpos
- *ppos
;
3220 unsigned int next_pos
= fs_info
->devfsd_buf_out
+ 1;
3222 if (next_pos
>= devfsd_buf_size
) next_pos
= 0;
3223 fs_info
->devfsd_buf_out
= next_pos
;
3228 } /* End Function devfsd_read */
3230 static int devfsd_ioctl (struct inode
*inode
, struct file
*file
,
3231 unsigned int cmd
, unsigned long arg
)
3234 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
3238 case DEVFSDIOC_GET_PROTO_REV
:
3239 ival
= DEVFSD_PROTOCOL_REVISION_KERNEL
;
3240 if ( copy_to_user ( (void *)arg
, &ival
, sizeof ival
) ) return -EFAULT
;
3242 case DEVFSDIOC_SET_EVENT_MASK
:
3243 /* Ensure only one reader has access to the queue. This scheme will
3244 work even if the global kernel lock were to be removed, because it
3245 doesn't matter who gets in first, as long as only one gets it */
3246 if (fs_info
->devfsd_task
== NULL
)
3249 /* Looks like no-one has it: check again and grab, with interrupts
3252 if (fs_info
->devfsd_task
== NULL
)
3255 fs_info
->devfsd_event_mask
= 0; /* Temporary disable */
3256 fs_info
->devfsd_task
= current
;
3262 /* Verify the task has grabbed the queue */
3263 if (fs_info
->devfsd_task
!= current
) return -EBUSY
;
3264 fs_info
->devfsd_file
= file
;
3265 fs_info
->devfsd_buffer
= (void *) __get_free_page (GFP_KERNEL
);
3266 if (fs_info
->devfsd_buffer
== NULL
)
3268 devfsd_close (inode
, file
);
3271 fs_info
->devfsd_buf_out
= fs_info
->devfsd_buf_in
;
3272 fs_info
->devfsd_event_mask
= arg
; /* Let the masses come forth */
3274 case DEVFSDIOC_RELEASE_EVENT_QUEUE
:
3275 if (fs_info
->devfsd_file
!= file
) return -EPERM
;
3276 return devfsd_close (inode
, file
);
3278 #ifdef CONFIG_DEVFS_DEBUG
3279 case DEVFSDIOC_SET_DEBUG_MASK
:
3280 if ( copy_from_user (&ival
, (void *) arg
, sizeof ival
) )return -EFAULT
;
3285 return -ENOIOCTLCMD
;
3288 } /* End Function devfsd_ioctl */
3290 static int devfsd_close (struct inode
*inode
, struct file
*file
)
3292 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
3294 if (fs_info
->devfsd_file
!= file
) return 0;
3295 fs_info
->devfsd_event_mask
= 0;
3296 fs_info
->devfsd_file
= NULL
;
3297 if (fs_info
->devfsd_buffer
)
3299 while (fs_info
->devfsd_buffer_in_use
) schedule ();
3300 free_page ( (unsigned long) fs_info
->devfsd_buffer
);
3302 fs_info
->devfsd_buffer
= NULL
;
3303 fs_info
->devfsd_task
= NULL
;
3304 wake_up (&fs_info
->revalidate_wait_queue
);
3306 } /* End Function devfsd_close */
3309 int __init
init_devfs_fs (void)
3313 printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
3314 DEVFS_NAME
, DEVFS_VERSION
);
3315 #ifdef CONFIG_DEVFS_DEBUG
3316 devfs_debug
= devfs_debug_init
;
3317 printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME
, devfs_debug
);
3319 printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME
, boot_options
);
3320 err
= register_filesystem (&devfs_fs_type
);
3323 struct vfsmount
*devfs_mnt
= kern_mount (&devfs_fs_type
);
3324 err
= PTR_ERR (devfs_mnt
);
3325 if ( !IS_ERR (devfs_mnt
) ) err
= 0;
3328 } /* End Function init_devfs_fs */
3330 void __init
mount_devfs_fs (void)
3334 if ( (boot_options
& OPTION_NOMOUNT
) ) return;
3335 err
= do_mount ("none", "/dev", "devfs", 0, "");
3336 if (err
== 0) printk ("Mounted devfs on /dev\n");
3337 else printk ("Warning: unable to mount devfs, err: %d\n", err
);
3338 } /* End Function mount_devfs_fs */