Re: [PATCH] correct attribute_container list usage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2005-08-22 at 17:47 -0500, James Bottomley wrote:
> One apparent, but rather nasty, solution would be to embed object get
> and put into the klist head as functions that take the node, so
> klist_next would take the object reference as well as the list kref,
> then drop it on klist_release.

Well, I'm not enormously fond of this, but it's not as downright nasty
as I thought.  Patrick, could you try this (assuming you have a fast
machine ... I'll be done with the complete kernel rebuild that touching
klist.h requires eventually) you'll have to encode klist to device get
and put functions and feed them to klist_init_embedded().

James

diff --git a/include/linux/klist.h b/include/linux/klist.h
--- a/include/linux/klist.h
+++ b/include/linux/klist.h
@@ -14,14 +14,24 @@
 #include <linux/kref.h>
 #include <linux/list.h>
 
-
+struct klist_node;
 struct klist {
 	spinlock_t		k_lock;
 	struct list_head	k_list;
+	void			(*get)(struct klist_node *);
+	void			(*put)(struct klist_node *);
 };
 
 
-extern void klist_init(struct klist * k);
+extern void klist_init_embedded(struct klist * k,
+				void (*get)(struct klist_node *),
+				void (*put)(struct klist_node *));
+
+static inline void klist_init(struct klist * k)
+{
+	klist_init_embedded(k, NULL, NULL);
+}
+
 
 
 struct klist_node {
diff --git a/lib/klist.c b/lib/klist.c
--- a/lib/klist.c
+++ b/lib/klist.c
@@ -42,15 +42,26 @@
 /**
  *	klist_init - Initialize a klist structure. 
  *	@k:	The klist we're initializing.
+ *	@get:	The get function for the embedding object (NULL if none)
+ *	@put:	The put function for the embedding object (NULL if none)
+ *
+ * Initialises the klist structure.  If the klist_node structures are
+ * going to be embedded in refcounted objects (necessary for safe
+ * deletion) then the get/put arguments are used to initialise
+ * functions that take and release references on the embedding
+ * objects.
  */
 
-void klist_init(struct klist * k)
+void klist_init_embedded(struct klist * k, void (*get)(struct klist_node *),
+			 void (*put)(struct klist_node *))
 {
 	INIT_LIST_HEAD(&k->k_list);
 	spin_lock_init(&k->k_lock);
+	k->get = get;
+	k->put = put;
 }
 
-EXPORT_SYMBOL_GPL(klist_init);
+EXPORT_SYMBOL_GPL(klist_init_embedded);
 
 
 static void add_head(struct klist * k, struct klist_node * n)
@@ -74,6 +85,8 @@ static void klist_node_init(struct klist
 	init_completion(&n->n_removed);
 	kref_init(&n->n_ref);
 	n->n_klist = k;
+	if (k->get)
+		k->get(n);
 }
 
 
@@ -110,9 +123,12 @@ EXPORT_SYMBOL_GPL(klist_add_tail);
 static void klist_release(struct kref * kref)
 {
 	struct klist_node * n = container_of(kref, struct klist_node, n_ref);
+	void (*put)(struct klist_node *) = n->n_klist->put;
 	list_del(&n->n_node);
 	complete(&n->n_removed);
 	n->n_klist = NULL;
+	if (put)
+		put(n);
 }
 
 static int klist_dec_and_del(struct klist_node * n)


-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux