All of lore.kernel.org
 help / color / mirror / Atom feed
* Driverfs updates
@ 2002-07-08 18:41 Patrick Mochel
  2002-07-08 23:33 ` Keith Owens
  0 siblings, 1 reply; 20+ messages in thread
From: Patrick Mochel @ 2002-07-08 18:41 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel


Quick Summary

- Add struct module * owner field to struct device_driver
- Change {get,put}_driver to use it

- Add void * object to struct driver_file_entry that points to owner of 
  file.
- Add struct driverfs_subsys with {get,put}_object callbacks to do generic 
  reference counting on file open/release

- Convert driverfs interface to struct devices to use above mechnanism
- Add 'bindings' between struct device_driver and struct bus_type, using 
  above mechanism to do proper reference counting on objects. 

Pull from bk://ldm.bkbits.net/linux-2.5-driverfs

Patch also available from:

http://kernel.org/pub/linux/kernel/people/mochel/patches/driverfs-patch-08072002.gz


Changelog and diffstat appended. 

Explanation:

driverfs currently does reference counting on struct device on file open() 
and release(). It accesses the device by doing a list_entry on the 
parent directory entry of the driver_file_entry (which is in the inode's 
u.generic_ip). 

This works fine, but is not very extensible to other objects that we want 
to export files for, like struct device_driver. One way to do it is create 
separate open/release callbacks for each object type that does a similar
list_entry. But, I considered that bulky and instead genericized a sole 
pair of open and release calls. 

To make it work for all objects, I added 

        void    * object;

to struct driver_file_entry, and created 

struct driverfs_subsys {
        int     (*get_object)(void * obj);
        void    (*put_object)(void * obj);
};

and 
        struct driverfs_subsys  * subsys;

in struct driver_dir_entry to do reference counting on that object.

Wait, come back; it should work. 


Each type of object that is represented in driverfs gets a directory that 
is created when registered with the subsystem they belong to. When this 
directory is created, the subsystem is responsible for setting the 
subsys pointer in the directory entry. 

To create files, there should be wrapper functions for each type of object 
that take an explicit pointer to that object. E.g. 

device_create_file
driver_create_file
etc. 

The subsystem is responsibile for setting the object pointer on file 
creation. 

During open(), we get the driver_file_entry from the inode's u.generic_ip. 
>From that, we get the parent driver_dir_entry and the subsys structure. We 
pass the driver_file_entry::object to the subsys's get_object() callback. 
The subsystem pins the object in memory, and life is a bit happier. 

On release, we do the same in order to call put_object().

Having get/set functions that take opaque pointers can appear to 
completely sacrifice type-safety. However, the fact that the only thing we 
have to work with initially is an opaque pointer in u.generic_ip makes 
that point, IMHO. 

Plus, the driverfs code never relies on the validity of that pointer. It 
simply passes it back to the subsystem to verify it and refcount. It's the 
sole responsibility of the subsystem to not do something stupid. 

It is possible to change the contents of the object pointer, the
driver_file_entry, or the inode after the file has been created. But, if
you aim the gun at your foot, and your finger slips off the trigger, it's
not my fault...


Anyway, it is now really easy to extend driverfs to support any type of   
object. To add 'bindings' for a particular object type, it is literally   
about 45 lines (excluding comments). See drivers/base/fs/*.c for examples.


Concerning reference counting on objects that aren't devices; i.e.  
drivers: Drivers can be modular, and the refcount wasn't tied to the
module refcount. I went around a few times with Kai about this, about a
month ago. What I ended doing was adding an owner field to the
device_driver structure, and using that to do refcounting.

During normal operation, the refcount stays at 0, so the module can be 
removed. During any access to the driver, it bumps up the refcount. (This 
likely still suffers from the same module race conditions, but it's a step 
in the right direction.)


I've also updated the driverfs documentation to reflect the recent changes 
and removed most gross inaccuracies. 


	-pat


ChangeSet@1.447.23.1, 2002-06-10 09:12:20-07:00, mochel@osdl.org
  driver refcounting:
  Make {get,put}_driver simply wrappers for touching module reference count
  Get rid of driver's release callback
  Rename remove_driver to driver_unregister

diffstat results: 
 drivers/base/driver.c    |   53 +++++++++++++++++++++++------------------------
 drivers/pci/pci-driver.c |    2 -
 include/linux/device.h   |   14 ++----------
 3 files changed, 31 insertions, 38 deletions

ChangeSet@1.604.3.13, 2002-07-03 13:40:09-07:00, mochel@osdl.org
  Don't set module owner in driver_register, that's just dumb. Drivers need to do it explicitly. 

diffstat results: 
 drivers/base/driver.c |    1 -
 1 files changed, 1 deletion

ChangeSet@1.604.3.14, 2002-07-03 13:59:55-07:00, mochel@osdl.org
  driverfs: Break out file creation functions from inode.c into lib.c

diffstat results: 
 fs/driverfs/Makefile |    4 
 fs/driverfs/inode.c  |  278 -------------------------------------------------
 fs/driverfs/lib.c    |  289 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 292 insertions, 279 deletions

ChangeSet@1.604.3.15, 2002-07-03 14:21:45-07:00, mochel@osdl.org
  driverfs:
  - typedef show and store callbacks in driver_file_entry
  - Add an object pointer that points to the object that owns the file

diffstat results: 
 include/linux/driverfs_fs.h |    9 +++++++--
 1 files changed, 7 insertions, 2 deletions

ChangeSet@1.604.3.16, 2002-07-03 14:22:41-07:00, mochel@osdl.org
  driverfs file creation for devices:
  Set the object pointer in the struct driver_file_entry when creating a file for the device

diffstat results: 
 drivers/base/fs.c |    2 ++
 1 files changed, 2 insertions

ChangeSet@1.604.3.17, 2002-07-03 14:24:04-07:00, mochel@osdl.org
  driverfs:
  - Use the object field of struct driver_file_entry when calling the owner's show and store callbacks
  - Use the object field on open and release, instead of using list_entry

diffstat results: 
 fs/driverfs/inode.c |   14 ++++----------
 1 files changed, 4 insertions, 10 deletions

ChangeSet@1.604.3.18, 2002-07-03 15:31:56-07:00, mochel@osdl.org
  driverfs:
  - add driverfs_subsys to describe a subsystem that owns a class of objects that are represented in driverfs
  Previously, all directories in driverfs mapped to struct device's. This assumption was used to do reference 
  counting on the devices. They were also passed to the show and store callbacks of the file owners. 
  
  However, now we want to be able to add files for other types of objects. We want to do reference counting on these 
  objects, and pass them downstream. The show and store callbacks were modified to take void *, instead of creating
  a different type of show and store for each type of object that can have files. 
  
  Reference counting takes place in file open and release. Instead of defining a completely separate open and release
  for each subsystem or type of object, I've implemented only what we need - callbacks to increment and decrement
  the reference count of the target objects. 
  
  It's assumed that each object that has presence in driverfs has a directory. When this directory is created (by the
  subsystem that owns it), it the subsys field needs to be set appropriately. 
  

diffstat results: 
 include/linux/driverfs_fs.h |    6 ++++++
 1 files changed, 6 insertions

ChangeSet@1.604.3.19, 2002-07-03 15:37:54-07:00, mochel@osdl.org
  driverfs:
  Use the driverfs_subsys types in open and release to do reference counting on the object that owns the file
  It tries to be stringent about the whole situation:
  - Return an error if 
  	- no subsys is present
  	- get_object() fails (returns 0)
  - Don't return error if 
  	- get_object() isn't implemented (no ref counting on objects)
  	- get_object() returns 1
  
  On release, it's assumed the subsys pointer is valid, since we wouldn't have allowed file open if it wasn't.

diffstat results: 
 fs/driverfs/inode.c |   31 ++++++++++++++++++++++---------
 1 files changed, 22 insertions, 9 deletions

ChangeSet@1.604.3.20, 2002-07-03 15:39:08-07:00, mochel@osdl.org
  device <-> driverfs interface:
  Declare a driverfs_device_subsys, complete with get_object and put_object callbacks
  Set the pointer in device's directory entry when their directory is created

diffstat results: 
 drivers/base/fs.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions

ChangeSet@1.604.3.21, 2002-07-03 16:58:18-07:00, mochel@osdl.org
  device model:
  Move driverfs interface (fs.c) to drivers/base/fs/

diffstat results: 
 drivers/base/fs.c        |  217 -----------------------------------------------
 drivers/base/Makefile    |    4 
 drivers/base/fs/Makefile |    5 +
 drivers/base/fs/fs.c     |  217 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 225 insertions, 218 deletions

ChangeSet@1.604.3.22, 2002-07-03 17:04:29-07:00, mochel@osdl.org
  device model - driverfs bindings:
  Move device <-> driverfs binding to separate file; pave way for new bindings to come 

diffstat results: 
 drivers/base/fs/Makefile |    4 -
 drivers/base/fs/device.c |  127 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/base/fs/fs.c     |  116 ------------------------------------------
 drivers/base/fs/fs.h     |    5 +
 4 files changed, 134 insertions, 118 deletions

ChangeSet@1.604.3.23, 2002-07-03 17:42:02-07:00, mochel@osdl.org
  device model:
  - move driverfs <-> bus bindings into drivers/base/fs/bus.c
  - add helpers to create/remove files for buses

diffstat results: 
 drivers/base/base.h      |    3 +
 drivers/base/bus.c       |   38 -----------------
 drivers/base/fs/Makefile |    4 -
 drivers/base/fs/bus.c    |  105 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions, 39 deletions

ChangeSet@1.604.3.24, 2002-07-03 17:54:20-07:00, mochel@osdl.org
  device model driverfs bindings:
  Implement device_dup_file for use by various specific bindings:
  - allocate new driver_file_entry
  - copy template in
  - create driverfs file
  - return error to caller

diffstat results: 
 drivers/base/fs/bus.c    |   22 +++++-----------------
 drivers/base/fs/device.c |   24 ++++++------------------
 drivers/base/fs/fs.c     |   18 ++++++++++++++++++
 drivers/base/fs/fs.h     |    2 ++
 4 files changed, 31 insertions, 35 deletions

ChangeSet@1.604.3.25, 2002-07-05 13:55:01-07:00, mochel@osdl.org
  device model <-> driverfs bindings
  Rename device_dup_file to common_create_file
  Make it inc/dec reference count on object that's passed in
  Add common_remove_file that touches reference count of object and calls driverfs to remove file

diffstat results: 
 drivers/base/fs/fs.c |   35 +++++++++++++++++++++++++----------
 drivers/base/fs/fs.h |    3 ++-
 2 files changed, 27 insertions, 11 deletions

ChangeSet@1.604.3.26, 2002-07-05 13:57:30-07:00, mochel@osdl.org
  Add device driver <-> driverfs bindings

diffstat results: 
 drivers/base/base.h      |    3 ++
 drivers/base/driver.c    |   10 -------
 drivers/base/fs/driver.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions, 10 deletions

ChangeSet@1.604.3.27, 2002-07-05 13:58:13-07:00, mochel@osdl.org
  add driver.o target in drivers/base/fs/

diffstat results: 
 drivers/base/fs/Makefile |    4 ++--
 1 files changed, 2 insertions, 2 deletions

ChangeSet@1.604.3.28, 2002-07-05 13:59:26-07:00, mochel@osdl.org
  device model, bus drivers
  Convert bus_create_file to use common_create_file and bus_remove_file to use common_remove_file (and let them handle reference counting)
  Export bus_{create,remove}_file

diffstat results: 
 drivers/base/fs/bus.c |   19 +++++--------------
 1 files changed, 5 insertions, 14 deletions

ChangeSet@1.604.3.29, 2002-07-05 14:00:42-07:00, mochel@osdl.org
  Convert device_{create,remove}_file to use common_{create,remove}_file

diffstat results: 
 drivers/base/fs/device.c |   24 +++++++-----------------
 1 files changed, 7 insertions, 17 deletions

ChangeSet@1.604.3.30, 2002-07-05 14:01:40-07:00, mochel@osdl.org
  Add prototypes for {bus,driver}_{create,remove}_file to include/linux/device.h

diffstat results: 
 include/linux/device.h |    8 ++++++++
 1 files changed, 8 insertions

ChangeSet@1.604.3.31, 2002-07-05 15:54:13-07:00, mochel@osdl.org
  Rewrite driverfs documentation

diffstat results: 
 Documentation/filesystems/driverfs.txt |  366 ++++++++++++++++++++++-----------
 1 files changed, 251 insertions, 115 deletions



^ permalink raw reply	[flat|nested] 20+ messages in thread
* driverfs updates
@ 2002-07-18 18:11 Patrick Mochel
  2002-07-18 18:33 ` Greg KH
  0 siblings, 1 reply; 20+ messages in thread
