[dm-devel] [PATCH][RESEND+fixes] dm + sysfs

Mike Christie mikenc at us.ibm.com
Tue Dec 9 11:03:01 UTC 2003


On Mon, 8 Dec 2003, Joe Thornber wrote:

Hi again Joe,
 
> ok, I accept your argument that sysfs is a lot smaller interface than
> dmfs/ioctl.  However I'm not polluting nice clear abstractions like
> dm_table with sysfs.  So I think we have to go the callback way.  It's
> probably more work for you, but I need to draw these lines in order to
> keep control of the complexity, your patch makes it more complicated
> for people to understand and modify the code.

I think I may have mislead you as to what kobjects are (my bad patch 
didn't help either). From the kernel doc, "The kobject infrastructure
performs basic object management that larger data structures and
subsystems can leverage, rather then reimplement similar functionality."

If you look at the attached patch (dm-kobj.patch) built and tested against 
test10-dm1 you will see kobjects used as a replacement for the "atomic_t 
holders" value in dm_table and mapped_device. There is no sysfs :) and I
did not modify any of the get/put semantics. The only change is the kobject
infrastructure manages the ref count and calls the release function when
the count goes to zero.

With this patch, I can use the callback method, the sysfs junk will not be 
coupled to the core code, no abstractions are broken and we will all use 
the same ref count. Better?

> Sorry this isn't the answer you were hoping for :(

A reply and rejection is better than just being ignored. It's ok. It keeps 
me busy and learning about the kernel :)

Thanks,

mike

Mike Christie
mikenc at us.ibm.com
-------------- next part --------------
diff -aurp linux-2.6.0-test10/drivers/md/dm.c linux-2.6.0-test10-dmkobj/drivers/md/dm.c
--- linux-2.6.0-test10/drivers/md/dm.c	2003-12-08 22:25:01.620094201 -0800
+++ linux-2.6.0-test10-dmkobj/drivers/md/dm.c	2003-12-08 22:03:17.000000000 -0800
@@ -13,6 +13,7 @@
 #include <linux/bio.h>
 #include <linux/mempool.h>
 #include <linux/slab.h>
+#include <linux/kobject.h>
 
 static const char *_name = DM_NAME;
 #define MAX_DEVICES 1024
@@ -40,7 +41,7 @@ struct deferred_io {
 
 struct mapped_device {
 	struct rw_semaphore lock;
-	atomic_t holders;
+	struct kobject kobj;
 
 	unsigned long flags;
 
@@ -71,6 +72,12 @@ struct mapped_device {
 	wait_queue_head_t eventq;
 };
 
+static void release_md(struct kobject *kobj);
+
+struct kobj_type md_ktype = {
+	.release = release_md,
+};
+
 #define MIN_IOS 256
 static kmem_cache_t *_io_cache;
 
@@ -599,7 +606,8 @@ static struct mapped_device *alloc_dev(u
 
 	memset(md, 0, sizeof(*md));
 	init_rwsem(&md->lock);
-	atomic_set(&md->holders, 1);
+	kobject_init(&md->kobj);
+	md->kobj.ktype = &md_ktype;
 
 	md->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!md->queue) {
@@ -736,17 +744,22 @@ int dm_create_with_minor(unsigned int mi
 
 void dm_get(struct mapped_device *md)
 {
-	atomic_inc(&md->holders);
+	kobject_get(&md->kobj);
 }
 
 void dm_put(struct mapped_device *md)
 {
-	if (atomic_dec_and_test(&md->holders)) {
-		if (!test_bit(DMF_SUSPENDED, &md->flags) && md->map)
-			dm_table_suspend_targets(md->map);
-		__unbind(md);
-		free_dev(md);
-	}
+	kobject_put(&md->kobj);
+}
+
+static void release_md(struct kobject *kobj)
+{
+	struct mapped_device *md = dm_kobj_to_md(kobj);
+
+	if (!test_bit(DMF_SUSPENDED, &md->flags) && md->map)
+		dm_table_suspend_targets(md->map);
+	__unbind(md);
+	free_dev(md);
 }
 
 /*
@@ -922,6 +935,11 @@ struct dm_table *dm_get_table(struct map
 	return t;
 }
 
+struct mapped_device *dm_kobj_to_md(struct kobject *kobj)
+{
+	return container_of(kobj, struct mapped_device, kobj);
+}
+
 int dm_suspended(struct mapped_device *md)
 {
 	return test_bit(DMF_SUSPENDED, &md->flags);
diff -aurp linux-2.6.0-test10/drivers/md/dm.h linux-2.6.0-test10-dmkobj/drivers/md/dm.h
--- linux-2.6.0-test10/drivers/md/dm.h	2003-12-08 22:25:01.656083845 -0800
+++ linux-2.6.0-test10-dmkobj/drivers/md/dm.h	2003-12-08 22:02:41.000000000 -0800
@@ -90,6 +90,7 @@ void dm_remove_wait_queue(struct mapped_
  */
 struct gendisk *dm_disk(struct mapped_device *md);
 int dm_suspended(struct mapped_device *md);
+struct mapped_device *dm_kobj_to_md(struct kobject *kobj);
 
 /*-----------------------------------------------------------------
  * Functions for manipulating a table.  Tables are also reference
@@ -115,6 +116,7 @@ struct list_head *dm_table_get_devices(s
 int dm_table_get_mode(struct dm_table *t);
 void dm_table_suspend_targets(struct dm_table *t);
 void dm_table_resume_targets(struct dm_table *t);
+struct dm_table *dm_kobj_to_table(struct kobject *kobj);
 
 /*-----------------------------------------------------------------
  * A registry of target types.
diff -aurp linux-2.6.0-test10/drivers/md/dm-table.c linux-2.6.0-test10-dmkobj/drivers/md/dm-table.c
--- linux-2.6.0-test10/drivers/md/dm-table.c	2003-12-08 22:25:01.660082695 -0800
+++ linux-2.6.0-test10-dmkobj/drivers/md/dm-table.c	2003-12-08 22:04:06.000000000 -0800
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <asm/atomic.h>
+#include <linux/kobject.h>
 
 #define MAX_DEPTH 16
 #define NODE_SIZE L1_CACHE_BYTES
@@ -21,7 +22,7 @@
 #define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)
 
 struct dm_table {
-	atomic_t holders;
+	struct kobject kobj;
 
 	/* btree table */
 	unsigned int depth;
@@ -54,6 +55,12 @@ struct dm_table {
 	void *event_context;
 };
 
+static void release_table(struct kobject *kobj);
+
+static struct kobj_type table_ktype = {
+	.release = release_table,
+};
+
 /*
  * Similar to ceiling(log_size(n))
  */
@@ -212,7 +219,8 @@ int dm_table_create(struct dm_table **re
 
 	memset(t, 0, sizeof(*t));
 	INIT_LIST_HEAD(&t->devices);
-	atomic_set(&t->holders, 1);
+	kobject_init(&t->kobj);
+	t->kobj.ktype = &table_ktype;
 
 	if (!num_targets)
 		num_targets = KEYS_PER_NODE;
@@ -272,15 +280,19 @@ void table_destroy(struct dm_table *t)
 	kfree(t);
 }
 
+static void release_table(struct kobject *kobj)
+{
+	table_destroy(dm_kobj_to_table(kobj));
+}
+
 void dm_table_get(struct dm_table *t)
 {
-	atomic_inc(&t->holders);
+	kobject_get(&t->kobj);
 }
 
 void dm_table_put(struct dm_table *t)
 {
-	if (atomic_dec_and_test(&t->holders))
-		table_destroy(t);
+	kobject_put(&t->kobj);
 }
 
 /*
@@ -833,6 +845,11 @@ int dm_table_get_mode(struct dm_table *t
 	return t->mode;
 }
 
+struct dm_table *dm_kobj_to_table(struct kobject *kobj)
+{
+	return container_of(kobj, struct dm_table, kobj);
+}
+
 void dm_table_suspend_targets(struct dm_table *t)
 {
 	int i;


More information about the dm-devel mailing list