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.
475 20000621 Richard Gooch <rgooch@atnf.csiro.au>
476 Changed interface to <devfs_register>.
477 Work sponsored by SGI.
479 20000622 Richard Gooch <rgooch@atnf.csiro.au>
480 Simplified interface to <devfs_mk_symlink> and <devfs_mk_dir>.
481 Simplified interface to <devfs_find_handle>.
482 Work sponsored by SGI.
485 #include <linux/types.h>
486 #include <linux/errno.h>
487 #include <linux/sched.h>
488 #include <linux/tty.h>
489 #include <linux/timer.h>
490 #include <linux/config.h>
491 #include <linux/kernel.h>
492 #include <linux/wait.h>
493 #include <linux/string.h>
494 #include <linux/malloc.h>
495 #include <linux/ioport.h>
496 #include <linux/delay.h>
497 #include <linux/ctype.h>
498 #include <linux/mm.h>
499 #include <linux/module.h>
500 #include <linux/init.h>
501 #include <linux/locks.h>
502 #include <linux/kdev_t.h>
503 #include <linux/devfs_fs.h>
504 #include <linux/devfs_fs_kernel.h>
505 #include <linux/smp_lock.h>
506 #include <linux/smp.h>
507 #include <linux/version.h>
509 #include <asm/uaccess.h>
511 #include <asm/processor.h>
512 #include <asm/system.h>
513 #include <asm/pgtable.h>
514 #include <asm/segment.h>
515 #include <asm/bitops.h>
516 #include <asm/atomic.h>
518 #define DEVFS_VERSION "0.102 (20000622)"
520 #define DEVFS_NAME "devfs"
522 #define INODE_TABLE_INC 250
523 #define FIRST_INODE 1
525 #define STRING_LENGTH 256
527 #define MIN_DEVNUM 36864 /* Use major numbers 144 */
528 #define MAX_DEVNUM 61439 /* through 239, inclusive */
535 #define IS_HIDDEN(de) (( ((de)->hide && !is_devfsd_or_child(fs_info)) || (!(de)->registered&& !(de)->show_unreg)))
537 #define DEBUG_NONE 0x00000
538 #define DEBUG_MODULE_LOAD 0x00001
539 #define DEBUG_REGISTER 0x00002
540 #define DEBUG_UNREGISTER 0x00004
541 #define DEBUG_SET_FLAGS 0x00008
542 #define DEBUG_S_PUT 0x00010
543 #define DEBUG_I_LOOKUP 0x00020
544 #define DEBUG_I_CREATE 0x00040
545 #define DEBUG_I_READ 0x00080
546 #define DEBUG_I_WRITE 0x00100
547 #define DEBUG_I_UNLINK 0x00200
548 #define DEBUG_I_RLINK 0x00400
549 #define DEBUG_I_FLINK 0x00800
550 #define DEBUG_I_MKNOD 0x01000
551 #define DEBUG_F_READDIR 0x02000
552 #define DEBUG_D_DELETE 0x04000
553 #define DEBUG_D_RELEASE 0x08000
554 #define DEBUG_D_IPUT 0x10000
555 #define DEBUG_ALL (DEBUG_MODULE_LOAD | DEBUG_REGISTER | \
556 DEBUG_SET_FLAGS | DEBUG_I_LOOKUP | \
557 DEBUG_I_UNLINK | DEBUG_I_MKNOD | \
558 DEBUG_D_RELEASE | DEBUG_D_IPUT)
559 #define DEBUG_DISABLED DEBUG_NONE
561 #define OPTION_NONE 0x00
562 #define OPTION_SHOW 0x01
563 #define OPTION_NOMOUNT 0x02
564 #define OPTION_ONLY 0x04
566 #define OOPS(format, args...) {printk (format, ## args); \
567 printk ("Forcing Oops\n"); \
570 struct directory_type
572 struct devfs_entry
*first
;
573 struct devfs_entry
*last
;
574 unsigned int num_removable
;
584 unsigned short major
;
585 unsigned short minor
;
588 struct fcb_type
/* File, char, block type */
595 struct file_type file
;
596 struct device_type device
;
599 unsigned char auto_owner
:1;
600 unsigned char aopen_notify
:1;
601 unsigned char removable
:1; /* Belongs in device_type, but save space */
602 unsigned char open
:1; /* Not entirely correct */
607 unsigned int length
; /* Not including the NULL-termimator */
608 char *linkname
; /* This is NULL-terminated */
617 struct devfs_inode
/* This structure is for "persistent" inode storage */
622 unsigned int ino
; /* Inode number as seen in the VFS */
623 struct dentry
*dentry
;
635 struct directory_type dir
;
637 struct symlink_type symlink
;
638 struct fifo_type fifo
;
641 struct devfs_entry
*prev
; /* Previous entry in the parent directory */
642 struct devfs_entry
*next
; /* Next entry in the parent directory */
643 struct devfs_entry
*parent
; /* The parent directory */
644 struct devfs_entry
*slave
; /* Another entry to unregister */
645 struct devfs_inode inode
;
647 unsigned short namelen
; /* I think 64k+ filenames are a way off... */
648 unsigned char registered
:1;
649 unsigned char show_unreg
:1;
650 unsigned char hide
:1;
651 unsigned char no_persistence
:1;
652 char name
[1]; /* This is just a dummy: the allocated array is
653 bigger. This is NULL-terminated */
656 /* The root of the device tree */
657 static struct devfs_entry
*root_entry
= NULL
;
659 struct devfsd_buf_entry
668 struct fs_info
/* This structure is for each mounted devfs */
670 unsigned int num_inodes
; /* Number of inodes created */
671 unsigned int table_size
; /* Size of the inode pointer table */
672 struct devfs_entry
**table
;
673 struct super_block
*sb
;
674 volatile struct devfsd_buf_entry
*devfsd_buffer
;
675 volatile unsigned int devfsd_buf_in
;
676 volatile unsigned int devfsd_buf_out
;
677 volatile int devfsd_sleeping
;
678 volatile int devfsd_buffer_in_use
;
679 volatile struct task_struct
*devfsd_task
;
680 volatile struct file
*devfsd_file
;
681 volatile unsigned long devfsd_event_mask
;
682 atomic_t devfsd_overrun_count
;
683 wait_queue_head_t devfsd_wait_queue
;
684 wait_queue_head_t revalidate_wait_queue
;
687 static struct fs_info fs_info
;
688 static unsigned int next_devnum_char
= MIN_DEVNUM
;
689 static unsigned int next_devnum_block
= MIN_DEVNUM
;
690 static const int devfsd_buf_size
= PAGE_SIZE
/ sizeof(struct devfsd_buf_entry
);
691 #ifdef CONFIG_DEVFS_DEBUG
692 static unsigned int devfs_debug_init __initdata
= DEBUG_NONE
;
693 static unsigned int devfs_debug
= DEBUG_NONE
;
696 #ifdef CONFIG_DEVFS_MOUNT
697 static unsigned int boot_options
= OPTION_NONE
;
699 static unsigned int boot_options
= OPTION_NOMOUNT
;
702 /* Forward function declarations */
703 static struct devfs_entry
*search_for_entry (struct devfs_entry
*dir
,
705 unsigned int namelen
, int mkdir
,
706 int mkfile
, int *is_new
,
707 int traverse_symlink
);
708 static ssize_t
devfsd_read (struct file
*file
, char *buf
, size_t len
,
710 static int devfsd_ioctl (struct inode
*inode
, struct file
*file
,
711 unsigned int cmd
, unsigned long arg
);
712 static int devfsd_close (struct inode
*inode
, struct file
*file
);
715 /* Devfs daemon file operations */
716 static struct file_operations devfsd_fops
=
720 release
: devfsd_close
,
724 /* Support functions follow */
728 * search_for_entry_in_dir - Search for a devfs entry inside another devfs entry.
729 * @parent: The parent devfs entry.
730 * @name: The name of the entry.
731 * @namelen: The number of characters in @name.
732 * @traverse_symlink: If %TRUE then the entry is traversed if it is a symlink.
734 * Search for a devfs entry inside another devfs entry and returns a pointer
735 * to the entry on success, else %NULL.
738 static struct devfs_entry
*search_for_entry_in_dir (struct devfs_entry
*parent
,
740 unsigned int namelen
,
741 int traverse_symlink
)
743 struct devfs_entry
*curr
;
745 if ( !S_ISDIR (parent
->mode
) )
747 printk ("%s: entry is not a directory\n", DEVFS_NAME
);
750 for (curr
= parent
->u
.dir
.first
; curr
!= NULL
; curr
= curr
->next
)
752 if (curr
->namelen
!= namelen
) continue;
753 if (memcmp (curr
->name
, name
, namelen
) == 0) break;
754 /* Not found: try the next one */
756 if (curr
== NULL
) return NULL
;
757 if (!S_ISLNK (curr
->mode
) || !traverse_symlink
) return curr
;
758 /* Need to follow the link: this is a stack chomper */
759 return search_for_entry (parent
,
760 curr
->u
.symlink
.linkname
, curr
->u
.symlink
.length
,
761 FALSE
, FALSE
, NULL
, TRUE
);
762 } /* End Function search_for_entry_in_dir */
764 static struct devfs_entry
*create_entry (struct devfs_entry
*parent
,
765 const char *name
,unsigned int namelen
)
767 struct devfs_entry
*new, **table
;
769 /* First ensure table size is enough */
770 if (fs_info
.num_inodes
>= fs_info
.table_size
)
772 if ( ( table
= kmalloc (sizeof *table
*
773 (fs_info
.table_size
+ INODE_TABLE_INC
),
774 GFP_KERNEL
) ) == NULL
) return NULL
;
775 fs_info
.table_size
+= INODE_TABLE_INC
;
776 #ifdef CONFIG_DEVFS_DEBUG
777 if (devfs_debug
& DEBUG_I_CREATE
)
778 printk ("%s: create_entry(): grew inode table to: %u entries\n",
779 DEVFS_NAME
, fs_info
.table_size
);
783 memcpy (table
, fs_info
.table
, sizeof *table
*fs_info
.num_inodes
);
784 kfree (fs_info
.table
);
786 fs_info
.table
= table
;
788 if ( name
&& (namelen
< 1) ) namelen
= strlen (name
);
789 if ( ( new = kmalloc (sizeof *new + namelen
, GFP_KERNEL
) ) == NULL
)
791 /* Magic: this will set the ctime to zero, thus subsequent lookups will
792 trigger the call to <update_devfs_inode_from_entry> */
793 memset (new, 0, sizeof *new + namelen
);
794 new->parent
= parent
;
795 if (name
) memcpy (new->name
, name
, namelen
);
796 new->namelen
= namelen
;
797 new->inode
.ino
= fs_info
.num_inodes
+ FIRST_INODE
;
798 new->inode
.nlink
= 1;
799 fs_info
.table
[fs_info
.num_inodes
] = new;
800 ++fs_info
.num_inodes
;
801 if (parent
== NULL
) return new;
802 new->prev
= parent
->u
.dir
.last
;
803 /* Insert into the parent directory's list of children */
804 if (parent
->u
.dir
.first
== NULL
) parent
->u
.dir
.first
= new;
805 else parent
->u
.dir
.last
->next
= new;
806 parent
->u
.dir
.last
= new;
808 } /* End Function create_entry */
810 static void update_devfs_inode_from_entry (struct devfs_entry
*de
)
812 if (de
== NULL
) return;
813 if ( S_ISDIR (de
->mode
) )
815 de
->inode
.mode
= S_IFDIR
| S_IRWXU
| S_IRUGO
| S_IXUGO
;
819 else if ( S_ISLNK (de
->mode
) )
821 de
->inode
.mode
= S_IFLNK
| S_IRUGO
| S_IXUGO
;
825 else if ( S_ISFIFO (de
->mode
) )
827 de
->inode
.mode
= de
->mode
;
828 de
->inode
.uid
= de
->u
.fifo
.uid
;
829 de
->inode
.gid
= de
->u
.fifo
.gid
;
833 if (de
->u
.fcb
.auto_owner
)
834 de
->inode
.mode
= (de
->mode
& ~S_IALLUGO
) | S_IRUGO
| S_IWUGO
;
835 else de
->inode
.mode
= de
->mode
;
836 de
->inode
.uid
= de
->u
.fcb
.default_uid
;
837 de
->inode
.gid
= de
->u
.fcb
.default_gid
;
839 } /* End Function update_devfs_inode_from_entry */
842 * get_root_entry - Get the root devfs entry.
844 * Returns the root devfs entry on success, else %NULL.
847 static struct devfs_entry
*get_root_entry (void)
849 struct devfs_entry
*new;
851 /* Always ensure the root is created */
852 if (root_entry
!= NULL
) return root_entry
;
853 if ( ( root_entry
= create_entry (NULL
, NULL
, 0) ) == NULL
) return NULL
;
854 root_entry
->registered
= TRUE
;
855 root_entry
->mode
= S_IFDIR
;
856 /* Force an inode update, because lookup() is never done for the root */
857 update_devfs_inode_from_entry (root_entry
);
858 /* And create the entry for ".devfsd" */
859 if ( ( new = create_entry (root_entry
, ".devfsd", 0) ) == NULL
)
861 new->registered
= TRUE
;
862 new->u
.fcb
.u
.device
.major
= next_devnum_char
>> 8;
863 new->u
.fcb
.u
.device
.minor
= next_devnum_char
& 0xff;
865 new->mode
= S_IFCHR
| S_IRUSR
| S_IWUSR
;
866 new->u
.fcb
.default_uid
= 0;
867 new->u
.fcb
.default_gid
= 0;
868 new->u
.fcb
.ops
= &devfsd_fops
;
870 } /* End Function get_root_entry */
874 * search_for_entry - Search for an entry in the devfs tree.
875 * @dir: The parent directory to search from. If this is %NULL the root is used
876 * @name: The name of the entry.
877 * @namelen: The number of characters in @name.
878 * @mkdir: If %TRUE intermediate directories are created as needed.
879 * @mkfile: If %TRUE the file entry is created if it doesn't exist.
880 * @is_new: If the returned entry was newly made, %TRUE is written here. If
881 * this is %NULL nothing is written here.
882 * @traverse_symlink: If %TRUE then symbolic links are traversed.
884 * If the entry is created, then it will be in the unregistered state.
885 * Returns a pointer to the entry on success, else %NULL.
888 static struct devfs_entry
*search_for_entry (struct devfs_entry
*dir
,
890 unsigned int namelen
, int mkdir
,
891 int mkfile
, int *is_new
,
892 int traverse_symlink
)
895 const char *subname
, *stop
, *ptr
;
896 struct devfs_entry
*entry
;
898 if (is_new
) *is_new
= FALSE
;
899 if (dir
== NULL
) dir
= get_root_entry ();
900 if (dir
== NULL
) return NULL
;
901 /* Extract one filename component */
903 stop
= name
+ namelen
;
904 while (subname
< stop
)
906 /* Search for a possible '/' */
907 for (ptr
= subname
; (ptr
< stop
) && (*ptr
!= '/'); ++ptr
);
910 /* Look for trailing component */
911 len
= stop
- subname
;
912 entry
= search_for_entry_in_dir (dir
, subname
, len
,
914 if (entry
!= NULL
) return entry
;
915 if (!mkfile
) return NULL
;
916 entry
= create_entry (dir
, subname
, len
);
917 if (entry
&& is_new
) *is_new
= TRUE
;
920 /* Found '/': search for directory */
921 if (strncmp (subname
, "../", 3) == 0)
925 if (dir
== NULL
) return NULL
; /* Cannot escape from devfs */
930 entry
= search_for_entry_in_dir (dir
, subname
, len
, traverse_symlink
);
931 if (!entry
&& !mkdir
) return NULL
;
935 if ( ( entry
= create_entry (dir
, subname
, len
) ) == NULL
)
937 entry
->mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
| S_IWUSR
;
938 if (is_new
) *is_new
= TRUE
;
940 if ( !S_ISDIR (entry
->mode
) )
942 printk ("%s: existing non-directory entry\n", DEVFS_NAME
);
945 /* Ensure an unregistered entry is re-registered and visible */
946 entry
->registered
= TRUE
;
952 } /* End Function search_for_entry */
956 * find_by_dev - Find a devfs entry in a directory.
957 * @dir: The directory where to search
958 * @major: The major number to search for.
959 * @minor: The minor number to search for.
960 * @type: The type of special file to search for. This may be either
961 * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
963 * Returns the devfs_entry pointer on success, else %NULL.
966 static struct devfs_entry
*find_by_dev (struct devfs_entry
*dir
,
967 unsigned int major
, unsigned int minor
,
970 struct devfs_entry
*entry
, *de
;
972 if (dir
== NULL
) return NULL
;
973 if ( !S_ISDIR (dir
->mode
) )
975 printk ("%s: find_by_dev(): not a directory\n", DEVFS_NAME
);
978 /* First search files in this directory */
979 for (entry
= dir
->u
.dir
.first
; entry
!= NULL
; entry
= entry
->next
)
981 if ( !S_ISCHR (entry
->mode
) && !S_ISBLK (entry
->mode
) ) continue;
982 if ( S_ISCHR (entry
->mode
) && (type
!= DEVFS_SPECIAL_CHR
) ) continue;
983 if ( S_ISBLK (entry
->mode
) && (type
!= DEVFS_SPECIAL_BLK
) ) continue;
984 if ( (entry
->u
.fcb
.u
.device
.major
== major
) &&
985 (entry
->u
.fcb
.u
.device
.minor
== minor
) ) return entry
;
986 /* Not found: try the next one */
988 /* Now recursively search the subdirectories: this is a stack chomper */
989 for (entry
= dir
->u
.dir
.first
; entry
!= NULL
; entry
= entry
->next
)
991 if ( !S_ISDIR (entry
->mode
) ) continue;
992 de
= find_by_dev (entry
, major
, minor
, type
);
996 } /* End Function find_by_dev */
1000 * find_entry - Find a devfs entry.
1001 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1002 * name is relative to the root of the devfs.
1003 * @name: The name of the entry. This is ignored if @handle is not %NULL.
1004 * @namelen: The number of characters in @name, not including a %NULL
1005 * terminator. If this is 0, then @name must be %NULL-terminated and the
1006 * length is computed internally.
1007 * @major: The major number. This is used if @handle and @name are %NULL.
1008 * @minor: The minor number. This is used if @handle and @name are %NULL.
1009 * NOTE: If @major and @minor are both 0, searching by major and minor
1010 * numbers is disabled.
1011 * @type: The type of special file to search for. This may be either
1012 * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
1013 * @traverse_symlink: If %TRUE then symbolic links are traversed.
1015 * FIXME: What the hell is @handle? - ch
1016 * Returns the devfs_entry pointer on success, else %NULL.
1019 static struct devfs_entry
*find_entry (devfs_handle_t dir
,
1020 const char *name
, unsigned int namelen
,
1021 unsigned int major
, unsigned int minor
,
1022 char type
, int traverse_symlink
)
1024 struct devfs_entry
*entry
;
1028 if (namelen
< 1) namelen
= strlen (name
);
1031 /* Skip leading pathname component */
1034 printk ("%s: find_entry(%s): too short\n", DEVFS_NAME
, name
);
1037 for (++name
, --namelen
; (*name
!= '/') && (namelen
> 0);
1041 printk ("%s: find_entry(%s): too short\n", DEVFS_NAME
, name
);
1047 entry
= search_for_entry (dir
, name
, namelen
, FALSE
, FALSE
, NULL
,
1049 if (entry
!= NULL
) return entry
;
1051 /* Have to search by major and minor: slow */
1052 if ( (major
== 0) && (minor
== 0) ) return NULL
;
1053 return find_by_dev (root_entry
, major
, minor
, type
);
1054 } /* End Function find_entry */
1056 static struct devfs_entry
*get_devfs_entry_from_vfs_inode (struct inode
*inode
)
1058 struct fs_info
*fs_info
;
1060 if (inode
== NULL
) return NULL
;
1061 if (inode
->i_ino
< FIRST_INODE
) return NULL
;
1062 fs_info
= inode
->i_sb
->u
.generic_sbp
;
1063 if (fs_info
== NULL
) return NULL
;
1064 if (inode
->i_ino
- FIRST_INODE
>= fs_info
->num_inodes
) return NULL
;
1065 return fs_info
->table
[inode
->i_ino
- FIRST_INODE
];
1066 } /* End Function get_devfs_entry_from_vfs_inode */
1070 * free_dentries - Free the dentries for a device entry and invalidate inodes.
1074 static void free_dentries (struct devfs_entry
*de
)
1076 struct dentry
*dentry
;
1078 spin_lock(&dcache_lock
);
1079 dentry
= de
->inode
.dentry
;
1082 dget_locked (dentry
);
1083 de
->inode
.dentry
= NULL
;
1084 spin_unlock(&dcache_lock
);
1085 /* Forcefully remove the inode */
1086 if (dentry
->d_inode
!= NULL
) dentry
->d_inode
->i_nlink
= 0;
1090 spin_unlock(&dcache_lock
);
1091 } /* End Function free_dentries */
1095 * is_devfsd_or_child - Test if the current process is devfsd or one of its children.
1096 * @fs_info: The filesystem information.
1098 * Returns %TRUE if devfsd or child, else %FALSE.
1101 static int is_devfsd_or_child (struct fs_info
*fs_info
)
1103 struct task_struct
*p
;
1105 for (p
= current
; p
!= &init_task
; p
= p
->p_opptr
)
1107 if (p
== fs_info
->devfsd_task
) return (TRUE
);
1110 } /* End Function is_devfsd_or_child */
1114 * devfsd_queue_empty - Test if devfsd has work pending in its event queue.
1115 * @fs_info: The filesystem information.
1117 * Returns %TRUE if the queue is empty, else %FALSE.
1120 static inline int devfsd_queue_empty (struct fs_info
*fs_info
)
1122 return (fs_info
->devfsd_buf_out
== fs_info
->devfsd_buf_in
) ? TRUE
: FALSE
;
1123 } /* End Function devfsd_queue_empty */
1127 * wait_for_devfsd_finished - Wait for devfsd to finish processing its event queue.
1128 * @fs_info: The filesystem information.
1130 * Returns %TRUE if no more waiting will be required, else %FALSE.
1133 static int wait_for_devfsd_finished (struct fs_info
*fs_info
)
1135 DECLARE_WAITQUEUE (wait
, current
);
1137 if (fs_info
->devfsd_task
== NULL
) return (TRUE
);
1138 if (devfsd_queue_empty (fs_info
) && fs_info
->devfsd_sleeping
) return TRUE
;
1139 if ( is_devfsd_or_child (fs_info
) ) return (FALSE
);
1140 add_wait_queue (&fs_info
->revalidate_wait_queue
, &wait
);
1141 current
->state
= TASK_UNINTERRUPTIBLE
;
1142 if (!devfsd_queue_empty (fs_info
) || !fs_info
->devfsd_sleeping
)
1143 if (fs_info
->devfsd_task
) schedule();
1144 remove_wait_queue (&fs_info
->revalidate_wait_queue
, &wait
);
1145 current
->state
= TASK_RUNNING
;
1147 } /* End Function wait_for_devfsd_finished */
1151 * devfsd_notify_one - Notify a single devfsd daemon of a change.
1152 * @data: Data to be passed.
1153 * @type: The type of change.
1154 * @mode: The mode of the entry.
1155 * @uid: The user ID.
1156 * @gid: The group ID.
1157 * @fs_info: The filesystem info.
1159 * Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
1162 static int devfsd_notify_one (void *data
, unsigned int type
, umode_t mode
,
1163 uid_t uid
, gid_t gid
, struct fs_info
*fs_info
)
1165 unsigned int next_pos
;
1166 unsigned long flags
;
1167 struct devfsd_buf_entry
*entry
;
1168 static spinlock_t lock
= SPIN_LOCK_UNLOCKED
;
1170 if ( !( fs_info
->devfsd_event_mask
& (1 << type
) ) ) return (FALSE
);
1171 next_pos
= fs_info
->devfsd_buf_in
+ 1;
1172 if (next_pos
>= devfsd_buf_size
) next_pos
= 0;
1173 if (next_pos
== fs_info
->devfsd_buf_out
)
1175 /* Running up the arse of the reader: drop it */
1176 atomic_inc (&fs_info
->devfsd_overrun_count
);
1179 spin_lock_irqsave (&lock
, flags
);
1180 fs_info
->devfsd_buffer_in_use
= TRUE
;
1181 next_pos
= fs_info
->devfsd_buf_in
+ 1;
1182 if (next_pos
>= devfsd_buf_size
) next_pos
= 0;
1183 entry
= (struct devfsd_buf_entry
*) fs_info
->devfsd_buffer
+
1184 fs_info
->devfsd_buf_in
;
1190 fs_info
->devfsd_buf_in
= next_pos
;
1191 fs_info
->devfsd_buffer_in_use
= FALSE
;
1192 spin_unlock_irqrestore (&lock
, flags
);
1193 wake_up_interruptible (&fs_info
->devfsd_wait_queue
);
1195 } /* End Function devfsd_notify_one */
1199 * devfsd_notify - Notify all devfsd daemons of a change.
1200 * @de: The devfs entry that has changed.
1201 * @type: The type of change event.
1202 * @wait: If TRUE, the functions waits for all daemons to finish processing
1206 static void devfsd_notify (struct devfs_entry
*de
, unsigned int type
, int wait
)
1208 if (devfsd_notify_one (de
, type
, de
->mode
, current
->euid
,
1209 current
->egid
, &fs_info
) && wait
)
1210 wait_for_devfsd_finished (&fs_info
);
1211 } /* End Function devfsd_notify */
1215 * devfs_register - Register a device entry.
1216 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1217 * new name is relative to the root of the devfs.
1218 * @name: The name of the entry.
1219 * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
1220 * @major: The major number. Not needed for regular files.
1221 * @minor: The minor number. Not needed for regular files.
1222 * @mode: The default file mode.
1223 * @ops: The &file_operations or &block_device_operations structure.
1224 * This must not be externally deallocated.
1225 * @info: An arbitrary pointer which will be written to the @private_data
1226 * field of the &file structure passed to the device driver. You can set
1227 * this to whatever you like, and change it once the file is opened (the next
1228 * file opened will not see this change).
1230 * Returns a handle which may later be used in a call to devfs_unregister().
1231 * On failure %NULL is returned.
1234 devfs_handle_t
devfs_register (devfs_handle_t dir
, const char *name
,
1236 unsigned int major
, unsigned int minor
,
1237 umode_t mode
, void *ops
, void *info
)
1240 struct devfs_entry
*de
;
1244 printk ("%s: devfs_register(): NULL name pointer\n", DEVFS_NAME
);
1249 if ( S_ISBLK (mode
) ) ops
= (void *) get_blkfops (major
);
1252 printk ("%s: devfs_register(%s): NULL ops pointer\n",
1256 printk ("%s: devfs_register(%s): NULL ops, got %p from major table\n",
1257 DEVFS_NAME
, name
, ops
);
1259 if ( S_ISDIR (mode
) )
1261 printk("%s: devfs_register(%s): creating directories is not allowed\n",
1265 if ( S_ISLNK (mode
) )
1267 printk ("%s: devfs_register(%s): creating symlinks is not allowed\n",
1271 if ( S_ISCHR (mode
) && (flags
& DEVFS_FL_AUTO_DEVNUM
) )
1273 if (next_devnum_char
>= MAX_DEVNUM
)
1275 printk ("%s: devfs_register(%s): exhausted char device numbers\n",
1279 major
= next_devnum_char
>> 8;
1280 minor
= next_devnum_char
& 0xff;
1283 if ( S_ISBLK (mode
) && (flags
& DEVFS_FL_AUTO_DEVNUM
) )
1285 if (next_devnum_block
>= MAX_DEVNUM
)
1287 printk ("%s: devfs_register(%s): exhausted block device numbers\n",
1291 major
= next_devnum_block
>> 8;
1292 minor
= next_devnum_block
& 0xff;
1293 ++next_devnum_block
;
1295 de
= search_for_entry (dir
, name
, strlen (name
), TRUE
, TRUE
, &is_new
,
1299 printk ("%s: devfs_register(): could not create entry: \"%s\"\n",
1303 #ifdef CONFIG_DEVFS_DEBUG
1304 if (devfs_debug
& DEBUG_REGISTER
)
1305 printk ("%s: devfs_register(%s): de: %p %s\n",
1306 DEVFS_NAME
, name
, de
, is_new
? "new" : "existing");
1310 /* Existing entry */
1311 if ( !S_ISCHR (de
->mode
) && !S_ISBLK (de
->mode
) &&
1312 !S_ISREG (de
->mode
) )
1314 printk ("%s: devfs_register(): existing non-device/file entry: \"%s\"\n",
1320 printk("%s: devfs_register(): device already registered: \"%s\"\n",
1325 de
->registered
= TRUE
;
1326 if ( S_ISCHR (mode
) || S_ISBLK (mode
) )
1328 de
->u
.fcb
.u
.device
.major
= major
;
1329 de
->u
.fcb
.u
.device
.minor
= minor
;
1331 else if ( S_ISREG (mode
) ) de
->u
.fcb
.u
.file
.size
= 0;
1334 printk ("%s: devfs_register(): illegal mode: %x\n",
1340 if (flags
& DEVFS_FL_CURRENT_OWNER
)
1342 de
->u
.fcb
.default_uid
= current
->uid
;
1343 de
->u
.fcb
.default_gid
= current
->gid
;
1347 de
->u
.fcb
.default_uid
= 0;
1348 de
->u
.fcb
.default_gid
= 0;
1350 de
->registered
= TRUE
;
1351 de
->u
.fcb
.ops
= ops
;
1352 de
->u
.fcb
.auto_owner
= (flags
& DEVFS_FL_AUTO_OWNER
) ? TRUE
: FALSE
;
1353 de
->u
.fcb
.aopen_notify
= (flags
& DEVFS_FL_AOPEN_NOTIFY
) ? TRUE
: FALSE
;
1354 if (flags
& DEVFS_FL_REMOVABLE
)
1356 de
->u
.fcb
.removable
= TRUE
;
1357 ++de
->parent
->u
.dir
.num_removable
;
1359 de
->u
.fcb
.open
= FALSE
;
1360 de
->show_unreg
= ( (boot_options
& OPTION_SHOW
)
1361 || (flags
& DEVFS_FL_SHOW_UNREG
) ) ? TRUE
: FALSE
;
1362 de
->hide
= (flags
& DEVFS_FL_HIDE
) ? TRUE
: FALSE
;
1363 de
->no_persistence
= (flags
& DEVFS_FL_NO_PERSISTENCE
) ? TRUE
: FALSE
;
1364 devfsd_notify (de
, DEVFSD_NOTIFY_REGISTERED
, flags
& DEVFS_FL_WAIT
);
1366 } /* End Function devfs_register */
1370 * unregister - Unregister a device entry.
1371 * @de: The entry to unregister.
1374 static void unregister (struct devfs_entry
*de
)
1376 struct devfs_entry
*child
;
1378 if ( (child
= de
->slave
) != NULL
)
1380 de
->slave
= NULL
; /* Unhook first in case slave is parent directory */
1385 devfsd_notify (de
, DEVFSD_NOTIFY_UNREGISTERED
, 0);
1389 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1391 de
->registered
= FALSE
;
1392 de
->u
.fcb
.ops
= NULL
;
1395 if ( S_ISLNK (de
->mode
) )
1397 de
->registered
= FALSE
;
1398 if (de
->u
.symlink
.linkname
!= NULL
) kfree (de
->u
.symlink
.linkname
);
1399 de
->u
.symlink
.linkname
= NULL
;
1402 if ( S_ISFIFO (de
->mode
) )
1404 de
->registered
= FALSE
;
1407 if (!de
->registered
) return;
1408 if ( !S_ISDIR (de
->mode
) )
1410 printk ("%s: unregister(): unsupported type\n", DEVFS_NAME
);
1413 de
->registered
= FALSE
;
1414 /* Now recursively search the subdirectories: this is a stack chomper */
1415 for (child
= de
->u
.dir
.first
; child
!= NULL
; child
= child
->next
)
1417 #ifdef CONFIG_DEVFS_DEBUG
1418 if (devfs_debug
& DEBUG_UNREGISTER
)
1419 printk ("%s: unregister(): child->name: \"%s\" child: %p\n",
1420 DEVFS_NAME
, child
->name
, child
);
1424 } /* End Function unregister */
1428 * devfs_unregister - Unregister a device entry.
1429 * @de: A handle previously created by devfs_register() or returned from
1430 * devfs_find_handle(). If this is %NULL the routine does nothing.
1433 void devfs_unregister (devfs_handle_t de
)
1435 if (de
== NULL
) return;
1436 #ifdef CONFIG_DEVFS_DEBUG
1437 if (devfs_debug
& DEBUG_UNREGISTER
)
1438 printk ("%s: devfs_unregister(): de->name: \"%s\" de: %p\n",
1439 DEVFS_NAME
, de
->name
, de
);
1442 } /* End Function devfs_unregister */
1446 * devfs_mk_symlink Create a symbolic link in the devfs namespace.
1447 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1448 * new name is relative to the root of the devfs.
1449 * @name: The name of the entry.
1450 * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
1451 * @link: The destination name.
1452 * @handle: The handle to the symlink entry is written here. This may be %NULL.
1453 * @info: An arbitrary pointer which will be associated with the entry.
1455 * Returns 0 on success, else a negative error code is returned.
1458 int devfs_mk_symlink (devfs_handle_t dir
, const char *name
, unsigned int flags
,
1459 const char *link
, devfs_handle_t
*handle
, void *info
)
1462 unsigned int linklength
;
1464 struct devfs_entry
*de
;
1466 if (handle
!= NULL
) *handle
= NULL
;
1469 printk ("%s: devfs_mk_symlink(): NULL name pointer\n", DEVFS_NAME
);
1472 #ifdef CONFIG_DEVFS_DEBUG
1473 if (devfs_debug
& DEBUG_REGISTER
)
1474 printk ("%s: devfs_mk_symlink(%s)\n", DEVFS_NAME
, name
);
1478 printk ("%s: devfs_mk_symlink(): NULL link pointer\n", DEVFS_NAME
);
1481 linklength
= strlen (link
);
1482 de
= search_for_entry (dir
, name
, strlen (name
), TRUE
, TRUE
, &is_new
,
1484 if (de
== NULL
) return -ENOMEM
;
1485 if (!S_ISLNK (de
->mode
) && de
->registered
)
1487 printk ("%s: devfs_mk_symlink(): non-link entry already exists\n",
1491 if (handle
!= NULL
) *handle
= de
;
1492 de
->mode
= S_IFLNK
| S_IRUGO
| S_IXUGO
;
1494 de
->show_unreg
= ( (boot_options
& OPTION_SHOW
)
1495 || (flags
& DEVFS_FL_SHOW_UNREG
) ) ? TRUE
: FALSE
;
1496 de
->hide
= (flags
& DEVFS_FL_HIDE
) ? TRUE
: FALSE
;
1497 /* Note there is no need to fiddle the dentry cache if the symlink changes
1498 as the symlink follow method is called every time it's needed */
1499 if ( de
->registered
&& (linklength
== de
->u
.symlink
.length
) )
1501 /* New link is same length as old link */
1502 if (memcmp (link
, de
->u
.symlink
.linkname
, linklength
) == 0) return 0;
1503 return -EEXIST
; /* Contents would change */
1505 /* Have to create/update */
1506 if (de
->registered
) return -EEXIST
;
1507 de
->registered
= TRUE
;
1508 if ( ( newname
= kmalloc (linklength
+ 1, GFP_KERNEL
) ) == NULL
)
1510 struct devfs_entry
*parent
= de
->parent
;
1512 if (!is_new
) return -ENOMEM
;
1513 /* Have to clean up */
1514 if (de
->prev
== NULL
) parent
->u
.dir
.first
= de
->next
;
1515 else de
->prev
->next
= de
->next
;
1516 if (de
->next
== NULL
) parent
->u
.dir
.last
= de
->prev
;
1517 else de
->next
->prev
= de
->prev
;
1521 if (de
->u
.symlink
.linkname
!= NULL
) kfree (de
->u
.symlink
.linkname
);
1522 de
->u
.symlink
.linkname
= newname
;
1523 memcpy (de
->u
.symlink
.linkname
, link
, linklength
);
1524 de
->u
.symlink
.linkname
[linklength
] = '\0';
1525 de
->u
.symlink
.length
= linklength
;
1527 } /* End Function devfs_mk_symlink */
1531 * devfs_mk_dir - Create a directory in the devfs namespace.
1532 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1533 * new name is relative to the root of the devfs.
1534 * @name: The name of the entry.
1535 * @info: An arbitrary pointer which will be associated with the entry.
1537 * Use of this function is optional. The devfs_register() function
1538 * will automatically create intermediate directories as needed. This function
1539 * is provided for efficiency reasons, as it provides a handle to a directory.
1540 * Returns a handle which may later be used in a call to devfs_unregister().
1541 * On failure %NULL is returned.
1544 devfs_handle_t
devfs_mk_dir (devfs_handle_t dir
, const char *name
, void *info
)
1547 struct devfs_entry
*de
;
1551 printk ("%s: devfs_mk_dir(): NULL name pointer\n", DEVFS_NAME
);
1554 de
= search_for_entry (dir
, name
, strlen (name
), TRUE
, TRUE
, &is_new
,
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 * @major: The major number. This is used if @name is %NULL.
1595 * @minor: The minor number. This is used if @name is %NULL.
1596 * @type: The type of special file to search for. This may be either
1597 * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
1598 * @traverse_symlinks: If %TRUE then symlink entries in the devfs namespace are
1599 * traversed. Symlinks pointing out of the devfs namespace will cause a
1600 * failure. Symlink traversal consumes stack space.
1602 * Returns a handle which may later be used in a call to devfs_unregister(),
1603 * devfs_get_flags(), or devfs_set_flags(). On failure %NULL is returned.
1606 devfs_handle_t
devfs_find_handle (devfs_handle_t dir
, const char *name
,
1607 unsigned int major
, unsigned int minor
,
1608 char type
, int traverse_symlinks
)
1612 if ( (name
!= NULL
) && (name
[0] == '\0') ) name
= NULL
;
1613 de
= find_entry (dir
, name
, 0, major
, minor
, type
,
1615 if (de
== NULL
) return NULL
;
1616 if (!de
->registered
) return NULL
;
1618 } /* End Function devfs_find_handle */
1622 * devfs_get_flags - Get the flags for a devfs entry.
1623 * @de: The handle to the device entry.
1624 * @flags: The flags are written here.
1626 * Returns 0 on success, else a negative error code.
1629 int devfs_get_flags (devfs_handle_t de
, unsigned int *flags
)
1631 unsigned int fl
= 0;
1633 if (de
== NULL
) return -EINVAL
;
1634 if (!de
->registered
) return -ENODEV
;
1635 if (de
->show_unreg
) fl
|= DEVFS_FL_SHOW_UNREG
;
1636 if (de
->hide
) fl
|= DEVFS_FL_HIDE
;
1637 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1639 if (de
->u
.fcb
.auto_owner
) fl
|= DEVFS_FL_AUTO_OWNER
;
1640 if (de
->u
.fcb
.aopen_notify
) fl
|= DEVFS_FL_AOPEN_NOTIFY
;
1641 if (de
->u
.fcb
.removable
) fl
|= DEVFS_FL_REMOVABLE
;
1645 } /* End Function devfs_get_flags */
1649 * devfs_set_flags - Set the flags for a devfs entry.
1650 * @de: The handle to the device entry.
1651 * @flags: The flags to set. Unset flags are cleared.
1653 * Returns 0 on success, else a negative error code.
1656 int devfs_set_flags (devfs_handle_t de
, unsigned int flags
)
1658 if (de
== NULL
) return -EINVAL
;
1659 if (!de
->registered
) return -ENODEV
;
1660 #ifdef CONFIG_DEVFS_DEBUG
1661 if (devfs_debug
& DEBUG_SET_FLAGS
)
1662 printk ("%s: devfs_set_flags(): de->name: \"%s\"\n",
1663 DEVFS_NAME
, de
->name
);
1665 de
->show_unreg
= (flags
& DEVFS_FL_SHOW_UNREG
) ? TRUE
: FALSE
;
1666 de
->hide
= (flags
& DEVFS_FL_HIDE
) ? TRUE
: FALSE
;
1667 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1669 de
->u
.fcb
.auto_owner
= (flags
& DEVFS_FL_AUTO_OWNER
) ? TRUE
: FALSE
;
1670 de
->u
.fcb
.aopen_notify
= (flags
& DEVFS_FL_AOPEN_NOTIFY
) ? TRUE
:FALSE
;
1671 if ( de
->u
.fcb
.removable
&& !(flags
& DEVFS_FL_REMOVABLE
) )
1673 de
->u
.fcb
.removable
= FALSE
;
1674 --de
->parent
->u
.dir
.num_removable
;
1676 else if ( !de
->u
.fcb
.removable
&& (flags
& DEVFS_FL_REMOVABLE
) )
1678 de
->u
.fcb
.removable
= TRUE
;
1679 ++de
->parent
->u
.dir
.num_removable
;
1683 } /* End Function devfs_set_flags */
1687 * devfs_get_maj_min - Get the major and minor numbers for a devfs entry.
1688 * @de: The handle to the device entry.
1689 * @major: The major number is written here. This may be %NULL.
1690 * @minor: The minor number is written here. This may be %NULL.
1692 * Returns 0 on success, else a negative error code.
1695 int devfs_get_maj_min (devfs_handle_t de
, unsigned int *major
,
1696 unsigned int *minor
)
1698 if (de
== NULL
) return -EINVAL
;
1699 if (!de
->registered
) return -ENODEV
;
1700 if ( S_ISDIR (de
->mode
) ) return -EISDIR
;
1701 if ( !S_ISCHR (de
->mode
) && !S_ISBLK (de
->mode
) ) return -EINVAL
;
1702 if (major
!= NULL
) *major
= de
->u
.fcb
.u
.device
.major
;
1703 if (minor
!= NULL
) *minor
= de
->u
.fcb
.u
.device
.minor
;
1705 } /* End Function devfs_get_maj_min */
1709 * devfs_get_handle_from_inode - Get the devfs handle for a VFS inode.
1710 * @inode: The VFS inode.
1712 * Returns the devfs handle on success, else %NULL.
1715 devfs_handle_t
devfs_get_handle_from_inode (struct inode
*inode
)
1717 if (!inode
|| !inode
->i_sb
) return NULL
;
1718 if (inode
->i_sb
->s_magic
!= DEVFS_SUPER_MAGIC
) return NULL
;
1719 return get_devfs_entry_from_vfs_inode (inode
);
1720 } /* End Function devfs_get_handle_from_inode */
1724 * devfs_generate_path - Generate a pathname for an entry, relative to the devfs root.
1725 * @de: The devfs entry.
1726 * @path: The buffer to write the pathname to. The pathname and '\0'
1727 * terminator will be written at the end of the buffer.
1728 * @buflen: The length of the buffer.
1730 * Returns the offset in the buffer where the pathname starts on success,
1731 * else a negative error code.
1734 int devfs_generate_path (devfs_handle_t de
, char *path
, int buflen
)
1738 if (de
== NULL
) return -EINVAL
;
1739 if (de
->namelen
>= buflen
) return -ENAMETOOLONG
; /* Must be first */
1740 if (de
->parent
== NULL
) return buflen
; /* Don't prepend root */
1741 pos
= buflen
- de
->namelen
- 1;
1742 memcpy (path
+ pos
, de
->name
, de
->namelen
);
1743 path
[buflen
- 1] = '\0';
1744 for (de
= de
->parent
; de
->parent
!= NULL
; de
= de
->parent
)
1746 if (pos
- de
->namelen
- 1 < 0) return -ENAMETOOLONG
;
1749 memcpy (path
+ pos
, de
->name
, de
->namelen
);
1752 } /* End Function devfs_generate_path */
1756 * devfs_get_ops - Get the device operations for a devfs entry.
1757 * @de: The handle to the device entry.
1759 * Returns a pointer to the device operations on success, else NULL.
1762 void *devfs_get_ops (devfs_handle_t de
)
1764 if (de
== NULL
) return NULL
;
1765 if (!de
->registered
) return NULL
;
1766 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
1767 return de
->u
.fcb
.ops
;
1769 } /* End Function devfs_get_ops */
1773 * devfs_set_file_size - Set the file size for a devfs regular file.
1774 * @de: The handle to the device entry.
1775 * @size: The new file size.
1777 * Returns 0 on success, else a negative error code.
1780 int devfs_set_file_size (devfs_handle_t de
, unsigned long size
)
1782 if (de
== NULL
) return -EINVAL
;
1783 if (!de
->registered
) return -EINVAL
;
1784 if ( !S_ISREG (de
->mode
) ) return -EINVAL
;
1785 if (de
->u
.fcb
.u
.file
.size
== size
) return 0;
1786 de
->u
.fcb
.u
.file
.size
= size
;
1787 if (de
->inode
.dentry
== NULL
) return 0;
1788 if (de
->inode
.dentry
->d_inode
== NULL
) return 0;
1789 de
->inode
.dentry
->d_inode
->i_size
= size
;
1791 } /* End Function devfs_set_file_size */
1795 * devfs_get_info - Get the info pointer written to private_data of @de upon open.
1796 * @de: The handle to the device entry.
1798 * Returns the info pointer.
1800 void *devfs_get_info (devfs_handle_t de
)
1802 if (de
== NULL
) return NULL
;
1803 if (!de
->registered
) return NULL
;
1805 } /* End Function devfs_get_info */
1809 * devfs_set_info - Set the info pointer written to private_data upon open.
1810 * @de: The handle to the device entry.
1811 * @info: pointer to the data
1813 * Returns 0 on success, else a negative error code.
1815 int devfs_set_info (devfs_handle_t de
, void *info
)
1817 if (de
== NULL
) return -EINVAL
;
1818 if (!de
->registered
) return -EINVAL
;
1821 } /* End Function devfs_set_info */
1825 * devfs_get_parent - Get the parent device entry.
1826 * @de: The handle to the device entry.
1828 * Returns the parent device entry if it exists, else %NULL.
1830 devfs_handle_t
devfs_get_parent (devfs_handle_t de
)
1832 if (de
== NULL
) return NULL
;
1833 if (!de
->registered
) return NULL
;
1835 } /* End Function devfs_get_parent */
1839 * devfs_get_first_child - Get the first leaf node in a directory.
1840 * @de: The handle to the device entry.
1842 * Returns the leaf node device entry if it exists, else %NULL.
1845 devfs_handle_t
devfs_get_first_child (devfs_handle_t de
)
1847 if (de
== NULL
) return NULL
;
1848 if (!de
->registered
) return NULL
;
1849 if ( !S_ISDIR (de
->mode
) ) return NULL
;
1850 return de
->u
.dir
.first
;
1851 } /* End Function devfs_get_first_child */
1855 * devfs_get_next_sibling - Get the next sibling leaf node. for a device entry.
1856 * @de: The handle to the device entry.
1858 * Returns the leaf node device entry if it exists, else %NULL.
1861 devfs_handle_t
devfs_get_next_sibling (devfs_handle_t de
)
1863 if (de
== NULL
) return NULL
;
1864 if (!de
->registered
) return NULL
;
1866 } /* End Function devfs_get_next_sibling */
1870 * devfs_auto_unregister - Configure a devfs entry to be automatically unregistered.
1871 * @master: The master devfs entry. Only one slave may be registered.
1872 * @slave: The devfs entry which will be automatically unregistered when the
1873 * master entry is unregistered. It is illegal to call devfs_unregister()
1877 void devfs_auto_unregister (devfs_handle_t master
, devfs_handle_t slave
)
1879 if (master
== NULL
) return;
1880 if (master
->slave
!= NULL
)
1882 /* Because of the dumbness of the layers above, ignore duplicates */
1883 if (master
->slave
== slave
) return;
1884 printk ("%s: devfs_auto_unregister(): only one slave allowed\n",
1886 OOPS (" master: \"%s\" old slave: \"%s\" new slave: \"%s\"\n",
1887 master
->name
, master
->slave
->name
, slave
->name
);
1889 master
->slave
= slave
;
1890 } /* End Function devfs_auto_unregister */
1894 * devfs_get_unregister_slave - Get the slave entry which will be automatically unregistered.
1895 * @master: The master devfs entry.
1897 * Returns the slave which will be unregistered when @master is unregistered.
1900 devfs_handle_t
devfs_get_unregister_slave (devfs_handle_t master
)
1902 if (master
== NULL
) return NULL
;
1903 return master
->slave
;
1904 } /* End Function devfs_get_unregister_slave */
1908 * devfs_get_name - Get the name for a device entry in its parent directory.
1909 * @de: The handle to the device entry.
1910 * @namelen: The length of the name is written here. This may be %NULL.
1912 * Returns the name on success, else %NULL.
1915 const char *devfs_get_name (devfs_handle_t de
, unsigned int *namelen
)
1917 if (de
== NULL
) return NULL
;
1918 if (!de
->registered
) return NULL
;
1919 if (namelen
!= NULL
) *namelen
= de
->namelen
;
1921 } /* End Function devfs_get_name */
1925 * devfs_register_chrdev - Optionally register a conventional character driver.
1926 * @major: The major number for the driver.
1927 * @name: The name of the driver (as seen in /proc/devices).
1928 * @fops: The &file_operations structure pointer.
1930 * This function will register a character driver provided the "devfs=only"
1931 * option was not provided at boot time.
1932 * Returns 0 on success, else a negative error code on failure.
1935 int devfs_register_chrdev (unsigned int major
, const char *name
,
1936 struct file_operations
*fops
)
1938 if (boot_options
& OPTION_ONLY
) return 0;
1939 return register_chrdev (major
, name
, fops
);
1940 } /* End Function devfs_register_chrdev */
1944 * devfs_register_blkdev - Optionally register a conventional block driver.
1945 * @major: The major number for the driver.
1946 * @name: The name of the driver (as seen in /proc/devices).
1947 * @bdops: The &block_device_operations structure pointer.
1949 * This function will register a block driver provided the "devfs=only"
1950 * option was not provided at boot time.
1951 * Returns 0 on success, else a negative error code on failure.
1954 int devfs_register_blkdev (unsigned int major
, const char *name
,
1955 struct block_device_operations
*bdops
)
1957 if (boot_options
& OPTION_ONLY
) return 0;
1958 return register_blkdev (major
, name
, bdops
);
1959 } /* End Function devfs_register_blkdev */
1963 * devfs_unregister_chrdev - Optionally unregister a conventional character driver.
1964 * @major: The major number for the driver.
1965 * @name: The name of the driver (as seen in /proc/devices).
1967 * This function will unregister a character driver provided the "devfs=only"
1968 * option was not provided at boot time.
1969 * Returns 0 on success, else a negative error code on failure.
1972 int devfs_unregister_chrdev (unsigned int major
, const char *name
)
1974 if (boot_options
& OPTION_ONLY
) return 0;
1975 return unregister_chrdev (major
, name
);
1976 } /* End Function devfs_unregister_chrdev */
1980 * devfs_unregister_blkdev - Optionally unregister a conventional block driver.
1981 * @major: The major number for the driver.
1982 * @name: The name of the driver (as seen in /proc/devices).
1984 * This function will unregister a block driver provided the "devfs=only"
1985 * option was not provided at boot time.
1986 * Returns 0 on success, else a negative error code on failure.
1989 int devfs_unregister_blkdev (unsigned int major
, const char *name
)
1991 if (boot_options
& OPTION_ONLY
) return 0;
1992 return unregister_blkdev (major
, name
);
1993 } /* End Function devfs_unregister_blkdev */
1996 * devfs_setup - Process kernel boot options.
1997 * @str: The boot options after the "devfs=".
2000 static int __init
devfs_setup (char *str
)
2002 while ( (*str
!= '\0') && !isspace (*str
) )
2004 #ifdef CONFIG_DEVFS_DEBUG
2005 if (strncmp (str
, "dall", 4) == 0)
2007 devfs_debug_init
|= DEBUG_ALL
;
2010 else if (strncmp (str
, "dmod", 4) == 0)
2012 devfs_debug_init
|= DEBUG_MODULE_LOAD
;
2015 else if (strncmp (str
, "dreg", 4) == 0)
2017 devfs_debug_init
|= DEBUG_REGISTER
;
2020 else if (strncmp (str
, "dunreg", 6) == 0)
2022 devfs_debug_init
|= DEBUG_UNREGISTER
;
2025 else if (strncmp (str
, "diread", 6) == 0)
2027 devfs_debug_init
|= DEBUG_I_READ
;
2030 else if (strncmp (str
, "dchange", 7) == 0)
2032 devfs_debug_init
|= DEBUG_SET_FLAGS
;
2035 else if (strncmp (str
, "diwrite", 7) == 0)
2037 devfs_debug_init
|= DEBUG_I_WRITE
;
2040 else if (strncmp (str
, "dimknod", 7) == 0)
2042 devfs_debug_init
|= DEBUG_I_MKNOD
;
2045 else if (strncmp (str
, "dilookup", 8) == 0)
2047 devfs_debug_init
|= DEBUG_I_LOOKUP
;
2050 else if (strncmp (str
, "diunlink", 8) == 0)
2052 devfs_debug_init
|= DEBUG_I_UNLINK
;
2056 #endif /* CONFIG_DEVFS_DEBUG */
2057 if (strncmp (str
, "show", 4) == 0)
2059 boot_options
|= OPTION_SHOW
;
2062 else if (strncmp (str
, "only", 4) == 0)
2064 boot_options
|= OPTION_ONLY
;
2067 else if (strncmp (str
, "mount", 5) == 0)
2069 boot_options
&= ~OPTION_NOMOUNT
;
2072 else if (strncmp (str
, "nomount", 7) == 0)
2074 boot_options
|= OPTION_NOMOUNT
;
2079 if (*str
!= ',') return 0;
2083 } /* End Function devfs_setup */
2085 __setup("devfs=", devfs_setup
);
2087 EXPORT_SYMBOL(devfs_register
);
2088 EXPORT_SYMBOL(devfs_unregister
);
2089 EXPORT_SYMBOL(devfs_mk_symlink
);
2090 EXPORT_SYMBOL(devfs_mk_dir
);
2091 EXPORT_SYMBOL(devfs_find_handle
);
2092 EXPORT_SYMBOL(devfs_get_flags
);
2093 EXPORT_SYMBOL(devfs_set_flags
);
2094 EXPORT_SYMBOL(devfs_get_maj_min
);
2095 EXPORT_SYMBOL(devfs_get_handle_from_inode
);
2096 EXPORT_SYMBOL(devfs_generate_path
);
2097 EXPORT_SYMBOL(devfs_get_ops
);
2098 EXPORT_SYMBOL(devfs_set_file_size
);
2099 EXPORT_SYMBOL(devfs_get_info
);
2100 EXPORT_SYMBOL(devfs_set_info
);
2101 EXPORT_SYMBOL(devfs_get_parent
);
2102 EXPORT_SYMBOL(devfs_get_first_child
);
2103 EXPORT_SYMBOL(devfs_get_next_sibling
);
2104 EXPORT_SYMBOL(devfs_auto_unregister
);
2105 EXPORT_SYMBOL(devfs_get_unregister_slave
);
2106 EXPORT_SYMBOL(devfs_register_chrdev
);
2107 EXPORT_SYMBOL(devfs_register_blkdev
);
2108 EXPORT_SYMBOL(devfs_unregister_chrdev
);
2109 EXPORT_SYMBOL(devfs_unregister_blkdev
);
2113 * try_modload - Notify devfsd of an inode lookup.
2114 * @parent: The parent devfs entry.
2115 * @fs_info: The filesystem info.
2116 * @name: The device name.
2117 * @namelen: The number of characters in @name.
2118 * @buf: A working area that will be used. This must not go out of scope until
2119 * devfsd is idle again.
2121 * Returns 0 on success, else a negative error code.
2124 static int try_modload (struct devfs_entry
*parent
, struct fs_info
*fs_info
,
2125 const char *name
, unsigned namelen
,
2126 char buf
[STRING_LENGTH
])
2130 if ( !( fs_info
->devfsd_event_mask
& (1 << DEVFSD_NOTIFY_LOOKUP
) ) )
2132 if ( is_devfsd_or_child (fs_info
) ) return -ENOENT
;
2133 if (namelen
>= STRING_LENGTH
) return -ENAMETOOLONG
;
2134 memcpy (buf
+ STRING_LENGTH
- namelen
- 1, name
, namelen
);
2135 buf
[STRING_LENGTH
- 1] = '\0';
2136 pos
= devfs_generate_path (parent
, buf
, STRING_LENGTH
- namelen
- 1);
2137 if (pos
< 0) return pos
;
2138 buf
[STRING_LENGTH
- namelen
- 2] = '/';
2139 if ( !devfsd_notify_one (buf
+ pos
, DEVFSD_NOTIFY_LOOKUP
, 0,
2140 current
->euid
, current
->egid
, fs_info
) )
2142 /* Possible success */
2144 } /* End Function try_modload */
2148 * check_disc_changed - Check if a removable disc was changed.
2151 * Returns 1 if the media was changed, else 0.
2154 static int check_disc_changed (struct devfs_entry
*de
)
2157 kdev_t dev
= MKDEV (de
->u
.fcb
.u
.device
.major
, de
->u
.fcb
.u
.device
.minor
);
2158 struct block_device_operations
*bdops
= de
->u
.fcb
.ops
;
2159 struct super_block
* sb
;
2160 extern int warn_no_part
;
2162 if ( !S_ISBLK (de
->mode
) ) return 0;
2163 if (bdops
== NULL
) return 0;
2164 if (bdops
->check_media_change
== NULL
) return 0;
2165 if ( !bdops
->check_media_change (dev
) ) return 0;
2166 printk ( KERN_DEBUG
"VFS: Disk change detected on device %s\n",
2168 sb
= get_super (dev
);
2169 if ( sb
&& invalidate_inodes (sb
) )
2170 printk("VFS: busy inodes on changed media..\n");
2171 invalidate_buffers (dev
);
2172 /* Ugly hack to disable messages about unable to read partition table */
2175 if (bdops
->revalidate
) bdops
->revalidate (dev
);
2178 } /* End Function check_disc_changed */
2182 * scan_dir_for_removable - Scan a directory for removable media devices and check media.
2183 * @dir: The directory.
2186 static void scan_dir_for_removable (struct devfs_entry
*dir
)
2188 struct devfs_entry
*de
;
2190 if (dir
->u
.dir
.num_removable
< 1) return;
2191 for (de
= dir
->u
.dir
.first
; de
!= NULL
; de
= de
->next
)
2193 if (!de
->registered
) continue;
2194 if ( !S_ISBLK (de
->mode
) ) continue;
2195 if (!de
->u
.fcb
.removable
) continue;
2196 check_disc_changed (de
);
2198 } /* End Function scan_dir_for_removable */
2201 * get_removable_partition - Get removable media partition.
2202 * @dir: The parent directory.
2203 * @name: The name of the entry.
2204 * @namelen: The number of characters in <<name>>.
2206 * Returns 1 if the media was changed, else 0.
2209 static int get_removable_partition (struct devfs_entry
*dir
, const char *name
,
2210 unsigned int namelen
)
2212 struct devfs_entry
*de
;
2214 for (de
= dir
->u
.dir
.first
; de
!= NULL
; de
= de
->next
)
2216 if (!de
->registered
) continue;
2217 if ( !S_ISBLK (de
->mode
) ) continue;
2218 if (!de
->u
.fcb
.removable
) continue;
2219 if (strcmp (de
->name
, "disc") == 0) return check_disc_changed (de
);
2220 /* Support for names where the partition is appended to the disc name
2222 if (de
->namelen
>= namelen
) continue;
2223 if (strncmp (de
->name
, name
, de
->namelen
) != 0) continue;
2224 return check_disc_changed (de
);
2227 } /* End Function get_removable_partition */
2230 /* Superblock operations follow */
2232 static struct inode_operations devfs_iops
;
2233 static struct inode_operations devfs_dir_iops
;
2234 static struct file_operations devfs_fops
;
2235 static struct inode_operations devfs_symlink_iops
;
2237 static void devfs_read_inode (struct inode
*inode
)
2239 struct devfs_entry
*de
;
2241 de
= get_devfs_entry_from_vfs_inode (inode
);
2244 printk ("%s: read_inode(%d): VFS inode: %p NO devfs_entry\n",
2245 DEVFS_NAME
, (int) inode
->i_ino
, inode
);
2248 #ifdef CONFIG_DEVFS_DEBUG
2249 if (devfs_debug
& DEBUG_I_READ
)
2250 printk ("%s: read_inode(%d): VFS inode: %p devfs_entry: %p\n",
2251 DEVFS_NAME
, (int) inode
->i_ino
, inode
, de
);
2254 inode
->i_blocks
= 0;
2255 inode
->i_blksize
= 1024;
2256 inode
->i_op
= &devfs_iops
;
2257 inode
->i_fop
= &devfs_fops
;
2258 inode
->i_rdev
= NODEV
;
2259 if ( S_ISCHR (de
->inode
.mode
) )
2261 inode
->i_rdev
= MKDEV (de
->u
.fcb
.u
.device
.major
,
2262 de
->u
.fcb
.u
.device
.minor
);
2264 else if ( S_ISBLK (de
->inode
.mode
) )
2266 inode
->i_rdev
= MKDEV (de
->u
.fcb
.u
.device
.major
,
2267 de
->u
.fcb
.u
.device
.minor
);
2268 inode
->i_bdev
= bdget (inode
->i_rdev
);
2271 if (!inode
->i_bdev
->bd_op
&& de
->u
.fcb
.ops
)
2272 inode
->i_bdev
->bd_op
= de
->u
.fcb
.ops
;
2274 else printk ("%s: read_inode(%d): no block device from bdget()\n",
2275 DEVFS_NAME
, (int) inode
->i_ino
);
2277 else if ( S_ISFIFO (de
->inode
.mode
) ) inode
->i_fop
= &def_fifo_fops
;
2278 else if ( S_ISREG (de
->inode
.mode
) ) inode
->i_size
= de
->u
.fcb
.u
.file
.size
;
2279 else if ( S_ISDIR (de
->inode
.mode
) ) inode
->i_op
= &devfs_dir_iops
;
2280 else if ( S_ISLNK (de
->inode
.mode
) )
2282 inode
->i_op
= &devfs_symlink_iops
;
2283 inode
->i_size
= de
->u
.symlink
.length
;
2285 inode
->i_mode
= de
->inode
.mode
;
2286 inode
->i_uid
= de
->inode
.uid
;
2287 inode
->i_gid
= de
->inode
.gid
;
2288 inode
->i_atime
= de
->inode
.atime
;
2289 inode
->i_mtime
= de
->inode
.mtime
;
2290 inode
->i_ctime
= de
->inode
.ctime
;
2291 inode
->i_nlink
= de
->inode
.nlink
;
2292 #ifdef CONFIG_DEVFS_DEBUG
2293 if (devfs_debug
& DEBUG_I_READ
)
2294 printk ("%s: mode: 0%o uid: %d gid: %d\n",
2295 DEVFS_NAME
, (int) inode
->i_mode
,
2296 (int) inode
->i_uid
, (int) inode
->i_gid
);
2298 } /* End Function devfs_read_inode */
2300 static void devfs_write_inode (struct inode
*inode
, int wait
)
2303 struct devfs_entry
*de
;
2304 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
2306 if (inode
->i_ino
< FIRST_INODE
) return;
2307 index
= inode
->i_ino
- FIRST_INODE
;
2309 if (index
>= fs_info
->num_inodes
)
2311 printk ("%s: writing inode: %lu for which there is no entry!\n",
2312 DEVFS_NAME
, inode
->i_ino
);
2316 de
= fs_info
->table
[index
];
2317 #ifdef CONFIG_DEVFS_DEBUG
2318 if (devfs_debug
& DEBUG_I_WRITE
)
2320 printk ("%s: write_inode(%d): VFS inode: %p devfs_entry: %p\n",
2321 DEVFS_NAME
, (int) inode
->i_ino
, inode
, de
);
2322 printk ("%s: mode: 0%o uid: %d gid: %d\n",
2323 DEVFS_NAME
, (int) inode
->i_mode
,
2324 (int) inode
->i_uid
, (int) inode
->i_gid
);
2327 de
->inode
.mode
= inode
->i_mode
;
2328 de
->inode
.uid
= inode
->i_uid
;
2329 de
->inode
.gid
= inode
->i_gid
;
2330 de
->inode
.atime
= inode
->i_atime
;
2331 de
->inode
.mtime
= inode
->i_mtime
;
2332 de
->inode
.ctime
= inode
->i_ctime
;
2334 } /* End Function devfs_write_inode */
2336 static int devfs_notify_change (struct dentry
*dentry
, struct iattr
*iattr
)
2339 struct devfs_entry
*de
;
2340 struct inode
*inode
= dentry
->d_inode
;
2341 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
2343 de
= get_devfs_entry_from_vfs_inode (inode
);
2344 if (de
== NULL
) return -ENODEV
;
2345 retval
= inode_change_ok (inode
, iattr
);
2346 if (retval
!= 0) return retval
;
2347 inode_setattr (inode
, iattr
);
2348 if ( iattr
->ia_valid
& (ATTR_MODE
| ATTR_UID
| ATTR_GID
) )
2349 devfsd_notify_one (de
, DEVFSD_NOTIFY_CHANGE
, inode
->i_mode
,
2350 inode
->i_uid
, inode
->i_gid
, fs_info
);
2352 } /* End Function devfs_notify_change */
2354 static int devfs_statfs (struct super_block
*sb
, struct statfs
*buf
)
2356 buf
->f_type
= DEVFS_SUPER_MAGIC
;
2357 buf
->f_bsize
= PAGE_SIZE
/ sizeof (long);
2361 buf
->f_namelen
= NAME_MAX
;
2363 } /* End Function devfs_statfs */
2365 static struct super_operations devfs_sops
=
2367 read_inode
: devfs_read_inode
,
2368 write_inode
: devfs_write_inode
,
2369 statfs
: devfs_statfs
,
2374 * get_vfs_inode - Get a VFS inode.
2375 * @sb: The super block.
2376 * @de: The devfs inode.
2377 * @dentry: The dentry to register with the devfs inode.
2379 * Returns the inode on success, else %NULL.
2382 static struct inode
*get_vfs_inode (struct super_block
*sb
,
2383 struct devfs_entry
*de
,
2384 struct dentry
*dentry
)
2386 struct inode
*inode
;
2388 if (de
->inode
.dentry
!= NULL
)
2390 printk ("%s: get_vfs_inode(%u): old de->inode.dentry: %p \"%s\" new dentry: %p \"%s\"\n",
2391 DEVFS_NAME
, de
->inode
.ino
,
2392 de
->inode
.dentry
, de
->inode
.dentry
->d_name
.name
,
2393 dentry
, dentry
->d_name
.name
);
2394 printk (" old inode: %p\n", de
->inode
.dentry
->d_inode
);
2397 if ( ( inode
= iget (sb
, de
->inode
.ino
) ) == NULL
) return NULL
;
2398 de
->inode
.dentry
= dentry
;
2400 } /* End Function get_vfs_inode */
2403 /* File operations for device entries follow */
2405 static ssize_t
devfs_read (struct file
*file
, char *buf
, size_t len
, loff_t
*ppos
)
2407 if ( S_ISDIR (file
->f_dentry
->d_inode
->i_mode
) ) return -EISDIR
;
2409 } /* End Function devfs_read */
2411 static int devfs_readdir (struct file
*file
, void *dirent
, filldir_t filldir
)
2415 struct fs_info
*fs_info
;
2416 struct devfs_entry
*parent
, *de
;
2417 struct inode
*inode
= file
->f_dentry
->d_inode
;
2421 printk ("%s: readdir(): NULL inode\n", DEVFS_NAME
);
2424 if ( !S_ISDIR (inode
->i_mode
) )
2426 printk ("%s: readdir(): inode is not a directory\n", DEVFS_NAME
);
2429 fs_info
= inode
->i_sb
->u
.generic_sbp
;
2430 parent
= get_devfs_entry_from_vfs_inode (file
->f_dentry
->d_inode
);
2431 if ( (long) file
->f_pos
< 0 ) return -EINVAL
;
2432 #ifdef CONFIG_DEVFS_DEBUG
2433 if (devfs_debug
& DEBUG_F_READDIR
)
2434 printk ("%s: readdir(): fs_info: %p pos: %ld\n", DEVFS_NAME
,
2435 fs_info
, (long) file
->f_pos
);
2437 switch ( (long) file
->f_pos
)
2440 scan_dir_for_removable (parent
);
2441 err
= (*filldir
) (dirent
, "..", 2, file
->f_pos
,
2442 file
->f_dentry
->d_parent
->d_inode
->i_ino
);
2443 if (err
== -EINVAL
) break;
2444 if (err
< 0) return err
;
2449 err
= (*filldir
) (dirent
, ".", 1, file
->f_pos
, inode
->i_ino
);
2450 if (err
== -EINVAL
) break;
2451 if (err
< 0) return err
;
2457 count
= file
->f_pos
- 2;
2458 for (de
= parent
->u
.dir
.first
; (de
!= NULL
) && (count
> 0);
2460 if ( !IS_HIDDEN (de
) ) --count
;
2461 /* Now add all remaining entries */
2462 for (; de
!= NULL
; de
= de
->next
)
2464 if ( IS_HIDDEN (de
) ) continue;
2465 err
= (*filldir
) (dirent
, de
->name
, de
->namelen
,
2466 file
->f_pos
, de
->inode
.ino
);
2467 if (err
== -EINVAL
) break;
2468 if (err
< 0) return err
;
2475 } /* End Function devfs_readdir */
2477 static int devfs_open (struct inode
*inode
, struct file
*file
)
2480 struct fcb_type
*df
;
2481 struct devfs_entry
*de
;
2482 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
2485 de
= get_devfs_entry_from_vfs_inode (inode
);
2490 if ( S_ISDIR (de
->mode
) )
2494 if (!de
->registered
)
2496 file
->private_data
= de
->info
;
2497 if ( S_ISBLK (inode
->i_mode
) )
2499 file
->f_op
= &def_blk_fops
;
2500 if (df
->ops
) inode
->i_bdev
->bd_op
= df
->ops
;
2502 else file
->f_op
= fops_get((struct file_operations
*)df
->ops
);
2504 err
= file
->f_op
->open
? (*file
->f_op
->open
) (inode
, file
) : 0;
2507 /* Fallback to legacy scheme */
2509 * Do we need it? Richard, could you verify it?
2510 * It can legitimately happen if
2511 * it is a character device and
2512 * df->ops == NULL and
2513 * de->registered is true,
2514 * but AFAICS it can't happen - in devfs_register() we never set
2515 * ->ops to NULL, in unregister() we set ->registered to false,
2516 * in devfs_mknod() we set it to NULL only if ->register is false.
2518 * Looks like this fallback is not needed at all.
2521 if ( S_ISCHR (inode
->i_mode
) ) err
= chrdev_open (inode
, file
);
2524 if (err
< 0) goto out
;
2525 /* Open was successful */
2527 if (df
->open
) goto out
;
2528 df
->open
= TRUE
; /* This is the first open */
2531 /* Change the ownership/protection */
2532 de
->inode
.mode
= (de
->inode
.mode
& ~S_IALLUGO
) |(de
->mode
& S_IRWXUGO
);
2533 de
->inode
.uid
= current
->euid
;
2534 de
->inode
.gid
= current
->egid
;
2535 inode
->i_mode
= de
->inode
.mode
;
2536 inode
->i_uid
= de
->inode
.uid
;
2537 inode
->i_gid
= de
->inode
.gid
;
2539 if (df
->aopen_notify
)
2540 devfsd_notify_one (de
, DEVFSD_NOTIFY_ASYNC_OPEN
, inode
->i_mode
,
2541 current
->euid
, current
->egid
, fs_info
);
2545 } /* End Function devfs_open */
2547 static struct file_operations devfs_fops
=
2550 readdir
: devfs_readdir
,
2555 /* Dentry operations for device entries follow */
2559 * devfs_d_release - Callback for when a dentry is freed.
2560 * @dentry: The dentry.
2563 static void devfs_d_release (struct dentry
*dentry
)
2565 #ifdef CONFIG_DEVFS_DEBUG
2566 struct inode
*inode
= dentry
->d_inode
;
2568 if (devfs_debug
& DEBUG_D_RELEASE
)
2569 printk ("%s: d_release(): dentry: %p inode: %p\n",
2570 DEVFS_NAME
, dentry
, inode
);
2572 } /* End Function devfs_d_release */
2575 * devfs_d_iput - Callback for when a dentry loses its inode.
2576 * @dentry: The dentry.
2577 * @inode: The inode.
2580 static void devfs_d_iput (struct dentry
*dentry
, struct inode
*inode
)
2582 struct devfs_entry
*de
;
2585 de
= get_devfs_entry_from_vfs_inode (inode
);
2586 #ifdef CONFIG_DEVFS_DEBUG
2587 if (devfs_debug
& DEBUG_D_IPUT
)
2588 printk ("%s: d_iput(): dentry: %p inode: %p de: %p de->dentry: %p\n",
2589 DEVFS_NAME
, dentry
, inode
, de
, de
->inode
.dentry
);
2591 if (de
->inode
.dentry
== dentry
) de
->inode
.dentry
= NULL
;
2594 } /* End Function devfs_d_iput */
2596 static int devfs_d_delete (struct dentry
*dentry
);
2598 static struct dentry_operations devfs_dops
=
2600 d_delete
: devfs_d_delete
,
2601 d_release
: devfs_d_release
,
2602 d_iput
: devfs_d_iput
,
2605 static int devfs_d_revalidate_wait (struct dentry
*dentry
, int flags
);
2607 static struct dentry_operations devfs_wait_dops
=
2609 d_delete
: devfs_d_delete
,
2610 d_release
: devfs_d_release
,
2611 d_iput
: devfs_d_iput
,
2612 d_revalidate
: devfs_d_revalidate_wait
,
2616 * devfs_d_delete - Callback for when all files for a dentry are closed.
2617 * @dentry: The dentry.
2620 static int devfs_d_delete (struct dentry
*dentry
)
2622 struct inode
*inode
= dentry
->d_inode
;
2623 struct devfs_entry
*de
;
2624 struct fs_info
*fs_info
;
2626 if (dentry
->d_op
== &devfs_wait_dops
) dentry
->d_op
= &devfs_dops
;
2627 /* Unhash dentry if negative (has no inode) */
2630 #ifdef CONFIG_DEVFS_DEBUG
2631 if (devfs_debug
& DEBUG_D_DELETE
)
2632 printk ("%s: d_delete(): dropping negative dentry: %p\n",
2633 DEVFS_NAME
, dentry
);
2637 fs_info
= inode
->i_sb
->u
.generic_sbp
;
2638 de
= get_devfs_entry_from_vfs_inode (inode
);
2639 #ifdef CONFIG_DEVFS_DEBUG
2640 if (devfs_debug
& DEBUG_D_DELETE
)
2641 printk ("%s: d_delete(): dentry: %p inode: %p devfs_entry: %p\n",
2642 DEVFS_NAME
, dentry
, inode
, de
);
2644 if (de
== NULL
) return 0;
2645 if ( !S_ISCHR (de
->mode
) && !S_ISBLK (de
->mode
) && !S_ISREG (de
->mode
) )
2647 if (!de
->u
.fcb
.open
) return 0;
2648 de
->u
.fcb
.open
= FALSE
;
2649 if (de
->u
.fcb
.aopen_notify
)
2650 devfsd_notify_one (de
, DEVFSD_NOTIFY_CLOSE
, inode
->i_mode
,
2651 current
->euid
, current
->egid
, fs_info
);
2652 if (!de
->u
.fcb
.auto_owner
) return 0;
2653 /* Change the ownership/protection back */
2654 de
->inode
.mode
= (de
->inode
.mode
& ~S_IALLUGO
) | S_IRUGO
| S_IWUGO
;
2655 de
->inode
.uid
= de
->u
.fcb
.default_uid
;
2656 de
->inode
.gid
= de
->u
.fcb
.default_gid
;
2657 inode
->i_mode
= de
->inode
.mode
;
2658 inode
->i_uid
= de
->inode
.uid
;
2659 inode
->i_gid
= de
->inode
.gid
;
2661 } /* End Function devfs_d_delete */
2663 static int devfs_d_revalidate_wait (struct dentry
*dentry
, int flags
)
2665 devfs_handle_t de
= dentry
->d_fsdata
;
2667 struct fs_info
*fs_info
;
2670 dir
= dentry
->d_parent
->d_inode
;
2671 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2672 if (!de
|| de
->registered
)
2674 if ( !dentry
->d_inode
&& is_devfsd_or_child (fs_info
) )
2676 struct inode
*inode
;
2678 #ifdef CONFIG_DEVFS_DEBUG
2679 char txt
[STRING_LENGTH
];
2681 memset (txt
, 0, STRING_LENGTH
);
2682 memcpy (txt
, dentry
->d_name
.name
,
2683 (dentry
->d_name
.len
>= STRING_LENGTH
) ?
2684 (STRING_LENGTH
- 1) : dentry
->d_name
.len
);
2685 if (devfs_debug
& DEBUG_I_LOOKUP
)
2686 printk ("%s: d_revalidate(): dentry: %p name: \"%s\" by: \"%s\"\n",
2687 DEVFS_NAME
, dentry
, txt
, current
->comm
);
2691 devfs_handle_t parent
;
2693 parent
= get_devfs_entry_from_vfs_inode (dir
);
2694 de
= search_for_entry_in_dir (parent
, dentry
->d_name
.name
,
2695 dentry
->d_name
.len
, FALSE
);
2697 if (de
== NULL
) goto out
;
2698 /* Create an inode, now that the driver information is available
2700 if (de
->no_persistence
) update_devfs_inode_from_entry (de
);
2701 else if (de
->inode
.ctime
== 0) update_devfs_inode_from_entry (de
);
2702 else de
->inode
.mode
=
2703 (de
->mode
& ~S_IALLUGO
) | (de
->inode
.mode
& S_IALLUGO
);
2704 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2706 #ifdef CONFIG_DEVFS_DEBUG
2707 if (devfs_debug
& DEBUG_I_LOOKUP
)
2708 printk ("%s: d_revalidate(): new VFS inode(%u): %p devfs_entry: %p\n",
2709 DEVFS_NAME
, de
->inode
.ino
, inode
, de
);
2711 d_instantiate (dentry
, inode
);
2715 if ( wait_for_devfsd_finished (fs_info
) ) dentry
->d_op
= &devfs_dops
;
2719 } /* End Function devfs_d_revalidate_wait */
2722 /* Inode operations for device entries follow */
2724 static struct dentry
*devfs_lookup (struct inode
*dir
, struct dentry
*dentry
)
2726 struct fs_info
*fs_info
;
2727 struct devfs_entry
*parent
, *de
;
2728 struct inode
*inode
;
2729 char txt
[STRING_LENGTH
];
2731 /* Set up the dentry operations before anything else, to ensure cleaning
2733 dentry
->d_op
= &devfs_dops
;
2736 printk ("%s: lookup(): NULL directory inode\n", DEVFS_NAME
);
2737 return ERR_PTR (-ENOTDIR
);
2739 if ( !S_ISDIR (dir
->i_mode
) ) return ERR_PTR (-ENOTDIR
);
2740 memset (txt
, 0, STRING_LENGTH
);
2741 memcpy (txt
, dentry
->d_name
.name
,
2742 (dentry
->d_name
.len
>= STRING_LENGTH
) ?
2743 (STRING_LENGTH
- 1) : dentry
->d_name
.len
);
2744 #ifdef CONFIG_DEVFS_DEBUG
2745 if (devfs_debug
& DEBUG_I_LOOKUP
)
2746 printk ("%s: lookup(%s): dentry: %p by: \"%s\"\n",
2747 DEVFS_NAME
, txt
, dentry
, current
->comm
);
2749 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2750 /* First try to get the devfs entry for this directory */
2751 parent
= get_devfs_entry_from_vfs_inode (dir
);
2752 if (parent
== NULL
) return ERR_PTR (-EINVAL
);
2753 if (!parent
->registered
) return ERR_PTR (-ENOENT
);
2754 /* Try to reclaim an existing devfs entry */
2755 de
= search_for_entry_in_dir (parent
,
2756 dentry
->d_name
.name
, dentry
->d_name
.len
,
2758 if ( ( (de
== NULL
) || !de
->registered
) &&
2759 (parent
->u
.dir
.num_removable
> 0) &&
2760 get_removable_partition (parent
, dentry
->d_name
.name
,
2761 dentry
->d_name
.len
) )
2764 de
= search_for_entry_in_dir (parent
, dentry
->d_name
.name
,
2765 dentry
->d_name
.len
, FALSE
);
2767 if ( (de
== NULL
) || !de
->registered
)
2769 /* Try with devfsd. For any kind of failure, leave a negative dentry
2770 so someone else can deal with it (in the case where the sysadmin
2771 does a mknod()). It's important to do this before hashing the
2772 dentry, so that the devfsd queue is filled before revalidates
2774 if (try_modload (parent
, fs_info
,
2775 dentry
->d_name
.name
, dentry
->d_name
.len
, txt
) < 0)
2777 d_add (dentry
, NULL
);
2780 /* devfsd claimed success */
2781 dentry
->d_op
= &devfs_wait_dops
;
2782 dentry
->d_fsdata
= de
;
2783 d_add (dentry
, NULL
); /* Open the floodgates */
2784 /* Unlock directory semaphore, which will release any waiters. They
2785 will get the hashed dentry, and may be forced to wait for
2788 devfs_d_revalidate_wait (dentry
, 0); /* I might have to wait too */
2789 down (&dir
->i_sem
); /* Grab it again because them's the rules */
2790 /* If someone else has been so kind as to make the inode, we go home
2792 if (dentry
->d_inode
) return NULL
;
2793 if (de
&& !de
->registered
) return NULL
;
2795 de
= search_for_entry_in_dir (parent
, dentry
->d_name
.name
,
2796 dentry
->d_name
.len
, FALSE
);
2797 if (de
== NULL
) return NULL
;
2798 /* OK, there's an entry now, but no VFS inode yet */
2802 dentry
->d_op
= &devfs_wait_dops
;
2803 d_add (dentry
, NULL
); /* Open the floodgates */
2805 /* Create an inode, now that the driver information is available */
2806 if (de
->no_persistence
) update_devfs_inode_from_entry (de
);
2807 else if (de
->inode
.ctime
== 0) update_devfs_inode_from_entry (de
);
2808 else de
->inode
.mode
=
2809 (de
->mode
& ~S_IALLUGO
) | (de
->inode
.mode
& S_IALLUGO
);
2810 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2811 return ERR_PTR (-ENOMEM
);
2812 #ifdef CONFIG_DEVFS_DEBUG
2813 if (devfs_debug
& DEBUG_I_LOOKUP
)
2814 printk ("%s: lookup(): new VFS inode(%u): %p devfs_entry: %p\n",
2815 DEVFS_NAME
, de
->inode
.ino
, inode
, de
);
2817 d_instantiate (dentry
, inode
);
2818 /* Unlock directory semaphore, which will release any waiters. They will
2819 get the hashed dentry, and may be forced to wait for revalidation */
2821 if (dentry
->d_op
== &devfs_wait_dops
)
2822 devfs_d_revalidate_wait (dentry
, 0); /* I might have to wait too */
2823 down (&dir
->i_sem
); /* Grab it again because them's the rules */
2825 } /* End Function devfs_lookup */
2827 static int devfs_link (struct dentry
*old_dentry
, struct inode
*dir
,
2828 struct dentry
*dentry
)
2830 /*struct inode *inode = old_dentry->d_inode;*/
2831 char txt
[STRING_LENGTH
];
2833 memset (txt
, 0, STRING_LENGTH
);
2834 memcpy (txt
, old_dentry
->d_name
.name
, old_dentry
->d_name
.len
);
2835 txt
[STRING_LENGTH
- 1] = '\0';
2836 printk ("%s: link of \"%s\"\n", DEVFS_NAME
, txt
);
2838 } /* End Function devfs_link */
2840 static int devfs_unlink (struct inode
*dir
, struct dentry
*dentry
)
2842 struct devfs_entry
*de
;
2844 #ifdef CONFIG_DEVFS_DEBUG
2845 char txt
[STRING_LENGTH
];
2847 if (devfs_debug
& DEBUG_I_UNLINK
)
2849 memset (txt
, 0, STRING_LENGTH
);
2850 memcpy (txt
, dentry
->d_name
.name
, dentry
->d_name
.len
);
2851 txt
[STRING_LENGTH
- 1] = '\0';
2852 printk ("%s: unlink(%s)\n", DEVFS_NAME
, txt
);
2856 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2857 if (!dentry
|| !dentry
->d_inode
) return -ENOENT
;
2858 de
= get_devfs_entry_from_vfs_inode (dentry
->d_inode
);
2859 if (de
== NULL
) return -ENOENT
;
2860 if (!de
->registered
) return -ENOENT
;
2861 de
->registered
= FALSE
;
2865 } /* End Function devfs_unlink */
2867 static int devfs_symlink (struct inode
*dir
, struct dentry
*dentry
,
2868 const char *symname
)
2871 struct fs_info
*fs_info
;
2872 struct devfs_entry
*parent
, *de
;
2873 struct inode
*inode
;
2875 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2876 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2877 /* First try to get the devfs entry for this directory */
2878 parent
= get_devfs_entry_from_vfs_inode (dir
);
2879 if (parent
== NULL
) return -EINVAL
;
2880 if (!parent
->registered
) return -ENOENT
;
2881 err
= devfs_mk_symlink (parent
, dentry
->d_name
.name
, DEVFS_FL_NONE
,
2882 symname
, &de
, NULL
);
2883 #ifdef CONFIG_DEVFS_DEBUG
2884 if (devfs_debug
& DEBUG_DISABLED
)
2885 printk ("%s: symlink(): errcode from <devfs_mk_symlink>: %d\n",
2888 if (err
< 0) return err
;
2889 de
->inode
.mode
= de
->mode
;
2890 de
->inode
.atime
= CURRENT_TIME
;
2891 de
->inode
.mtime
= CURRENT_TIME
;
2892 de
->inode
.ctime
= CURRENT_TIME
;
2893 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2895 #ifdef CONFIG_DEVFS_DEBUG
2896 if (devfs_debug
& DEBUG_DISABLED
)
2897 printk ("%s: symlink(): new VFS inode(%u): %p dentry: %p\n",
2898 DEVFS_NAME
, de
->inode
.ino
, inode
, dentry
);
2901 d_instantiate (dentry
, inode
);
2902 devfsd_notify_one (de
, DEVFSD_NOTIFY_CREATE
, inode
->i_mode
,
2903 inode
->i_uid
, inode
->i_gid
, fs_info
);
2905 } /* End Function devfs_symlink */
2907 static int devfs_mkdir (struct inode
*dir
, struct dentry
*dentry
, int mode
)
2910 struct fs_info
*fs_info
;
2911 struct devfs_entry
*parent
, *de
;
2912 struct inode
*inode
;
2914 mode
= (mode
& ~S_IFMT
) | S_IFDIR
;
2915 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2916 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2917 /* We are allowed to create the directory */
2918 /* First try to get the devfs entry for this directory */
2919 parent
= get_devfs_entry_from_vfs_inode (dir
);
2920 if (parent
== NULL
) return -EINVAL
;
2921 if (!parent
->registered
) return -ENOENT
;
2922 /* Try to reclaim an existing devfs entry, create if there isn't one */
2923 de
= search_for_entry (parent
, dentry
->d_name
.name
, dentry
->d_name
.len
,
2924 FALSE
, TRUE
, &is_new
, FALSE
);
2925 if (de
== NULL
) return -ENOMEM
;
2928 printk ("%s: mkdir(): existing entry\n", DEVFS_NAME
);
2931 de
->registered
= TRUE
;
2933 if (!S_ISDIR (de
->mode
) && !is_new
)
2935 /* Transmogrifying an old entry */
2936 de
->u
.dir
.first
= NULL
;
2937 de
->u
.dir
.last
= NULL
;
2940 de
->u
.dir
.num_removable
= 0;
2941 de
->inode
.mode
= mode
;
2942 de
->inode
.uid
= current
->euid
;
2943 de
->inode
.gid
= current
->egid
;
2944 de
->inode
.atime
= CURRENT_TIME
;
2945 de
->inode
.mtime
= CURRENT_TIME
;
2946 de
->inode
.ctime
= CURRENT_TIME
;
2947 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
2949 #ifdef CONFIG_DEVFS_DEBUG
2950 if (devfs_debug
& DEBUG_DISABLED
)
2951 printk ("%s: mkdir(): new VFS inode(%u): %p dentry: %p\n",
2952 DEVFS_NAME
, de
->inode
.ino
, inode
, dentry
);
2954 d_instantiate (dentry
, inode
);
2955 devfsd_notify_one (de
, DEVFSD_NOTIFY_CREATE
, inode
->i_mode
,
2956 inode
->i_uid
, inode
->i_gid
, fs_info
);
2958 } /* End Function devfs_mkdir */
2960 static int devfs_rmdir (struct inode
*dir
, struct dentry
*dentry
)
2962 int has_children
= FALSE
;
2963 struct fs_info
*fs_info
;
2964 struct devfs_entry
*de
, *child
;
2965 struct inode
*inode
= dentry
->d_inode
;
2967 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
2968 if (dir
->i_sb
->u
.generic_sbp
!= inode
->i_sb
->u
.generic_sbp
) return -EINVAL
;
2969 if (inode
== dir
) return -EPERM
;
2970 fs_info
= dir
->i_sb
->u
.generic_sbp
;
2971 de
= get_devfs_entry_from_vfs_inode (inode
);
2972 if (de
== NULL
) return -ENOENT
;
2973 if (!de
->registered
) return -ENOENT
;
2974 if ( !S_ISDIR (de
->mode
) ) return -ENOTDIR
;
2975 for (child
= de
->u
.dir
.first
; child
!= NULL
; child
= child
->next
)
2977 if (child
->registered
)
2979 has_children
= TRUE
;
2983 if (has_children
) return -ENOTEMPTY
;
2984 de
->registered
= FALSE
;
2988 } /* End Function devfs_rmdir */
2990 static int devfs_mknod (struct inode
*dir
, struct dentry
*dentry
, int mode
,
2994 struct fs_info
*fs_info
;
2995 struct devfs_entry
*parent
, *de
;
2996 struct inode
*inode
;
2998 #ifdef CONFIG_DEVFS_DEBUG
2999 char txt
[STRING_LENGTH
];
3001 if (devfs_debug
& DEBUG_I_MKNOD
)
3003 memset (txt
, 0, STRING_LENGTH
);
3004 memcpy (txt
, dentry
->d_name
.name
, dentry
->d_name
.len
);
3005 txt
[STRING_LENGTH
- 1] = '\0';
3006 printk ("%s: mknod(%s): mode: 0%o dev: %d\n",
3007 DEVFS_NAME
, txt
, mode
, rdev
);
3011 if ( !dir
|| !S_ISDIR (dir
->i_mode
) ) return -ENOTDIR
;
3012 fs_info
= dir
->i_sb
->u
.generic_sbp
;
3013 if ( !S_ISBLK (mode
) && !S_ISCHR (mode
) && !S_ISFIFO (mode
) &&
3014 !S_ISSOCK (mode
) ) return -EPERM
;
3015 /* We are allowed to create the node */
3016 /* First try to get the devfs entry for this directory */
3017 parent
= get_devfs_entry_from_vfs_inode (dir
);
3018 if (parent
== NULL
) return -EINVAL
;
3019 if (!parent
->registered
) return -ENOENT
;
3020 /* Try to reclaim an existing devfs entry, create if there isn't one */
3021 de
= search_for_entry (parent
, dentry
->d_name
.name
, dentry
->d_name
.len
,
3022 FALSE
, TRUE
, &is_new
, FALSE
);
3023 if (de
== NULL
) return -ENOMEM
;
3024 if (!de
->registered
)
3026 /* Since we created the devfs entry we get to choose things */
3029 if ( S_ISBLK (mode
) || S_ISCHR (mode
) )
3031 de
->u
.fcb
.u
.device
.major
= MAJOR (rdev
);
3032 de
->u
.fcb
.u
.device
.minor
= MINOR (rdev
);
3033 de
->u
.fcb
.default_uid
= current
->euid
;
3034 de
->u
.fcb
.default_gid
= current
->egid
;
3035 de
->u
.fcb
.ops
= NULL
;
3036 de
->u
.fcb
.auto_owner
= FALSE
;
3037 de
->u
.fcb
.aopen_notify
= FALSE
;
3038 de
->u
.fcb
.open
= FALSE
;
3040 else if ( S_ISFIFO (mode
) )
3042 de
->u
.fifo
.uid
= current
->euid
;
3043 de
->u
.fifo
.gid
= current
->egid
;
3046 de
->registered
= TRUE
;
3047 de
->show_unreg
= FALSE
;
3049 de
->inode
.mode
= mode
;
3050 de
->inode
.uid
= current
->euid
;
3051 de
->inode
.gid
= current
->egid
;
3052 de
->inode
.atime
= CURRENT_TIME
;
3053 de
->inode
.mtime
= CURRENT_TIME
;
3054 de
->inode
.ctime
= CURRENT_TIME
;
3055 if ( ( inode
= get_vfs_inode (dir
->i_sb
, de
, dentry
) ) == NULL
)
3057 #ifdef CONFIG_DEVFS_DEBUG
3058 if (devfs_debug
& DEBUG_I_MKNOD
)
3059 printk ("%s: new VFS inode(%u): %p dentry: %p\n",
3060 DEVFS_NAME
, de
->inode
.ino
, inode
, dentry
);
3062 d_instantiate (dentry
, inode
);
3063 devfsd_notify_one (de
, DEVFSD_NOTIFY_CREATE
, inode
->i_mode
,
3064 inode
->i_uid
, inode
->i_gid
, fs_info
);
3066 } /* End Function devfs_mknod */
3068 static int devfs_readlink (struct dentry
*dentry
, char *buffer
, int buflen
)
3070 struct devfs_entry
*de
;
3073 de
= get_devfs_entry_from_vfs_inode (dentry
->d_inode
);
3075 return vfs_readlink (dentry
, buffer
, buflen
, de
->u
.symlink
.linkname
);
3076 } /* End Function devfs_readlink */
3078 static int devfs_follow_link (struct dentry
*dentry
, struct nameidata
*nd
)
3080 struct devfs_entry
*de
;
3083 de
= get_devfs_entry_from_vfs_inode (dentry
->d_inode
);
3085 return vfs_follow_link (nd
, de
->u
.symlink
.linkname
);
3086 } /* End Function devfs_follow_link */
3088 static struct inode_operations devfs_iops
=
3091 unlink
: devfs_unlink
,
3092 symlink
: devfs_symlink
,
3096 setattr
: devfs_notify_change
,
3099 static struct inode_operations devfs_dir_iops
=
3101 lookup
: devfs_lookup
,
3103 unlink
: devfs_unlink
,
3104 symlink
: devfs_symlink
,
3108 setattr
: devfs_notify_change
,
3111 static struct inode_operations devfs_symlink_iops
=
3113 readlink
: devfs_readlink
,
3114 follow_link
: devfs_follow_link
,
3115 setattr
: devfs_notify_change
,
3118 static struct super_block
*devfs_read_super (struct super_block
*sb
,
3119 void *data
, int silent
)
3121 struct inode
*root_inode
= NULL
;
3123 if (get_root_entry () == NULL
) goto out_no_root
;
3124 atomic_set (&fs_info
.devfsd_overrun_count
, 0);
3125 init_waitqueue_head (&fs_info
.devfsd_wait_queue
);
3126 init_waitqueue_head (&fs_info
.revalidate_wait_queue
);
3128 sb
->u
.generic_sbp
= &fs_info
;
3129 sb
->s_blocksize
= 1024;
3130 sb
->s_blocksize_bits
= 10;
3131 sb
->s_magic
= DEVFS_SUPER_MAGIC
;
3132 sb
->s_op
= &devfs_sops
;
3133 if ( ( root_inode
= get_vfs_inode (sb
, root_entry
, NULL
) ) == NULL
)
3135 sb
->s_root
= d_alloc_root (root_inode
);
3136 if (!sb
->s_root
) goto out_no_root
;
3137 #ifdef CONFIG_DEVFS_DEBUG
3138 if (devfs_debug
& DEBUG_DISABLED
)
3139 printk ("%s: read super, made devfs ptr: %p\n",
3140 DEVFS_NAME
, sb
->u
.generic_sbp
);
3145 printk ("devfs_read_super: get root inode failed\n");
3146 if (root_inode
) iput (root_inode
);
3148 } /* End Function devfs_read_super */
3151 static DECLARE_FSTYPE (devfs_fs_type
, DEVFS_NAME
, devfs_read_super
, FS_SINGLE
);
3154 /* File operations for devfsd follow */
3156 static ssize_t
devfsd_read (struct file
*file
, char *buf
, size_t len
,
3161 loff_t pos
, devname_offset
, tlen
, rpos
;
3162 struct devfsd_notify_struct info
;
3163 struct devfsd_buf_entry
*entry
;
3164 struct fs_info
*fs_info
= file
->f_dentry
->d_inode
->i_sb
->u
.generic_sbp
;
3165 DECLARE_WAITQUEUE (wait
, current
);
3167 /* Can't seek (pread) on this device */
3168 if (ppos
!= &file
->f_pos
) return -ESPIPE
;
3169 /* Verify the task has grabbed the queue */
3170 if (fs_info
->devfsd_task
!= current
) return -EPERM
;
3173 /* Block for a new entry */
3174 add_wait_queue (&fs_info
->devfsd_wait_queue
, &wait
);
3175 current
->state
= TASK_INTERRUPTIBLE
;
3176 while ( devfsd_queue_empty (fs_info
) )
3178 fs_info
->devfsd_sleeping
= TRUE
;
3179 wake_up (&fs_info
->revalidate_wait_queue
);
3181 fs_info
->devfsd_sleeping
= FALSE
;
3182 if ( signal_pending (current
) )
3184 remove_wait_queue (&fs_info
->devfsd_wait_queue
, &wait
);
3185 current
->state
= TASK_RUNNING
;
3189 remove_wait_queue (&fs_info
->devfsd_wait_queue
, &wait
);
3190 current
->state
= TASK_RUNNING
;
3191 /* Now play with the data */
3192 ival
= atomic_read (&fs_info
->devfsd_overrun_count
);
3193 if (ival
> 0) atomic_sub (ival
, &fs_info
->devfsd_overrun_count
);
3194 info
.overrun_count
= ival
;
3195 entry
= (struct devfsd_buf_entry
*) fs_info
->devfsd_buffer
+
3196 fs_info
->devfsd_buf_out
;
3197 info
.type
= entry
->type
;
3198 info
.mode
= entry
->mode
;
3199 info
.uid
= entry
->uid
;
3200 info
.gid
= entry
->gid
;
3201 if (entry
->type
== DEVFSD_NOTIFY_LOOKUP
)
3203 info
.namelen
= strlen (entry
->data
);
3205 memcpy (info
.devname
, entry
->data
, info
.namelen
+ 1);
3209 devfs_handle_t de
= entry
->data
;
3211 if ( S_ISCHR (de
->mode
) || S_ISBLK (de
->mode
) || S_ISREG (de
->mode
) )
3213 info
.major
= de
->u
.fcb
.u
.device
.major
;
3214 info
.minor
= de
->u
.fcb
.u
.device
.minor
;
3216 pos
= devfs_generate_path (de
, info
.devname
, DEVFS_PATHLEN
);
3217 if (pos
< 0) return pos
;
3218 info
.namelen
= DEVFS_PATHLEN
- pos
- 1;
3219 if (info
.mode
== 0) info
.mode
= de
->mode
;
3221 devname_offset
= info
.devname
- (char *) &info
;
3223 if (rpos
< devname_offset
)
3225 /* Copy parts of the header */
3226 tlen
= devname_offset
- rpos
;
3227 if (tlen
> len
) tlen
= len
;
3228 if ( copy_to_user (buf
, (char *) &info
+ rpos
, tlen
) )
3236 if ( (rpos
>= devname_offset
) && (len
> 0) )
3239 tlen
= info
.namelen
+ 1;
3240 if (tlen
> len
) tlen
= len
;
3242 if ( copy_to_user (buf
, info
.devname
+ pos
+ rpos
- devname_offset
,
3249 tlen
= rpos
- *ppos
;
3252 unsigned int next_pos
= fs_info
->devfsd_buf_out
+ 1;
3254 if (next_pos
>= devfsd_buf_size
) next_pos
= 0;
3255 fs_info
->devfsd_buf_out
= next_pos
;
3260 } /* End Function devfsd_read */
3262 static int devfsd_ioctl (struct inode
*inode
, struct file
*file
,
3263 unsigned int cmd
, unsigned long arg
)
3266 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
3270 case DEVFSDIOC_GET_PROTO_REV
:
3271 ival
= DEVFSD_PROTOCOL_REVISION_KERNEL
;
3272 if ( copy_to_user ( (void *)arg
, &ival
, sizeof ival
) ) return -EFAULT
;
3274 case DEVFSDIOC_SET_EVENT_MASK
:
3275 /* Ensure only one reader has access to the queue. This scheme will
3276 work even if the global kernel lock were to be removed, because it
3277 doesn't matter who gets in first, as long as only one gets it */
3278 if (fs_info
->devfsd_task
== NULL
)
3281 /* Looks like no-one has it: check again and grab, with interrupts
3284 if (fs_info
->devfsd_task
== NULL
)
3287 fs_info
->devfsd_event_mask
= 0; /* Temporary disable */
3288 fs_info
->devfsd_task
= current
;
3294 /* Verify the task has grabbed the queue */
3295 if (fs_info
->devfsd_task
!= current
) return -EBUSY
;
3296 fs_info
->devfsd_file
= file
;
3297 fs_info
->devfsd_buffer
= (void *) __get_free_page (GFP_KERNEL
);
3298 if (fs_info
->devfsd_buffer
== NULL
)
3300 devfsd_close (inode
, file
);
3303 fs_info
->devfsd_buf_out
= fs_info
->devfsd_buf_in
;
3304 fs_info
->devfsd_event_mask
= arg
; /* Let the masses come forth */
3306 case DEVFSDIOC_RELEASE_EVENT_QUEUE
:
3307 if (fs_info
->devfsd_file
!= file
) return -EPERM
;
3308 return devfsd_close (inode
, file
);
3310 #ifdef CONFIG_DEVFS_DEBUG
3311 case DEVFSDIOC_SET_DEBUG_MASK
:
3312 if ( copy_from_user (&ival
, (void *) arg
, sizeof ival
) )return -EFAULT
;
3317 return -ENOIOCTLCMD
;
3320 } /* End Function devfsd_ioctl */
3322 static int devfsd_close (struct inode
*inode
, struct file
*file
)
3324 struct fs_info
*fs_info
= inode
->i_sb
->u
.generic_sbp
;
3327 if (fs_info
->devfsd_file
!= file
)
3332 fs_info
->devfsd_event_mask
= 0;
3333 fs_info
->devfsd_file
= NULL
;
3334 if (fs_info
->devfsd_buffer
)
3336 while (fs_info
->devfsd_buffer_in_use
) schedule ();
3337 free_page ( (unsigned long) fs_info
->devfsd_buffer
);
3339 fs_info
->devfsd_buffer
= NULL
;
3340 fs_info
->devfsd_task
= NULL
;
3341 wake_up (&fs_info
->revalidate_wait_queue
);
3344 } /* End Function devfsd_close */
3347 int __init
init_devfs_fs (void)
3351 printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
3352 DEVFS_NAME
, DEVFS_VERSION
);
3353 #ifdef CONFIG_DEVFS_DEBUG
3354 devfs_debug
= devfs_debug_init
;
3355 printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME
, devfs_debug
);
3357 printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME
, boot_options
);
3358 err
= register_filesystem (&devfs_fs_type
);
3361 struct vfsmount
*devfs_mnt
= kern_mount (&devfs_fs_type
);
3362 err
= PTR_ERR (devfs_mnt
);
3363 if ( !IS_ERR (devfs_mnt
) ) err
= 0;
3366 } /* End Function init_devfs_fs */
3368 void __init
mount_devfs_fs (void)
3372 if ( (boot_options
& OPTION_NOMOUNT
) ) return;
3373 err
= do_mount ("none", "/dev", "devfs", 0, "");
3374 if (err
== 0) printk ("Mounted devfs on /dev\n");
3375 else printk ("Warning: unable to mount devfs, err: %d\n", err
);
3376 } /* End Function mount_devfs_fs */