From: Patrick Mochel @ 2002-07-18 18:11 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel


Here is a set of driverfs updates. These updates completely replace the 
patch that I posted last week, and actually have overlapping changesets. 

Short summary:

- break kernel interface to driverfs into fs/driverfs/lib.c
- change show/store callbacks to take void *, instead of struct device *
- Fix compilation warnings for all users
- Change driverfs_remove_file and device_remove_file to take 
  struct driver_file_entry *, instead of char * (so you can use the same
  paramter that you used to creat the file to remove it)
- Fix all users of those functions
- Make struct driver_dir_entry dynamically allocated
- Free it on dentry removal, instead of when object is removed
- Put pointer to object owning directory in directory entry, so we have 
  something handy to pass to show() and store()
- Change named initializers (keeping tabs in place) 

There is nothing in these changesets to deal with object locking or 
reference counting. Though they're related, they are separate issues, and 
will be dealt with separately. 

These changes basically make driverfs generic enough to handle any type of 
object or subsystem creating files and directories in it. 

The next set of patches (probably today) will add glue so that bus and
device drivers can create files of their own (instead of on behalf of a
device). Along with the udpated documentation, they will serve as an 
example of how any subsystem can exploit driverfs.

A patch is available at 

http://kernel.org/pub/linux/kernel/people/mochel/patches/driverfs-18072002.diff.gz

	-pat

