diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /fs/devfs |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'fs/devfs')
-rw-r--r-- | fs/devfs/Makefile | 8 | ||||
-rw-r--r-- | fs/devfs/base.c | 2838 | ||||
-rw-r--r-- | fs/devfs/util.c | 97 |
3 files changed, 2943 insertions, 0 deletions
diff --git a/fs/devfs/Makefile b/fs/devfs/Makefile new file mode 100644 index 00000000000..6dd8d1245e2 --- /dev/null +++ b/fs/devfs/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the linux devfs-filesystem routines. +# + +obj-$(CONFIG_DEVFS_FS) += devfs.o + +devfs-objs := base.o util.o + diff --git a/fs/devfs/base.c b/fs/devfs/base.c new file mode 100644 index 00000000000..1ecfe1f184d --- /dev/null +++ b/fs/devfs/base.c @@ -0,0 +1,2838 @@ +/* devfs (Device FileSystem) driver. + + Copyright (C) 1998-2002 Richard Gooch + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Richard Gooch may be reached by email at rgooch@atnf.csiro.au + The postal address is: + Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. + + ChangeLog + + 19980110 Richard Gooch <rgooch@atnf.csiro.au> + Original version. + v0.1 + 19980111 Richard Gooch <rgooch@atnf.csiro.au> + Created per-fs inode table rather than using inode->u.generic_ip + v0.2 + 19980111 Richard Gooch <rgooch@atnf.csiro.au> + Created .epoch inode which has a ctime of 0. + Fixed loss of named pipes when dentries lost. + Fixed loss of inode data when devfs_register() follows mknod(). + v0.3 + 19980111 Richard Gooch <rgooch@atnf.csiro.au> + Fix for when compiling with CONFIG_KERNELD. + 19980112 Richard Gooch <rgooch@atnf.csiro.au> + Fix for readdir() which sometimes didn't show entries. + Added <<tolerant>> option to <devfs_register>. + v0.4 + 19980113 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_fill_file> function. + v0.5 + 19980115 Richard Gooch <rgooch@atnf.csiro.au> + Added subdirectory support. Major restructuring. + 19980116 Richard Gooch <rgooch@atnf.csiro.au> + Fixed <find_by_dev> to not search major=0,minor=0. + Added symlink support. + v0.6 + 19980120 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_mk_dir> function and support directory unregister + 19980120 Richard Gooch <rgooch@atnf.csiro.au> + Auto-ownership uses real uid/gid rather than effective uid/gid. + v0.7 + 19980121 Richard Gooch <rgooch@atnf.csiro.au> + Supported creation of sockets. + v0.8 + 19980122 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFS_FL_HIDE_UNREG flag. + Interface change to <devfs_mk_symlink>. + Created <devfs_symlink> to support symlink(2). + v0.9 + 19980123 Richard Gooch <rgooch@atnf.csiro.au> + Added check to <devfs_fill_file> to check inode is in devfs. + Added optional traversal of symlinks. + v0.10 + 19980124 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_get_flags> and <devfs_set_flags>. + v0.11 + 19980125 C. Scott Ananian <cananian@alumni.princeton.edu> + Created <devfs_find_handle>. + 19980125 Richard Gooch <rgooch@atnf.csiro.au> + Allow removal of symlinks. + v0.12 + 19980125 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_set_symlink_destination>. + 19980126 Richard Gooch <rgooch@atnf.csiro.au> + Moved DEVFS_SUPER_MAGIC into header file. + Added DEVFS_FL_HIDE flag. + Created <devfs_get_maj_min>. + Created <devfs_get_handle_from_inode>. + Fixed minor bug in <find_by_dev>. + 19980127 Richard Gooch <rgooch@atnf.csiro.au> + Changed interface to <find_by_dev>, <find_entry>, + <devfs_unregister>, <devfs_fill_file> and <devfs_find_handle>. + Fixed inode times when symlink created with symlink(2). + v0.13 + 19980129 C. Scott Ananian <cananian@alumni.princeton.edu> + Exported <devfs_set_symlink_destination>, <devfs_get_maj_min> + and <devfs_get_handle_from_inode>. + 19980129 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_unlink> to support unlink(2). + v0.14 + 19980129 Richard Gooch <rgooch@atnf.csiro.au> + Fixed kerneld support for entries in devfs subdirectories. + 19980130 Richard Gooch <rgooch@atnf.csiro.au> + Bugfixes in <call_kerneld>. + v0.15 + 19980207 Richard Gooch <rgooch@atnf.csiro.au> + Call kerneld when looking up unregistered entries. + v0.16 + 19980326 Richard Gooch <rgooch@atnf.csiro.au> + Modified interface to <devfs_find_handle> for symlink traversal. + v0.17 + 19980331 Richard Gooch <rgooch@atnf.csiro.au> + Fixed persistence bug with device numbers for manually created + device files. + Fixed problem with recreating symlinks with different content. + v0.18 + 19980401 Richard Gooch <rgooch@atnf.csiro.au> + Changed to CONFIG_KMOD. + Hide entries which are manually unlinked. + Always invalidate devfs dentry cache when registering entries. + Created <devfs_rmdir> to support rmdir(2). + Ensure directories created by <devfs_mk_dir> are visible. + v0.19 + 19980402 Richard Gooch <rgooch@atnf.csiro.au> + Invalidate devfs dentry cache when making directories. + Invalidate devfs dentry cache when removing entries. + Fixed persistence bug with fifos. + v0.20 + 19980421 Richard Gooch <rgooch@atnf.csiro.au> + Print process command when debugging kerneld/kmod. + Added debugging for register/unregister/change operations. + 19980422 Richard Gooch <rgooch@atnf.csiro.au> + Added "devfs=" boot options. + v0.21 + 19980426 Richard Gooch <rgooch@atnf.csiro.au> + No longer lock/unlock superblock in <devfs_put_super>. + Drop negative dentries when they are released. + Manage dcache more efficiently. + v0.22 + 19980427 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFS_FL_AUTO_DEVNUM flag. + v0.23 + 19980430 Richard Gooch <rgooch@atnf.csiro.au> + No longer set unnecessary methods. + v0.24 + 19980504 Richard Gooch <rgooch@atnf.csiro.au> + Added PID display to <call_kerneld> debugging message. + Added "after" debugging message to <call_kerneld>. + 19980519 Richard Gooch <rgooch@atnf.csiro.au> + Added "diread" and "diwrite" boot options. + 19980520 Richard Gooch <rgooch@atnf.csiro.au> + Fixed persistence problem with permissions. + v0.25 + 19980602 Richard Gooch <rgooch@atnf.csiro.au> + Support legacy device nodes. + Fixed bug where recreated inodes were hidden. + v0.26 + 19980602 Richard Gooch <rgooch@atnf.csiro.au> + Improved debugging in <get_vfs_inode>. + 19980607 Richard Gooch <rgooch@atnf.csiro.au> + No longer free old dentries in <devfs_mk_dir>. + Free all dentries for a given entry when deleting inodes. + v0.27 + 19980627 Richard Gooch <rgooch@atnf.csiro.au> + Limit auto-device numbering to majors 128 to 239. + v0.28 + 19980629 Richard Gooch <rgooch@atnf.csiro.au> + Fixed inode times persistence problem. + v0.29 + 19980704 Richard Gooch <rgooch@atnf.csiro.au> + Fixed spelling in <devfs_readlink> debug. + Fixed bug in <devfs_setup> parsing "dilookup". + v0.30 + 19980705 Richard Gooch <rgooch@atnf.csiro.au> + Fixed devfs inode leak when manually recreating inodes. + Fixed permission persistence problem when recreating inodes. + v0.31 + 19980727 Richard Gooch <rgooch@atnf.csiro.au> + Removed harmless "unused variable" compiler warning. + Fixed modes for manually recreated device nodes. + v0.32 + 19980728 Richard Gooch <rgooch@atnf.csiro.au> + Added NULL devfs inode warning in <devfs_read_inode>. + Force all inode nlink values to 1. + v0.33 + 19980730 Richard Gooch <rgooch@atnf.csiro.au> + Added "dimknod" boot option. + Set inode nlink to 0 when freeing dentries. + Fixed modes for manually recreated symlinks. + v0.34 + 19980802 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bugs in recreated directories and symlinks. + v0.35 + 19980806 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bugs in recreated device nodes. + 19980807 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bug in currently unused <devfs_get_handle_from_inode>. + Defined new <devfs_handle_t> type. + Improved debugging when getting entries. + Fixed bug where directories could be emptied. + v0.36 + 19980809 Richard Gooch <rgooch@atnf.csiro.au> + Replaced dummy .epoch inode with .devfsd character device. + 19980810 Richard Gooch <rgooch@atnf.csiro.au> + Implemented devfsd protocol revision 0. + v0.37 + 19980819 Richard Gooch <rgooch@atnf.csiro.au> + Added soothing message to warning in <devfs_d_iput>. + v0.38 + 19980829 Richard Gooch <rgooch@atnf.csiro.au> + Use GCC extensions for structure initialisations. + Implemented async open notification. + Incremented devfsd protocol revision to 1. + v0.39 + 19980908 Richard Gooch <rgooch@atnf.csiro.au> + Moved async open notification to end of <devfs_open>. + v0.40 + 19980910 Richard Gooch <rgooch@atnf.csiro.au> + Prepended "/dev/" to module load request. + Renamed <call_kerneld> to <call_kmod>. + v0.41 + 19980910 Richard Gooch <rgooch@atnf.csiro.au> + Fixed typo "AYSNC" -> "ASYNC". + v0.42 + 19980910 Richard Gooch <rgooch@atnf.csiro.au> + Added open flag for files. + v0.43 + 19980927 Richard Gooch <rgooch@atnf.csiro.au> + Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>. + v0.44 + 19981005 Richard Gooch <rgooch@atnf.csiro.au> + Added test for empty <<name>> in <devfs_find_handle>. + Renamed <generate_path> to <devfs_generate_path> and published. + v0.45 + 19981006 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_get_fops>. + v0.46 + 19981007 Richard Gooch <rgooch@atnf.csiro.au> + Limit auto-device numbering to majors 144 to 239. + v0.47 + 19981010 Richard Gooch <rgooch@atnf.csiro.au> + Updated <devfs_follow_link> for VFS change in 2.1.125. + v0.48 + 19981022 Richard Gooch <rgooch@atnf.csiro.au> + Created DEVFS_ FL_COMPAT flag. + v0.49 + 19981023 Richard Gooch <rgooch@atnf.csiro.au> + Created "nocompat" boot option. + v0.50 + 19981025 Richard Gooch <rgooch@atnf.csiro.au> + Replaced "mount" boot option with "nomount". + v0.51 + 19981110 Richard Gooch <rgooch@atnf.csiro.au> + Created "only" boot option. + v0.52 + 19981112 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFS_FL_REMOVABLE flag. + v0.53 + 19981114 Richard Gooch <rgooch@atnf.csiro.au> + Only call <scan_dir_for_removable> on first call to + <devfs_readdir>. + v0.54 + 19981205 Richard Gooch <rgooch@atnf.csiro.au> + Updated <devfs_rmdir> for VFS change in 2.1.131. + v0.55 + 19981218 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_mk_compat>. + 19981220 Richard Gooch <rgooch@atnf.csiro.au> + Check for partitions on removable media in <devfs_lookup>. + v0.56 + 19990118 Richard Gooch <rgooch@atnf.csiro.au> + Added support for registering regular files. + Created <devfs_set_file_size>. + Update devfs inodes from entries if not changed through FS. + v0.57 + 19990124 Richard Gooch <rgooch@atnf.csiro.au> + Fixed <devfs_fill_file> to only initialise temporary inodes. + Trap for NULL fops in <devfs_register>. + Return -ENODEV in <devfs_fill_file> for non-driver inodes. + v0.58 + 19990126 Richard Gooch <rgooch@atnf.csiro.au> + Switched from PATH_MAX to DEVFS_PATHLEN. + v0.59 + 19990127 Richard Gooch <rgooch@atnf.csiro.au> + Created "nottycompat" boot option. + v0.60 + 19990318 Richard Gooch <rgooch@atnf.csiro.au> + Fixed <devfsd_read> to not overrun event buffer. + v0.61 + 19990329 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_auto_unregister>. + v0.62 + 19990330 Richard Gooch <rgooch@atnf.csiro.au> + Don't return unregistred entries in <devfs_find_handle>. + Panic in <devfs_unregister> if entry unregistered. + 19990401 Richard Gooch <rgooch@atnf.csiro.au> + Don't panic in <devfs_auto_unregister> for duplicates. + v0.63 + 19990402 Richard Gooch <rgooch@atnf.csiro.au> + Don't unregister already unregistered entries in <unregister>. + v0.64 + 19990510 Richard Gooch <rgooch@atnf.csiro.au> + Disable warning messages when unable to read partition table for + removable media. + v0.65 + 19990512 Richard Gooch <rgooch@atnf.csiro.au> + Updated <devfs_lookup> for VFS change in 2.3.1-pre1. + Created "oops-on-panic" boot option. + Improved debugging in <devfs_register> and <devfs_unregister>. + v0.66 + 19990519 Richard Gooch <rgooch@atnf.csiro.au> + Added documentation for some functions. + 19990525 Richard Gooch <rgooch@atnf.csiro.au> + Removed "oops-on-panic" boot option: now always Oops. + v0.67 + 19990531 Richard Gooch <rgooch@atnf.csiro.au> + Improved debugging in <devfs_register>. + v0.68 + 19990604 Richard Gooch <rgooch@atnf.csiro.au> + Added "diunlink" and "nokmod" boot options. + Removed superfluous warning message in <devfs_d_iput>. + v0.69 + 19990611 Richard Gooch <rgooch@atnf.csiro.au> + Took account of change to <d_alloc_root>. + v0.70 + 19990614 Richard Gooch <rgooch@atnf.csiro.au> + Created separate event queue for each mounted devfs. + Removed <devfs_invalidate_dcache>. + Created new ioctl()s. + Incremented devfsd protocol revision to 3. + Fixed bug when re-creating directories: contents were lost. + Block access to inodes until devfsd updates permissions. + 19990615 Richard Gooch <rgooch@atnf.csiro.au> + Support 2.2.x kernels. + v0.71 + 19990623 Richard Gooch <rgooch@atnf.csiro.au> + Switched to sending process uid/gid to devfsd. + Renamed <call_kmod> to <try_modload>. + Added DEVFSD_NOTIFY_LOOKUP event. + 19990624 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFSD_NOTIFY_CHANGE event. + Incremented devfsd protocol revision to 4. + v0.72 + 19990713 Richard Gooch <rgooch@atnf.csiro.au> + Return EISDIR rather than EINVAL for read(2) on directories. + v0.73 + 19990809 Richard Gooch <rgooch@atnf.csiro.au> + Changed <devfs_setup> to new __init scheme. + v0.74 + 19990901 Richard Gooch <rgooch@atnf.csiro.au> + Changed remaining function declarations to new __init scheme. + v0.75 + 19991013 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_get_info>, <devfs_set_info>, + <devfs_get_first_child> and <devfs_get_next_sibling>. + Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>, + <devfs_mk_dir> and <devfs_find_handle>. + Work sponsored by SGI. + v0.76 + 19991017 Richard Gooch <rgooch@atnf.csiro.au> + Allow multiple unregistrations. + Work sponsored by SGI. + v0.77 + 19991026 Richard Gooch <rgooch@atnf.csiro.au> + Added major and minor number to devfsd protocol. + Incremented devfsd protocol revision to 5. + Work sponsored by SGI. + v0.78 + 19991030 Richard Gooch <rgooch@atnf.csiro.au> + Support info pointer for all devfs entry types. + Added <<info>> parameter to <devfs_mk_dir> and + <devfs_mk_symlink>. + Work sponsored by SGI. + v0.79 + 19991031 Richard Gooch <rgooch@atnf.csiro.au> + Support "../" when searching devfs namespace. + Work sponsored by SGI. + v0.80 + 19991101 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_get_unregister_slave>. + Work sponsored by SGI. + v0.81 + 19991103 Richard Gooch <rgooch@atnf.csiro.au> + Exported <devfs_get_parent>. + Work sponsored by SGI. + v0.82 + 19991104 Richard Gooch <rgooch@atnf.csiro.au> + Removed unused <devfs_set_symlink_destination>. + 19991105 Richard Gooch <rgooch@atnf.csiro.au> + Do not hide entries from devfsd or children. + Removed DEVFS_ FL_TTY_COMPAT flag. + Removed "nottycompat" boot option. + Removed <devfs_mk_compat>. + Work sponsored by SGI. + v0.83 + 19991107 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFS_FL_WAIT flag. + Work sponsored by SGI. + v0.84 + 19991107 Richard Gooch <rgooch@atnf.csiro.au> + Support new "disc" naming scheme in <get_removable_partition>. + Allow NULL fops in <devfs_register>. + Work sponsored by SGI. + v0.85 + 19991110 Richard Gooch <rgooch@atnf.csiro.au> + Fall back to major table if NULL fops given to <devfs_register>. + Work sponsored by SGI. + v0.86 + 19991204 Richard Gooch <rgooch@atnf.csiro.au> + Support fifos when unregistering. + Work sponsored by SGI. + v0.87 + 19991209 Richard Gooch <rgooch@atnf.csiro.au> + Removed obsolete DEVFS_ FL_COMPAT and DEVFS_ FL_TOLERANT flags. + Work sponsored by SGI. + v0.88 + 19991214 Richard Gooch <rgooch@atnf.csiro.au> + Removed kmod support. + Work sponsored by SGI. + v0.89 + 19991216 Richard Gooch <rgooch@atnf.csiro.au> + Improved debugging in <get_vfs_inode>. + Ensure dentries created by devfsd will be cleaned up. + Work sponsored by SGI. + v0.90 + 19991223 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_get_name>. + Work sponsored by SGI. + v0.91 + 20000203 Richard Gooch <rgooch@atnf.csiro.au> + Ported to kernel 2.3.42. + Removed <devfs_fill_file>. + Work sponsored by SGI. + v0.92 + 20000306 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFS_ FL_NO_PERSISTENCE flag. + Removed unnecessary call to <update_devfs_inode_from_entry> in + <devfs_readdir>. + Work sponsored by SGI. + v0.93 + 20000413 Richard Gooch <rgooch@atnf.csiro.au> + Set inode->i_size to correct size for symlinks. + 20000414 Richard Gooch <rgooch@atnf.csiro.au> + Only give lookup() method to directories to comply with new VFS + assumptions. + Work sponsored by SGI. + 20000415 Richard Gooch <rgooch@atnf.csiro.au> + Remove unnecessary tests in symlink methods. + Don't kill existing block ops in <devfs_read_inode>. + Work sponsored by SGI. + v0.94 + 20000424 Richard Gooch <rgooch@atnf.csiro.au> + Don't create missing directories in <devfs_find_handle>. + Work sponsored by SGI. + v0.95 + 20000430 Richard Gooch <rgooch@atnf.csiro.au> + Added CONFIG_DEVFS_MOUNT. + Work sponsored by SGI. + v0.96 + 20000608 Richard Gooch <rgooch@atnf.csiro.au> + Disabled multi-mount capability (use VFS bindings instead). + Work sponsored by SGI. + v0.97 + 20000610 Richard Gooch <rgooch@atnf.csiro.au> + Switched to FS_SINGLE to disable multi-mounts. + 20000612 Richard Gooch <rgooch@atnf.csiro.au> + Removed module support. + Removed multi-mount code. + Removed compatibility macros: VFS has changed too much. + Work sponsored by SGI. + v0.98 + 20000614 Richard Gooch <rgooch@atnf.csiro.au> + Merged devfs inode into devfs entry. + Work sponsored by SGI. + v0.99 + 20000619 Richard Gooch <rgooch@atnf.csiro.au> + Removed dead code in <devfs_register> which used to call + <free_dentries>. + Work sponsored by SGI. + v0.100 + 20000621 Richard Gooch <rgooch@atnf.csiro.au> + Changed interface to <devfs_register>. + Work sponsored by SGI. + v0.101 + 20000622 Richard Gooch <rgooch@atnf.csiro.au> + Simplified interface to <devfs_mk_symlink> and <devfs_mk_dir>. + Simplified interface to <devfs_find_handle>. + Work sponsored by SGI. + v0.102 + 20010519 Richard Gooch <rgooch@atnf.csiro.au> + Ensure <devfs_generate_path> terminates string for root entry. + Exported <devfs_get_name> to modules. + 20010520 Richard Gooch <rgooch@atnf.csiro.au> + Make <devfs_mk_symlink> send events to devfsd. + Cleaned up option processing in <devfs_setup>. + 20010521 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bugs in handling symlinks: could leak or cause Oops. + 20010522 Richard Gooch <rgooch@atnf.csiro.au> + Cleaned up directory handling by separating fops. + v0.103 + 20010601 Richard Gooch <rgooch@atnf.csiro.au> + Fixed handling of inverted options in <devfs_setup>. + v0.104 + 20010604 Richard Gooch <rgooch@atnf.csiro.au> + Adjusted <try_modload> to account for <devfs_generate_path> fix. + v0.105 + 20010617 Richard Gooch <rgooch@atnf.csiro.au> + Answered question posed by Al Viro and removed his comments. + Moved setting of registered flag after other fields are changed. + Fixed race between <devfsd_close> and <devfsd_notify_one>. + Global VFS changes added bogus BKL to <devfsd_close>: removed. + Widened locking in <devfs_readlink> and <devfs_follow_link>. + Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc. + Simplified locking in <devfsd_ioctl> and fixed memory leak. + v0.106 + 20010709 Richard Gooch <rgooch@atnf.csiro.au> + Removed broken devnum allocation and use <devfs_alloc_devnum>. + Fixed old devnum leak by calling new <devfs_dealloc_devnum>. + v0.107 + 20010712 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bug in <devfs_setup> which could hang boot process. + v0.108 + 20010730 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFSD_NOTIFY_DELETE event. + 20010801 Richard Gooch <rgooch@atnf.csiro.au> + Removed #include <asm/segment.h>. + v0.109 + 20010807 Richard Gooch <rgooch@atnf.csiro.au> + Fixed inode table races by removing it and using + inode->u.generic_ip instead. + Moved <devfs_read_inode> into <get_vfs_inode>. + Moved <devfs_write_inode> into <devfs_notify_change>. + v0.110 + 20010808 Richard Gooch <rgooch@atnf.csiro.au> + Fixed race in <devfs_do_symlink> for uni-processor. + v0.111 + 20010818 Richard Gooch <rgooch@atnf.csiro.au> + Removed remnant of multi-mount support in <devfs_mknod>. + Removed unused DEVFS_FL_SHOW_UNREG flag. + v0.112 + 20010820 Richard Gooch <rgooch@atnf.csiro.au> + Removed nlink field from struct devfs_inode. + v0.113 + 20010823 Richard Gooch <rgooch@atnf.csiro.au> + Replaced BKL with global rwsem to protect symlink data (quick + and dirty hack). + v0.114 + 20010827 Richard Gooch <rgooch@atnf.csiro.au> + Replaced global rwsem for symlink with per-link refcount. + v0.115 + 20010919 Richard Gooch <rgooch@atnf.csiro.au> + Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>. + v0.116 + 20011008 Richard Gooch <rgooch@atnf.csiro.au> + Fixed overrun in <devfs_link> by removing function (not needed). + 20011009 Richard Gooch <rgooch@atnf.csiro.au> + Fixed buffer underrun in <try_modload>. + 20011029 Richard Gooch <rgooch@atnf.csiro.au> + Fixed race in <devfsd_ioctl> when setting event mask. + 20011114 Richard Gooch <rgooch@atnf.csiro.au> + First release of new locking code. + v1.0 + 20011117 Richard Gooch <rgooch@atnf.csiro.au> + Discard temporary buffer, now use "%s" for dentry names. + 20011118 Richard Gooch <rgooch@atnf.csiro.au> + Don't generate path in <try_modload>: use fake entry instead. + Use "existing" directory in <_devfs_make_parent_for_leaf>. + 20011122 Richard Gooch <rgooch@atnf.csiro.au> + Use slab cache rather than fixed buffer for devfsd events. + v1.1 + 20011125 Richard Gooch <rgooch@atnf.csiro.au> + Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>. + 20011127 Richard Gooch <rgooch@atnf.csiro.au> + Fixed locking bug in <devfs_d_revalidate_wait> due to typo. + Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from + devfsd or children. + v1.2 + 20011202 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bug in <devfsd_read>: was dereferencing freed pointer. + v1.3 + 20011203 Richard Gooch <rgooch@atnf.csiro.au> + Fixed bug in <devfsd_close>: was dereferencing freed pointer. + Added process group check for devfsd privileges. + v1.4 + 20011204 Richard Gooch <rgooch@atnf.csiro.au> + Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>. + v1.5 + 20011211 Richard Gooch <rgooch@atnf.csiro.au> + Return old entry in <devfs_mk_dir> for 2.4.x kernels. + 20011212 Richard Gooch <rgooch@atnf.csiro.au> + Increment refcount on module in <check_disc_changed>. + 20011215 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_get_handle> and exported <devfs_put>. + Increment refcount on module in <devfs_get_ops>. + Created <devfs_put_ops>. + v1.6 + 20011216 Richard Gooch <rgooch@atnf.csiro.au> + Added poisoning to <devfs_put>. + Improved debugging messages. + v1.7 + 20011221 Richard Gooch <rgooch@atnf.csiro.au> + Corrected (made useful) debugging message in <unregister>. + Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs> + 20011224 Richard Gooch <rgooch@atnf.csiro.au> + Added magic number to guard against scribbling drivers. + 20011226 Richard Gooch <rgooch@atnf.csiro.au> + Only return old entry in <devfs_mk_dir> if a directory. + Defined macros for error and debug messages. + v1.8 + 20020113 Richard Gooch <rgooch@atnf.csiro.au> + Fixed (rare, old) race in <devfs_lookup>. + v1.9 + 20020120 Richard Gooch <rgooch@atnf.csiro.au> + Fixed deadlock bug in <devfs_d_revalidate_wait>. + Tag VFS deletable in <devfs_mk_symlink> if handle ignored. + v1.10 + 20020129 Richard Gooch <rgooch@atnf.csiro.au> + Added KERN_* to remaining messages. + Cleaned up declaration of <stat_read>. + v1.11 + 20020219 Richard Gooch <rgooch@atnf.csiro.au> + Changed <devfs_rmdir> to allow later additions if not yet empty. + v1.12 + 20020406 Richard Gooch <rgooch@atnf.csiro.au> + Removed silently introduced calls to lock_kernel() and + unlock_kernel() due to recent VFS locking changes. BKL isn't + required in devfs. + v1.13 + 20020428 Richard Gooch <rgooch@atnf.csiro.au> + Removed 2.4.x compatibility code. + v1.14 + 20020510 Richard Gooch <rgooch@atnf.csiro.au> + Added BKL to <devfs_open> because drivers still need it. + v1.15 + 20020512 Richard Gooch <rgooch@atnf.csiro.au> + Protected <scan_dir_for_removable> and <get_removable_partition> + from changing directory contents. + v1.16 + 20020514 Richard Gooch <rgooch@atnf.csiro.au> + Minor cleanup of <scan_dir_for_removable>. + v1.17 + 20020721 Richard Gooch <rgooch@atnf.csiro.au> + Switched to ISO C structure field initialisers. + Switch to set_current_state() and move before add_wait_queue(). + 20020722 Richard Gooch <rgooch@atnf.csiro.au> + Fixed devfs entry leak in <devfs_readdir> when *readdir fails. + v1.18 + 20020725 Richard Gooch <rgooch@atnf.csiro.au> + Created <devfs_find_and_unregister>. + v1.19 + 20020728 Richard Gooch <rgooch@atnf.csiro.au> + Removed deprecated <devfs_find_handle>. + v1.20 + 20020820 Richard Gooch <rgooch@atnf.csiro.au> + Fixed module unload race in <devfs_open>. + v1.21 + 20021013 Richard Gooch <rgooch@atnf.csiro.au> + Removed DEVFS_ FL_AUTO_OWNER. + Switched lingering structure field initialiser to ISO C. + Added locking when updating FCB flags. + v1.22 +*/ +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/tty.h> +#include <linux/timer.h> +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/wait.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/ioport.h> +#include <linux/delay.h> +#include <linux/ctype.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/devfs_fs.h> +#include <linux/devfs_fs_kernel.h> +#include <linux/smp_lock.h> +#include <linux/smp.h> +#include <linux/rwsem.h> +#include <linux/sched.h> +#include <linux/namei.h> +#include <linux/bitops.h> + +#include <asm/uaccess.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/atomic.h> + +#define DEVFS_VERSION "2004-01-31" + +#define DEVFS_NAME "devfs" + +#define FIRST_INODE 1 + +#define STRING_LENGTH 256 +#define FAKE_BLOCK_SIZE 1024 +#define POISON_PTR ( *(void **) poison_array ) +#define MAGIC_VALUE 0x327db823 + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#define MODE_DIR (S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO) + +#define DEBUG_NONE 0x0000000 +#define DEBUG_MODULE_LOAD 0x0000001 +#define DEBUG_REGISTER 0x0000002 +#define DEBUG_UNREGISTER 0x0000004 +#define DEBUG_FREE 0x0000008 +#define DEBUG_SET_FLAGS 0x0000010 +#define DEBUG_S_READ 0x0000100 /* Break */ +#define DEBUG_I_LOOKUP 0x0001000 /* Break */ +#define DEBUG_I_CREATE 0x0002000 +#define DEBUG_I_GET 0x0004000 +#define DEBUG_I_CHANGE 0x0008000 +#define DEBUG_I_UNLINK 0x0010000 +#define DEBUG_I_RLINK 0x0020000 +#define DEBUG_I_FLINK 0x0040000 +#define DEBUG_I_MKNOD 0x0080000 +#define DEBUG_F_READDIR 0x0100000 /* Break */ +#define DEBUG_D_DELETE 0x1000000 /* Break */ +#define DEBUG_D_RELEASE 0x2000000 +#define DEBUG_D_IPUT 0x4000000 +#define DEBUG_ALL 0xfffffff +#define DEBUG_DISABLED DEBUG_NONE + +#define OPTION_NONE 0x00 +#define OPTION_MOUNT 0x01 + +#define PRINTK(format, args...) \ + {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);} + +#define OOPS(format, args...) \ + {printk (KERN_CRIT "%s" format, __FUNCTION__ , ## args); \ + printk ("Forcing Oops\n"); \ + BUG();} + +#ifdef CONFIG_DEVFS_DEBUG +# define VERIFY_ENTRY(de) \ + {if ((de) && (de)->magic_number != MAGIC_VALUE) \ + OOPS ("(%p): bad magic value: %x\n", (de), (de)->magic_number);} +# define WRITE_ENTRY_MAGIC(de,magic) (de)->magic_number = (magic) +# define DPRINTK(flag, format, args...) \ + {if (devfs_debug & flag) \ + printk (KERN_INFO "%s" format, __FUNCTION__ , ## args);} +#else +# define VERIFY_ENTRY(de) +# define WRITE_ENTRY_MAGIC(de,magic) +# define DPRINTK(flag, format, args...) +#endif + +typedef struct devfs_entry *devfs_handle_t; + +struct directory_type { + rwlock_t lock; /* Lock for searching(R)/updating(W) */ + struct devfs_entry *first; + struct devfs_entry *last; + unsigned char no_more_additions:1; +}; + +struct symlink_type { + unsigned int length; /* Not including the NULL-termimator */ + char *linkname; /* This is NULL-terminated */ +}; + +struct devfs_inode { /* This structure is for "persistent" inode storage */ + struct dentry *dentry; + struct timespec atime; + struct timespec mtime; + struct timespec ctime; + unsigned int ino; /* Inode number as seen in the VFS */ + uid_t uid; + gid_t gid; +}; + +struct devfs_entry { +#ifdef CONFIG_DEVFS_DEBUG + unsigned int magic_number; +#endif + void *info; + atomic_t refcount; /* When this drops to zero, it's unused */ + union { + struct directory_type dir; + dev_t dev; + struct symlink_type symlink; + const char *name; /* Only used for (mode == 0) */ + } u; + struct devfs_entry *prev; /* Previous entry in the parent directory */ + struct devfs_entry *next; /* Next entry in the parent directory */ + struct devfs_entry *parent; /* The parent directory */ + struct devfs_inode inode; + umode_t mode; + unsigned short namelen; /* I think 64k+ filenames are a way off... */ + unsigned char vfs:1; /* Whether the VFS may delete the entry */ + char name[1]; /* This is just a dummy: the allocated array + is bigger. This is NULL-terminated */ +}; + +/* The root of the device tree */ +static struct devfs_entry *root_entry; + +struct devfsd_buf_entry { + struct devfs_entry *de; /* The name is generated with this */ + unsigned short type; /* The type of event */ + umode_t mode; + uid_t uid; + gid_t gid; + struct devfsd_buf_entry *next; +}; + +struct fs_info { /* This structure is for the mounted devfs */ + struct super_block *sb; + spinlock_t devfsd_buffer_lock; /* Lock when inserting/deleting events */ + struct devfsd_buf_entry *devfsd_first_event; + struct devfsd_buf_entry *devfsd_last_event; + volatile int devfsd_sleeping; + volatile struct task_struct *devfsd_task; + volatile pid_t devfsd_pgrp; + volatile struct file *devfsd_file; + struct devfsd_notify_struct *devfsd_info; + volatile unsigned long devfsd_event_mask; + atomic_t devfsd_overrun_count; + wait_queue_head_t devfsd_wait_queue; /* Wake devfsd on input */ + wait_queue_head_t revalidate_wait_queue; /* Wake when devfsd sleeps */ +}; + +static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED }; +static kmem_cache_t *devfsd_buf_cache; +#ifdef CONFIG_DEVFS_DEBUG +static unsigned int devfs_debug_init __initdata = DEBUG_NONE; +static unsigned int devfs_debug = DEBUG_NONE; +static DEFINE_SPINLOCK(stat_lock); +static unsigned int stat_num_entries; +static unsigned int stat_num_bytes; +#endif +static unsigned char poison_array[8] = + { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a }; + +#ifdef CONFIG_DEVFS_MOUNT +static unsigned int boot_options = OPTION_MOUNT; +#else +static unsigned int boot_options = OPTION_NONE; +#endif + +/* Forward function declarations */ +static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir, + const char *name, int namelen, + int traverse_symlink); +static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len, + loff_t * ppos); +static int devfsd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +static int devfsd_close(struct inode *inode, struct file *file); +#ifdef CONFIG_DEVFS_DEBUG +static ssize_t stat_read(struct file *file, char __user *buf, size_t len, + loff_t * ppos); +static struct file_operations stat_fops = { + .open = nonseekable_open, + .read = stat_read, +}; +#endif + +/* Devfs daemon file operations */ +static struct file_operations devfsd_fops = { + .open = nonseekable_open, + .read = devfsd_read, + .ioctl = devfsd_ioctl, + .release = devfsd_close, +}; + +/* Support functions follow */ + +/** + * devfs_get - Get a reference to a devfs entry. + * @de: The devfs entry. + */ + +static struct devfs_entry *devfs_get(struct devfs_entry *de) +{ + VERIFY_ENTRY(de); |