From: Patrick Mochel <mochel@osdl.org>

Add ->k_name pointer which points to the name for a kobject. By default, this
points to ->name (the static name array). 
 
Users of kobjects may use the helper function kobject_set_name() (and are 
encouraged to do so in all cases). This function will determined whether or
not the name is short enough to fit in ->name. If so, great. 

Otherwise, a dyanamic string is allocated and the name is stored there. 
->k_name will point to that, and will be freed when the kobject is released. 

kobject_set_name() may take a format string, like:

	kobject_set_name(kobj,"%s%d",base_name,id); 

and will behave as expected (will put in ->name, unless it's too long, in 
which case a new string will be allocated and it will be stored in there). 



 fs/sysfs/dir.c          |    8 +----
 include/linux/kobject.h |    9 +++++
 lib/kobject.c           |   75 +++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 77 insertions(+), 15 deletions(-)

diff -puN fs/sysfs/dir.c~kobject-unlimited-name-lengths fs/sysfs/dir.c
--- 25/fs/sysfs/dir.c~kobject-unlimited-name-lengths	2003-08-30 15:39:48.000000000 -0700
+++ 25-akpm/fs/sysfs/dir.c	2003-08-30 15:39:48.000000000 -0700
@@ -70,7 +70,7 @@ int sysfs_create_dir(struct kobject * ko
 	else
 		return -EFAULT;
 
-	dentry = create_dir(kobj,parent,kobj->name);
+	dentry = create_dir(kobj,parent,kobject_name(kobj));
 	if (!IS_ERR(dentry))
 		kobj->dentry = dentry;
 	else
@@ -157,7 +157,7 @@ void sysfs_rename_dir(struct kobject * k
 {
 	struct dentry * new_dentry, * parent;
 
-	if (!strcmp(kobj->name, new_name))
+	if (!strcmp(kobject_name(kobj), new_name))
 		return;
 
 	if (!kobj->parent)
@@ -169,9 +169,7 @@ void sysfs_rename_dir(struct kobject * k
 
 	new_dentry = sysfs_get_dentry(parent, new_name);
 	d_move(kobj->dentry, new_dentry);
-
-	strlcpy(kobj->name, new_name, KOBJ_NAME_LEN);
-
+	kobject_set_name(kobj,new_name);
 	up(&parent->d_inode->i_sem);	
 }
 
diff -puN include/linux/kobject.h~kobject-unlimited-name-lengths include/linux/kobject.h
--- 25/include/linux/kobject.h~kobject-unlimited-name-lengths	2003-08-30 15:39:48.000000000 -0700
+++ 25-akpm/include/linux/kobject.h	2003-08-30 15:39:48.000000000 -0700
@@ -24,6 +24,7 @@
 #define KOBJ_NAME_LEN	20
 
 struct kobject {
+	char			* k_name;
 	char			name[KOBJ_NAME_LEN];
 	atomic_t		refcount;
 	struct list_head	entry;
@@ -33,6 +34,14 @@ struct kobject {
 	struct dentry		* dentry;
 };
 
+extern int kobject_set_name(struct kobject *, const char *, ...)
+	__attribute__((format(printf,2,3)));
+
+static inline char * kobject_name(struct kobject * kobj)
+{
+	return kobj->k_name;
+}
+
 extern void kobject_init(struct kobject *);
 extern void kobject_cleanup(struct kobject *);
 
diff -puN lib/kobject.c~kobject-unlimited-name-lengths lib/kobject.c
--- 25/lib/kobject.c~kobject-unlimited-name-lengths	2003-08-30 15:39:48.000000000 -0700
+++ 25-akpm/lib/kobject.c	2003-08-30 15:39:48.000000000 -0700
@@ -48,7 +48,7 @@ static int populate_dir(struct kobject *
 static int create_dir(struct kobject * kobj)
 {
 	int error = 0;
-	if (strlen(kobj->name)) {
+	if (kobject_name(kobj)) {
 		error = sysfs_create_dir(kobj);
 		if (!error) {
 			if ((error = populate_dir(kobj)))
@@ -76,7 +76,7 @@ static int get_kobj_path_length(struct k
 	 * Add 1 to strlen for leading '/' of each level.
 	 */
 	do {
-		length += strlen (parent->name) + 1;
+		length += strlen(kobject_name(parent)) + 1;
 		parent = parent->parent;
 	} while (parent);
 	return length;
@@ -88,10 +88,10 @@ static void fill_kobj_path(struct kset *
 
 	--length;
 	for (parent = kobj; parent; parent = parent->parent) {
-		int cur = strlen (parent->name);
+		int cur = strlen(kobject_name(parent));
 		/* back up enough to print this name with '/' */
 		length -= cur;
-		strncpy (path + length, parent->name, cur);
+		strncpy (path + length, kobject_name(parent), cur);
 		*(path + --length) = '/';
 	}
 
@@ -254,11 +254,12 @@ int kobject_add(struct kobject * kobj)
 
 	if (!(kobj = kobject_get(kobj)))
 		return -ENOENT;
-
+	if (!kobj->k_name)
+		kobj->k_name = kobj->name;
 	parent = kobject_get(kobj->parent);
 
 	pr_debug("kobject %s: registering. parent: %s, set: %s\n",
-		 kobj->name, parent ? parent->name : "<NULL>", 
+		 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
 		 kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
 
 	if (kobj->kset) {
@@ -305,7 +306,7 @@ int kobject_register(struct kobject * ko
 		error = kobject_add(kobj);
 		if (error) {
 			printk("kobject_register failed for %s (%d)\n",
-			       kobj->name,error);
+			       kobject_name(kobj),error);
 			dump_stack();
 		}
 	} else
@@ -313,6 +314,57 @@ int kobject_register(struct kobject * ko
 	return error;
 }
 
+
+/**
+ *	kobject_set_name - Set the name of an object
+ *	@kobj:	object.
+ *	@name:	name.
+ *
+ *	If strlen(name) < KOBJ_NAME_LEN, then use a dynamically allocated
+ *	string that @kobj->k_name points to. Otherwise, use the static
+ *	@kobj->name array.
+ */
+
+int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
+{
+	int error = 0;
+	int limit = KOBJ_NAME_LEN;
+	int need;
+	va_list args;
+
+	va_start(args,fmt);
+	/*
+	 * First, try the static array
+	 */
+	need = vsnprintf(kobj->name,limit,fmt,args);
+	if (need < limit)
+		kobj->k_name = kobj->name;
+	else {
+		/*
+		 * Need more space? Allocate it and try again
+		 */
+		kobj->k_name = kmalloc(need,GFP_KERNEL);
+		if (!kobj->k_name) {
+			error = -ENOMEM;
+			goto Done;
+		}
+		limit = need;
+		need = vsnprintf(kobj->k_name,limit,fmt,args);
+
+		/* Still? Give up. */
+		if (need > limit) {
+			kfree(kobj->k_name);
+			error = -EFAULT;
+		}
+	}
+ Done:
+	va_end(args);
+	return error;
+}
+
+EXPORT_SYMBOL(kobject_set_name);
+
+
 /**
  *	kobject_rename - change the name of an object
  *	@kobj:	object in question.
@@ -360,7 +412,7 @@ void kobject_del(struct kobject * kobj)
 
 void kobject_unregister(struct kobject * kobj)
 {
-	pr_debug("kobject %s: unregistering\n",kobj->name);
+	pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
 	kobject_del(kobj);
 	kobject_put(kobj);
 }
@@ -392,11 +444,14 @@ void kobject_cleanup(struct kobject * ko
 	struct kobj_type * t = get_ktype(kobj);
 	struct kset * s = kobj->kset;
 
-	pr_debug("kobject %s: cleaning up\n",kobj->name);
+	pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
 	if (t && t->release)
 		t->release(kobj);
 	if (s)
 		kset_put(s);
+	if (kobj->k_name != kobj->name)
+		kfree(kobj->k_name);
+	kobj->k_name = NULL;
 }
 
 /**
@@ -488,7 +543,7 @@ struct kobject * kset_find_obj(struct ks
 	down_read(&kset->subsys->rwsem);
 	list_for_each(entry,&kset->list) {
 		struct kobject * k = to_kobj(entry);
-		if (!strcmp(k->name,name)) {
+		if (!strcmp(kobject_name(k),name)) {
 			ret = k;
 			break;
 		}

_