Please pull from

	http://ldm.bkbits.net/linux-2.5-driverfs

This will update the following files:

 drivers/base/base.h         |    1 
 drivers/base/bus.c          |   78 +++++++--
 drivers/base/driver.c       |   18 +-
 drivers/base/fs.c           |   39 +++-
 drivers/base/interface.c    |    9 -
 drivers/cdrom/cdrom.c       |    5 
 drivers/pci/proc.c          |    6 
 drivers/scsi/scsi_scan.c    |    5 
 drivers/scsi/sg.c           |   11 -
 drivers/scsi/sr.c           |    7 
 fs/driverfs/Makefile        |    4 
 fs/driverfs/inode.c         |  361 +++++---------------------------------------
 fs/driverfs/lib.c           |  297 +++++++++++++++++++++++++++++++++++-
 fs/partitions/check.c       |   15 -
 include/linux/device.h      |   12 -
 include/linux/driverfs_fs.h |   13 +
 16 files changed, 497 insertions(+), 384 deletions(-)

through these ChangeSets:

<mochel@osdl.org> (02/07/18 1.739)
   driverfs:
   Change named initializers from 
   	name:	value
   to
   	.name	= value

<mochel@osdl.org> (02/07/17 1.639.3.20)
   device driverfs files:
   set object pointer in directory, not for individual files

