aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-01-24 14:35:52 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 13:37:14 -0500
commitb592fcfe7f06c15ec11774b5be7ce0de3aa86e73 (patch)
tree13f2cb344f8871edd30dc15007534405197d8480 /lib
parent2f65168de7d68a5795e945e781d85b313bdc97b9 (diff)
sysfs: Shadow directory support
The problem. When implementing a network namespace I need to be able to have multiple network devices with the same name. Currently this is a problem for /sys/class/net/*. What I want is a separate /sys/class/net directory in sysfs for each network namespace, and I want to name each of them /sys/class/net. I looked and the VFS actually allows that. All that is needed is for /sys/class/net to implement a follow link method to redirect lookups to the real directory you want. Implementing a follow link method that is sensitive to the current network namespace turns out to be 3 lines of code so it looks like a clean approach. Modifying sysfs so it doesn't get in my was is a bit trickier. I am calling the concept of multiple directories all at the same path in the filesystem shadow directories. With the directory entry really at that location the shadow master. The following patch modifies sysfs so it can handle a directory structure slightly different from the kobject tree so I can implement the shadow directories for handling /sys/class/net/. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Maneesh Soni <maneesh@in.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/kobject.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/lib/kobject.c b/lib/kobject.c
index 74b8dbca150e..c2917ffe8bf1 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj)
44 return error; 44 return error;
45} 45}
46 46
47static int create_dir(struct kobject * kobj) 47static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
48{ 48{
49 int error = 0; 49 int error = 0;
50 if (kobject_name(kobj)) { 50 if (kobject_name(kobj)) {
51 error = sysfs_create_dir(kobj); 51 error = sysfs_create_dir(kobj, shadow_parent);
52 if (!error) { 52 if (!error) {
53 if ((error = populate_dir(kobj))) 53 if ((error = populate_dir(kobj)))
54 sysfs_remove_dir(kobj); 54 sysfs_remove_dir(kobj);
@@ -158,9 +158,10 @@ static void unlink(struct kobject * kobj)
158/** 158/**
159 * kobject_add - add an object to the hierarchy. 159 * kobject_add - add an object to the hierarchy.
160 * @kobj: object. 160 * @kobj: object.
161 * @shadow_parent: sysfs directory to add to.
161 */ 162 */
162 163
163int kobject_add(struct kobject * kobj) 164int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
164{ 165{
165 int error = 0; 166 int error = 0;
166 struct kobject * parent; 167 struct kobject * parent;
@@ -191,7 +192,7 @@ int kobject_add(struct kobject * kobj)
191 } 192 }
192 kobj->parent = parent; 193 kobj->parent = parent;
193 194
194 error = create_dir(kobj); 195 error = create_dir(kobj, shadow_parent);
195 if (error) { 196 if (error) {
196 /* unlink does the kobject_put() for us */ 197 /* unlink does the kobject_put() for us */
197 unlink(kobj); 198 unlink(kobj);
@@ -212,6 +213,15 @@ int kobject_add(struct kobject * kobj)
212 return error; 213 return error;
213} 214}
214 215
216/**
217 * kobject_add - add an object to the hierarchy.
218 * @kobj: object.
219 */
220int kobject_add(struct kobject * kobj)
221{
222 return kobject_shadow_add(kobj, NULL);
223}
224
215 225
216/** 226/**
217 * kobject_register - initialize and add an object. 227 * kobject_register - initialize and add an object.
@@ -304,7 +314,29 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
304 kobj = kobject_get(kobj); 314 kobj = kobject_get(kobj);
305 if (!kobj) 315 if (!kobj)
306 return -EINVAL; 316 return -EINVAL;
307 error = sysfs_rename_dir(kobj, new_name); 317 if (!kobj->parent)
318 return -EINVAL;
319 error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
320 kobject_put(kobj);
321
322 return error;
323}
324
325/**
326 * kobject_rename - change the name of an object
327 * @kobj: object in question.
328 * @new_name: object's new name
329 */
330
331int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
332 const char *new_name)
333{
334 int error = 0;
335
336 kobj = kobject_get(kobj);
337 if (!kobj)
338 return -EINVAL;
339 error = sysfs_rename_dir(kobj, new_parent, new_name);
308 kobject_put(kobj); 340 kobject_put(kobj);
309 341
310 return error; 342 return error;