summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-01-24 22:35:52 +0300
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 21:37:14 +0300
commitb592fcfe7f06c15ec11774b5be7ce0de3aa86e73 (patch)
tree13f2cb344f8871edd30dc15007534405197d8480 /include/linux
parent2f65168de7d68a5795e945e781d85b313bdc97b9 (diff)
downloadlinux-b592fcfe7f06c15ec11774b5be7ce0de3aa86e73.tar.xz
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 'include/linux')
-rw-r--r--include/linux/kobject.h4
-rw-r--r--include/linux/sysfs.h23
2 files changed, 23 insertions, 4 deletions
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 76538fcf2c4e..b850e0310538 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -74,9 +74,13 @@ extern void kobject_init(struct kobject *);
extern void kobject_cleanup(struct kobject *);
extern int __must_check kobject_add(struct kobject *);
+extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *);
extern void kobject_del(struct kobject *);
extern int __must_check kobject_rename(struct kobject *, const char *new_name);
+extern int __must_check kobject_shadow_rename(struct kobject *kobj,
+ struct dentry *new_parent,
+ const char *new_name);
extern int __must_check kobject_move(struct kobject *, struct kobject *);
extern int __must_check kobject_register(struct kobject *);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index eee485957c0c..192de3afa96b 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -16,6 +16,7 @@
struct kobject;
struct module;
+struct nameidata;
struct attribute {
const char * name;
@@ -89,13 +90,13 @@ struct sysfs_dirent {
#ifdef CONFIG_SYSFS
extern int __must_check
-sysfs_create_dir(struct kobject *);
+sysfs_create_dir(struct kobject *, struct dentry *);
extern void
sysfs_remove_dir(struct kobject *);
extern int __must_check
-sysfs_rename_dir(struct kobject *, const char *new_name);
+sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name);
extern int __must_check
sysfs_move_dir(struct kobject *, struct kobject *);
@@ -127,11 +128,17 @@ int __must_check sysfs_create_group(struct kobject *,
void sysfs_remove_group(struct kobject *, const struct attribute_group *);
void sysfs_notify(struct kobject * k, char *dir, char *attr);
+
+extern int sysfs_make_shadowed_dir(struct kobject *kobj,
+ void * (*follow_link)(struct dentry *, struct nameidata *));
+extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj);
+extern void sysfs_remove_shadow_dir(struct dentry *dir);
+
extern int __must_check sysfs_init(void);
#else /* CONFIG_SYSFS */
-static inline int sysfs_create_dir(struct kobject * k)
+static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
{
return 0;
}
@@ -141,7 +148,9 @@ static inline void sysfs_remove_dir(struct kobject * k)
;
}
-static inline int sysfs_rename_dir(struct kobject * k, const char *new_name)
+static inline int sysfs_rename_dir(struct kobject * k,
+ struct dentry *new_parent,
+ const char *new_name)
{
return 0;
}
@@ -205,6 +214,12 @@ static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
{
}
+static inline int sysfs_make_shadowed_dir(struct kobject *kobj,
+ void * (*follow_link)(struct dentry *, struct nameidata *))
+{
+ return 0;
+}
+
static inline int __must_check sysfs_init(void)
{
return 0;