<mochel@osdl.org> (02/07/17 1.639.3.19)
   driverfs:
   - move pointer to object that owns file to driver_dir_entry, since the same object will own all files in that directory

<mochel@osdl.org> (02/07/17 1.639.3.18)
   bus directories in driverfs:
   - don't free directories, since that's done now when the dentry is deleted

<mochel@osdl.org> (02/07/17 1.639.3.17)
   driverfs:
   add d_delete callback for directories that frees driver_dir_entry, now that all users dynamically allocate it

<mochel@osdl.org> (02/07/17 1.639.3.16)
   driver directories in driverfs:
   dynamically allocate directories

<mochel@osdl.org> (02/07/17 1.639.3.15)
   bus symlinks in driverfs:
   make sure we use right pointer to parent when creating symlink

<mochel@osdl.org> (02/07/17 1.639.3.14)
   bus driver directories:
   - make sure we get parent right when creating directories
   - make sure we memset them when we allocate them

<mochel@osdl.org> (02/07/17 1.639.3.13)
   bus drivers:
   - make bus's directories dynamically allocated. 
   - update creation and deletion functions to handle that

<mochel@osdl.org> (02/07/17 1.639.3.12)
   devices:
   - make struct device::dir dynamically allocated, instead of static
   - change functions that use it to treat it as such

