Thread (4 messages) 4 messages, 3 authors, 2011-05-27

Struct Inheritance in drivers/ata/

From: Peter Hamilton <hidden>
Date: 2011-05-27 02:20:30

I see that it works, but I'm not exactly following how.  Maybe I just don't
have enough C experience.  But I can't seem to duplicate that functionality.


I understand the way I've normally seen inheritance, where:

struct Child {
  struct Parent p;
  int somethingOnlyForChildren;
}

Or something similar.  Then the Child struct can be casted as a Parent, and
since there is no padding before the first piece of data in a struct, every
parent attribute is accessed as though the struct were a Parent.

I see how it all lines up in memory, but in the case of the kernel code I
can't quite follow it.  Wouldn't everything assigned to 'inherits' be so
much farther down in memory?  I feel like I'm missing something.  Is there a
special way they all need to be accessed?

- Peter

On Thu, May 26, 2011 at 7:23 PM, Greg KH [off-list ref] wrote:
On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote:
quoted
The code in drivers/ata/ uses an implementation of inheritance that I
have not
quoted
seen before.  It's only briefly explained in the header file (
include/linux/
quoted
libata.h:885):

/*
 * ->inherits must be the last field and all the preceding
 * fields must be pointers.
 */

The structs are then initialized with .inherits assigned first:

drivers/ata/sata_nv.c:475

static struct ata_port_operations nv_nf2_ops = {
quoted
        .inherits               = &nv_generic_ops,
        .freeze                 = nv_nf2_freeze,
quoted
        .thaw                   = nv_nf2_thaw,
quoted
};


Is this actually implementing inheritance?  Why do all preceding fields
need to
quoted
be pointers?

As far as I can tell, this style is only found in the ata drivers.
I think you are right, but more subsystems need to emulate it, it is
very powerful and works very well.  I have been wanting to convert the
usb-serial layer to use the same thing one of these days.
quoted
Could anyone explain how this works?
The code is all there that shows it, but basically the driver is telling
the core to "use this type of functions, but if I set any others, use
them instead."  It's a nicer way of doing inheritance in C than we do in
other places in the kernel where we are a bit more "verbose" in making
it happen.

hope this helps,

greg k-h
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110526/a66e84ee/attachment-0001.html 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help