The following patch replaces devfs with a ramfs-derived
implementation which is under one quarter the size although it
eliminates certain functionality.
wc -l *.c Makefile size (text + data + bss)
devfs 3614 lines 25,863 bytes
mini-devfs 629 lines 5,367 bytes
Reduction 5.7x 4.8x
Further minor reductions may be possible from some additional
clean-ups and perhaps a simplification to the programming interface.
This code is probably very buggy. I've just gotten it working
on the machine on which I'm composing this message. It is not ready
for integration yet. I would particularly appreciate help with the
dentry manipulation and locking, which I think I've probably botched.
The notable differences between devfs and mini-devfs are:
1. devfsd has been replaced with the user mode helper
/sbin/devfs_helper which is exec'ed for registration and initial
lookup events (I could catch all the events that devfs does, but I
don't think that's really necessary). I have yet to port devfsd to
this interface. When sysfs support is added to the new kernel
parameter system, I will make this a kernel parameter, so it can be
off initially, and only turned on by systems that use it when the boot
process is ready for it. This will also eliminate the problem where
the boot process currently tries to do 200+ execs as each pseudo-terminal
is registered.
2. The removable device code that cleared and reread partition
tables from removable media all the time preventing use of userland
partitioning with devfs is eliminated. (Non-devfs systems never had
this problem.)
3. devfs_handle_t is now a synonym for struct dentry*.
4. A lot of the devfs routines are unimplemented. I haven't
noticed much code that uses them, and I'm not sure that any code
really should. I think arch/ia64/sn uses devfs_get_first_child,
devfs_get_next_sibling. I need to understand what if any of the
other routines are really necessary and why (for example, why can't
we use struct dentry). My computer seems to run fine without them.
TODO:
First of all, I'd like to debug this code and I'd welcome any
help. The only malfunction (aside from routines that aren't written)
that I've noticed is that previously xdm would give up after trying to
start the X server about five times (it is not configured). With this
smaller devfs, xdm keeps trying to start the X server. Also, I'm
pretty sure that my code is at least releasing and reacquiring
dcache_lock when it shouldn't, and I think there may be some similar
inode->i_sem issues.
In the future, I'd like to shrink the devfs interface to
devfs_{create,delete}. If we prohibit file renaming in devfs, then
drivers can be sure they've removed the devfs nodes that they've
created when they delete the paths that they've created. A
side-effect of this would be that devfs_handle_t would be eliminated.
I still want the ability to pass a struct file_operations* to
devfs_create as it may enable the elimination of fixed device numbers.
I think I'd like to change fs/super.c slightly to make it
easier to statically allocate the struct super_block for filesystems
that can have only one instance even if they are mounted in multiple
locations (devfs, procfs, sysfs, usbdevfs, etc.).
I started hacking on this code by making an approximately ten
line change to ramfs just to have it call a user level program on
lookups and file creation. I had hoped to change the devfs routines
to just generically operate on whatever was mounted on /dev. If
the devfs API were shrunk substantially, it might be worth trying
that approach again.
Comments?
--
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
I have made a new version of my mini-devfs (attached below).
I have also made a first version of my devfs_helper program to handle
the functionality of devfsd on systems that use my mini-devfs.
devfs_helper is avaiable from the following location:
ftp://ftp.yggdrasil.com/pub/dist/device_control/devfs_helper/devfs_helper-0.1.tar.gz
This version of devfs_helper only supports "EXECUTE" and
"MODLOAD" actions, which may be the only events that are really
necessary. In the future, I envision eliminating the "MODLOAD"
action, since it is equivalent to
"EXECUTE modprobe -C /etc/modprobe.devfs $devname".
devfs_helper is currently 211 lines of C code. In comparison,
devfsd-1.3.25/*.[ch] is 3143 lines.
Also, here is version 2 of my mini-devfs. I am embarassed
to say that I omitted Richard Gooch's copyright notice on his code that
I copoied into mini-devfs/numspace.c. This patch corrects that and
fixes a variety of other little problems. It also changes the directory
of this facility to fs/mini-devfs/. One change that is necessary for
operation with devfs_helper is that the event names are now in all
capitals ("REGISTER" and "LOOKUP") to match the format of /etc/devfsd.conf.
mini-devfs has grown by 21 lines, mostly due to my restoring
Richard's copyright notice. Here is an updated size comparison in case
anyone is interested:
devfs 3614 lines 25,863 bytes
mini-devfs 650 lines 5,562 bytes
Reduction 5.6x 4.6x
--
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
On Tue, Dec 31, 2002 at 06:24:22PM -0800, Adam J. Richter wrote:
> The following patch replaces devfs with a ramfs-derived
> implementation which is under one quarter the size although it
> eliminates certain functionality.
>
> wc -l *.c Makefile size (text + data + bss)
>
> devfs 3614 lines 25,863 bytes
> mini-devfs 629 lines 5,367 bytes
> Reduction 5.7x 4.8x
Wow, that looks really cool! I just wonder where viro is hiding the last
weeks, he promised more devfs API cleanups that likely clash with
your changes.
> 3. devfs_handle_t is now a synonym for struct dentry*.
I wonder whether some code uses struct devfs_entry * directly, at least
I was tempted to do so in the scsi midlayer.
> 4. A lot of the devfs routines are unimplemented. I haven't
> noticed much code that uses them, and I'm not sure that any code
> really should. I think arch/ia64/sn uses devfs_get_first_child,
> devfs_get_next_sibling. I need to understand what if any of the
> other routines are really necessary and why (for example, why can't
> we use struct dentry). My computer seems to run fine without them.
The hcl code in arch/ia64/sn/ is supposed to get replaced by a filesystem
on it's own once the sn port is properly updated for 2.5/2.6.
> First of all, I'd like to debug this code and I'd welcome any
> help.
Is it supposed to work out of the box on previously (and for 2.4 use)
non-devfs systems? I still don't plan to use devfs, but such an effort
is really worth some debugging help..
> I think I'd like to change fs/super.c slightly to make it
> easier to statically allocate the struct super_block for filesystems
> that can have only one instance even if they are mounted in multiple
> locations (devfs, procfs, sysfs, usbdevfs, etc.).
Why do you want to allocate it statically?
> @@ -24,7 +24,11 @@
> #define DEVFS_SPECIAL_CHR 0
> #define DEVFS_SPECIAL_BLK 1
>
> +#ifdef CONFIG_DEVFS_SMALL
> +typedef struct dentry * devfs_handle_t;
> +#else
> typedef struct devfs_entry * devfs_handle_t;
> +#endif
Do you really need to keep both around?
> +/* On success, returns with (*parent_inode)->i_sem taken. */
> +static int devfs_decode(devfs_handle_t dir, const char *name, int is_dir,
> + struct inode **parent_inode, struct dentry **dentry)
Do we really have to support this?
> +++ linux/fs/devfs2/numspace.c 2002-12-25 17:44:14.000000000 -0800
> @@ -0,0 +1,76 @@
> +#include <linux/module.h>
> +#include <linux/vmalloc.h>
> +#include <linux/devfs_fs_kernel.h>
> +
> +/**
> + * devfs_alloc_unique_number - Allocate a unique (positive) number.
> + * @space: The number space to allocate from.
> + *
> + * Returns the allocated unique number, else a negative error code.
> + * This routine is thread safe and may block.
> + */
> +
> +int devfs_alloc_unique_number (struct unique_numspace *space)
Remove the devfs_ prefix here (it's not devfs-specific at all) and
convert to sane indentation?
>On Tue, Dec 31, 2002 at 06:24:22PM -0800, Adam J. Richter wrote:
>> The following patch replaces devfs with a ramfs-derived
>> implementation which is under one quarter the size although it
>> eliminates certain functionality.
>>
>> wc -l *.c Makefile size (text + data + bss)
>>
>> devfs 3614 lines 25,863 bytes
>> mini-devfs 629 lines 5,367 bytes
>> Reduction 5.7x 4.8x
>Wow, that looks really cool! I just wonder where viro is hiding the last
>weeks, he promised more devfs API cleanups that likely clash with
>your changes.
I don't know what devfs API changes he wants to make, but I
imagine that I can probably follow them.
The one devfs quirk that I really like that one might be
tempted to eliminate is that you can pass a file_operations pointer to
devfs_register, which enables the possibility in future of being able
to build systems that just use devfs names for identifying devices.
>> 3. devfs_handle_t is now a synonym for struct dentry*.
>I wonder whether some code uses struct devfs_entry * directly, at least
>I was tempted to do so in the scsi midlayer.
Thankfully, struct devfs_entry* is an opaque pointer. The
struct is only defined in fs/devfs/base.c. Searching with
"find . -name '*.[ch]' | xargs grep -w devfs_entry" indicates
that everyone declares devfs_handle_t instead of "struct devfs_entry*",
so that's not a problem either.
Your question prompted me to do a little bit of research.
I believe the list of routines that my reduced devfs does not
implement is as follows:
devfs_get_handle
devfs_get_handle_from_inode
devfs_set_file_size
devfs_get_info
devfs_set_info
devfs_get_parent
devfs_get_first_child
devfs_get_next_sibling
devfs_get_name
devfs_register_tape
devfs_unregister_tape
devfs_alloc_major
devfs_dealloc_major
devfs_alloc_devnum
devfs_dealloc_devnum
Storing this list in /tmp/names and grepping for these
identifiers shows only a small number of hits:
% find . -name '*.[ch]' | xargs fgrep -l -w -f /tmp/names
./arch/i386/kernel/cpu/mtrr/if.c
./arch/i386/kernel/microcode.c
./arch/ia64/sn/io/sn1/hubcounters.c
./arch/ia64/sn/io/hcl.c
./arch/ia64/sn/io/labelcl.c
./arch/ia64/sn/kernel/sn1/synergy.c
./arch/x86_64/kernel/mtrr.c
./drivers/ide/ide-tape.c
./drivers/media/radio/miropcm20-rds.c
./drivers/scsi/osst.c
./drivers/scsi/st.c
./fs/devfs/base.c
./fs/devfs/util.c
./fs/mini-devfs/inode.c
./include/linux/devfs_fs_kernel.h
Also, drivers/media/dvb/dvb-core/dvbdev.c has an option
to use DEVFS_F_AUTO_DEVNUM, which my devfs code does not yet support,
but, still it looks like the compatability issues may be pretty small.
>> 4. A lot of the devfs routines are unimplemented. I haven't
>> noticed much code that uses them, and I'm not sure that any code
>> really should. I think arch/ia64/sn uses devfs_get_first_child,
>> devfs_get_next_sibling. I need to understand what if any of the
>> other routines are really necessary and why (for example, why can't
>> we use struct dentry). My computer seems to run fine without them.
>The hcl code in arch/ia64/sn/ is supposed to get replaced by a filesystem
>on it's own once the sn port is properly updated for 2.5/2.6.
Great.
>> First of all, I'd like to debug this code and I'd welcome any
>> help.
>Is it supposed to work out of the box on previously (and for 2.4 use)
>non-devfs systems? I still don't plan to use devfs, but such an effort
>is really worth some debugging help..
Thanks for the encouragement.
>> I think I'd like to change fs/super.c slightly to make it
>> easier to statically allocate the struct super_block for filesystems
>> that can have only one instance even if they are mounted in multiple
>> locations (devfs, procfs, sysfs, usbdevfs, etc.).
>Why do you want to allocate it statically?
A few fields could be initialized statically. A few bytes
would be saved from memory allocation overhead. Cache locality would
improve infinitesemally. If all one-instance filesystems are changed
to do this, it will eliminate one memory allocation failure branch in
fs/super.c. Perhaps the same could be done with the root inode. I
know this is pretty marginal and might end up adding more complexity
than it would save. It's at the bottom of my TODO (or "to try") list.
>> @@ -24,7 +24,11 @@
>> #define DEVFS_SPECIAL_CHR 0
>> #define DEVFS_SPECIAL_BLK 1
>>
>> +#ifdef CONFIG_DEVFS_SMALL
>> +typedef struct dentry * devfs_handle_t;
>> +#else
>> typedef struct devfs_entry * devfs_handle_t;
>> +#endif
>Do you really need to keep both around?
I am starting by posting this as an addition in case it turns
out that there is a camp that needs the existing devfs. If that does
not appear to be the case, then I'd be happy to make a patch to remove
the current devfs.
>> +/* On success, returns with (*parent_inode)->i_sem taken. */
>> +static int devfs_decode(devfs_handle_t dir, const char *name, int is_dir,
>> + struct inode **parent_inode, struct dentry **dentry)
>Do we really have to support this?
It's a static routine to support the existing devfs interface.
Later, the devfs interface can be simplified to eliminate the need
for this routine and perhaps walk_parents_mkdir.
>> +++ linux/fs/devfs2/numspace.c 2002-12-25 17:44:14.000000000 -0800
[...]
>> +int devfs_alloc_unique_number (struct unique_numspace *space)
>Remove the devfs_ prefix here (it's not devfs-specific at all) and
>convert to sane indentation?
I'm trying to first land a patch that involves no changes to
users of devfs. After that, I expect this code to be completely
replaced soon anyhow as a result of efforts independent of devfs
(probably by an enhanced number allocation facility for
device_interface in drivers/base/). Currently
devfs_alloc_unique_number is used only to allocate disk numbers in
/dev/discs/discNNN/. If my shruken devfs gets integrated and
devfs_alloc_unique_number is still in use, I'd be happy to make the
change you suggest. I'd just rather do integration as a separate
phase from API changes to keep the patches somewhat comprehensible.
Anyhow, thanks for all of the feedback.
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
jobs
On Wed, Jan 01, 2003 at 11:13:02AM -0800, Adam J. Richter wrote:
> >I wonder whether some code uses struct devfs_entry * directly, at least
> >I was tempted to do so in the scsi midlayer.
>
> Thankfully, struct devfs_entry* is an opaque pointer.
I know. IMHO it's still preferable to use struct devfs_entry * over
devfs_handle_t like all the devfs mess does. This would work when
devfs_handle_t suddenly points to something else.
The
> struct is only defined in fs/devfs/base.c. Searching with
> "find . -name '*.[ch]' | xargs grep -w devfs_entry" indicates
> that everyone declares devfs_handle_t instead of "struct devfs_entry*",
> so that's not a problem either.
OK.
> Your question prompted me to do a little bit of research.
> I believe the list of routines that my reduced devfs does not
> implement is as follows:
>
> devfs_get_handle
> devfs_get_handle_from_inode
> devfs_set_file_size
> devfs_get_info
> devfs_set_info
> devfs_get_parent
> devfs_get_first_child
> devfs_get_next_sibling
> devfs_get_name
> devfs_register_tape
> devfs_unregister_tape
> devfs_alloc_major
> devfs_dealloc_major
> devfs_alloc_devnum
> devfs_dealloc_devnum
>
> Storing this list in /tmp/names and grepping for these
> identifiers shows only a small number of hits:
<snip>
At least the devfs_set_* / devfs_get_* can be removed easily when
leaving the sn1 stuff danling. But I already discussed that with
the responsible persons.
> >Is it supposed to work out of the box on previously (and for 2.4 use)
> >non-devfs systems? I still don't plan to use devfs, but such an effort
> >is really worth some debugging help..
>
> Thanks for the encouragement.
So is the answer yes or no now? :)
> >Why do you want to allocate it statically?
>
> A few fields could be initialized statically. A few bytes
> would be saved from memory allocation overhead. Cache locality would
> improve infinitesemally. If all one-instance filesystems are changed
> to do this, it will eliminate one memory allocation failure branch in
> fs/super.c. Perhaps the same could be done with the root inode. I
> know this is pretty marginal and might end up adding more complexity
> than it would save. It's at the bottom of my TODO (or "to try") list.
Hmm. I don't think it's worth the effort, but if you can do it without
introducing major ugliness you have my vote.
Just to keep everyone up to date, here is a third iteration of
my patch converting devfs to a ramfs-based file system. This one uses
an almost unmodified version of devfs/util.c to restore automatic
device number allocation and devfs_{,un}register_tape().
This code now tries to implement almost all of the devfs
functionality that anything outside of arch/ia64/sn uses. The most
significant except that I'm aware of is the ability to create a plain
file with custom file operations, which is done the Memory Type Range
Register code, but that code also provides a proc interface for the
same thing, and I think the proc interface is what everyone uses right
now anyhow.
If Christoph's patch for deleting a bunch of unused stuff from
devfs gets into 2.5.54, that should make my patch smaller, and I'll
post a new version then. If nobody objects, then perhaps I'll make
that version replace fs/devfs rather than creating a separate
fs/mini-devfs.
--
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
On Wed, Jan 01, 2003 at 04:51:21PM -0800, Adam J. Richter wrote:
> The most
> significant except that I'm aware of is the ability to create a plain
> file with custom file operations, which is done the Memory Type Range
> Register code, but that code also provides a proc interface for the
> same thing, and I think the proc interface is what everyone uses right
> now anyhow.
There is some userspace code out there doing ioctls on /dev/mtrr
The testgart app uses it, and I *think* thats what X uses.
Dave
--
| Dave Jones. http://www.codemonkey.org.uk
| SuSE Labs
On Wed, Jan 01, 2003 at 04:51:21PM -0800, Adam J. Richter wrote:
> This code now tries to implement almost all of the devfs
> functionality that anything outside of arch/ia64/sn uses. The most
> significant except that I'm aware of is the ability to create a plain
> file with custom file operations, which is done the Memory Type Range
> Register code, but that code also provides a proc interface for the
> same thing, and I think the proc interface is what everyone uses right
> now anyhow.
Ignore other mail. -ENOTAWAKEYET
testgart uses /proc/mtrr too, and thinking about it I guess X does
too, or it would break in the non-devfs case.
Dave
--
| Dave Jones. http://www.codemonkey.org.uk
| SuSE Labs
Dave Jones wrote:
>Ignore other mail. -ENOTAWAKEYET
>testgart uses /proc/mtrr too, and thinking about it I guess X does
>too, or it would break in the non-devfs case.
By the way, your first email prompted me to try X on an AGP
video card with my mini-devfs, and it seems to be fine. I'm composing
this message on it.
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."