<mochel@osdl.org> (02/07/17 1.639.3.11)
   fs/partitions/check.c:
   change calls to device_remove_file to take pointer to driver_file_entry, instead of just the name

<mochel@osdl.org> (02/07/17 1.639.3.10)
   drivers/scsi/sg.c:
   change call device_remove_file to take pointer to the driver_file_entry, insetad of the name

<mochel@osdl.org> (02/07/17 1.639.3.9)
   #ifdef out this code that removes driverfs files that it didn't create. 
   That sounds buggy...

<mochel@osdl.org> (02/07/17 1.639.3.8)
   device model:
   - change device_remove_file to take pointer to driver_file_entry instead of char * to match change in driverfs interface
   - implement device_remove_symlink, that manaualy searches dir's list of files to obtain a struct driver_file_entry to pass to driverfs_remove_file

<mochel@osdl.org> (02/07/17 1.639.3.7)
   driverfs - 
   Change driverfs_remove_file to take struct driver_file_entry * instead of char *
   Walk list of dir's files to find matching entry (so entry passed in can be re-used for multiple objects) on file removal
   But, now creation and removal take the same parameter

<mochel@osdl.org> (02/07/17 1.639.3.6)
   fs/partitions/check.c
   Change driverfs callbacks to take void * and cast to struct device *

<mochel@osdl.org> (02/07/17 1.639.3.5)
   drivers/scsi/*c:
   Change driverfs callbacks to take void * and cast to struct device *

<mochel@osdl.org> (02/07/17 1.639.3.4)
   drivers/pci/proc.c:
   Change driverfs callbacks to take void * and cast to struct device *

<mochel@osdl.org> (02/07/17 1.639.3.3)
   driverfs/base/interface.c:
   Change driverfs callbacks to take void * and cast to struct device

<mochel@osdl.org> (02/07/17 1.639.3.2)
   driverfs:
   - Add void * object pointer in driver_file_entry
   - Change show() and store() callbacks to take a void *, instead of struct device *
   - Use object pointer in read() and write() instead of doing list_entry on the driver_file_entry
   - Make sure that device_create_file sets object pointer when creating a file

<mochel@osdl.org> (02/07/15 1.639.3.1)
   driverfs:
   split apart kernel interface from the standard file operations



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2002-07-18 19:59 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-08 18:41 Driverfs updates Patrick Mochel
2002-07-08 23:33 ` Keith Owens
2002-07-08 23:52   ` Thunder from the hill
2002-07-09  0:09     ` Keith Owens
2002-07-09  8:30     ` Oliver Neukum
2002-07-09 11:08       ` Thunder from the hill
2002-07-09 11:45         ` Richard B. Johnson
2002-07-09 12:20           ` David D. Hagood
2002-07-09 12:33             ` Thunder from the hill
2002-07-09 14:43             ` jbradford
2002-07-10  7:15             ` jw schultz
2002-07-09 17:05         ` Oliver Neukum
2002-07-10  0:43         ` Pavel Machek
2002-07-09 16:56   ` Patrick Mochel
2002-07-09 23:29     ` Keith Owens
2002-07-10 20:02       ` Patrick Mochel
2002-07-11  0:40     ` John Alvord
2002-07-18 18:11 driverfs updates Patrick Mochel
2002-07-18 18:33 ` Greg KH
2002-07-18 19:57   ` Patrick Mochel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.