tree ad08bea9651332c41192cd7e019692a1e1e103bf
parent 53c165e0a6c8a4ff7df316557528fa7a52d20711
author James Bottomley <[EMAIL PROTECTED]> Sun, 28 Aug 2005 19:13:17 -0500
committer James Bottomley <[EMAIL PROTECTED](none)> Wed, 31 Aug 2005 08:44:32 
-0500

[SCSI] attribute container final klist fixes

Since the attribute container deletes from a klist while it's walking
it, it is vulnerable to the problem (and fix) here:

http://marc.theaimsgroup.com/?l=linux-scsi&m=112485448830217

The attached fixes this (but won't compile without the above).

It also fixes the logical reversal in the traversal loop which meant
that we were never actually traversing the loop to hit this bug in the
first place.

Signed-off-by: James Bottomley <[EMAIL PROTECTED]>

 drivers/base/attribute_container.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/base/attribute_container.c 
b/drivers/base/attribute_container.c
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -27,6 +27,21 @@ struct internal_container {
        struct class_device classdev;
 };
 
+static void internal_container_klist_get(struct klist_node *n)
+{
+       struct internal_container *ic =
+               container_of(n, struct internal_container, node);
+       class_device_get(&ic->classdev);
+}
+
+static void internal_container_klist_put(struct klist_node *n)
+{
+       struct internal_container *ic =
+               container_of(n, struct internal_container, node);
+       class_device_put(&ic->classdev);
+}
+
+
 /**
  * attribute_container_classdev_to_container - given a classdev, return the 
container
  *
@@ -57,7 +72,8 @@ int
 attribute_container_register(struct attribute_container *cont)
 {
        INIT_LIST_HEAD(&cont->node);
-       klist_init(&cont->containers);
+       klist_init(&cont->containers,internal_container_klist_get,
+                  internal_container_klist_put);
                
        down(&attribute_container_mutex);
        list_add_tail(&cont->node, &attribute_container_list);
@@ -163,8 +179,8 @@ attribute_container_add_device(struct de
 #define klist_for_each_entry(pos, head, member, iter) \
        for (klist_iter_init(head, iter); (pos = ({ \
                struct klist_node *n = klist_next(iter); \
-               n ? ({ klist_iter_exit(iter) ; NULL; }) : \
-                       container_of(n, typeof(*pos), member);\
+               n ? container_of(n, typeof(*pos), member) : \
+                       ({ klist_iter_exit(iter) ; NULL; }); \
        }) ) != NULL; )
                        
 
@@ -206,7 +222,7 @@ attribute_container_remove_device(struct
                klist_for_each_entry(ic, &cont->containers, node, &iter) {
                        if (dev != ic->classdev.dev)
                                continue;
-                       klist_remove(&ic->node);
+                       klist_del(&ic->node);
                        if (fn)
                                fn(cont, dev, &ic->classdev);
                        else {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to