#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/kmod.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
return p;
}
+
+/* define fs_subsys */
+static decl_subsys(fs, NULL);
+
+static int register_fs_subsys(struct file_system_type * fs)
+{
+ struct subsystem *sub = &fs->subsys;
+
+ snprintf(sub->kset.kobj.name, KOBJ_NAME_LEN, "%s", fs->name);
+ subsys_set_kset(fs, fs_subsys);
+ return subsystem_register(sub);
+}
+
+static int unlink_fs(struct file_system_type * fs)
+{
+ struct file_system_type ** tmp;
+
+ write_lock(&file_systems_lock);
+ tmp = &file_systems;
+ while (*tmp) {
+ if (fs == *tmp) {
+ *tmp = fs->next;
+ fs->next = NULL;
+ write_unlock(&file_systems_lock);
+ return 0;
+ }
+ tmp = &(*tmp)->next;
+ }
+ write_unlock(&file_systems_lock);
+ return -EINVAL;
+}
+
/**
* register_filesystem - register a new filesystem
* @fs: the file system structure
else
*p = fs;
write_unlock(&file_systems_lock);
+
+ if (!res) {
+ /* we implicitly possess reference to @fs during registration,
+ * so it cannot be unregister from under us. */
+ if (register_fs_subsys(fs))
+ printk(KERN_WARNING "Failed to register '%s' in sysfs\n",
+ fs->name);
+ }
return res;
}
int unregister_filesystem(struct file_system_type * fs)
{
- struct file_system_type ** tmp;
+ int res;
- write_lock(&file_systems_lock);
- tmp = &file_systems;
- while (*tmp) {
- if (fs == *tmp) {
- *tmp = fs->next;
- fs->next = NULL;
- write_unlock(&file_systems_lock);
- return 0;
- }
- tmp = &(*tmp)->next;
- }
- write_unlock(&file_systems_lock);
- return -EINVAL;
+ res = unlink_fs(fs);
+ if (!res)
+ subsystem_unregister(&fs->subsys);
+ return res;
+}
+
+extern int sysfs_init(void);
+
+/**
+ * fs_subsys_init - initialize sysfs and fs subsystem.
+ *
+ * In order to register filesystems in sysfs, it has to be
+ * initialized. Also, we need the base fs filesystem, so the
+ * registered filesystems have a home.
+ *
+ * During sysfs_init(), the registration of sysfs into itself
+ * will fail, since it's not mounted yet. To make sure that
+ * sysfs does show up, we re-register sysfs's embedded subsystem,
+ * which will get added, since sysfs is now mounted.
+ */
+
+void __init fs_subsys_init(void)
+{
+ struct file_system_type ** p;
+
+ /* make sure sysfs is up and running */
+ sysfs_init();
+
+ /* register fs_subsys */
+ subsystem_register(&fs_subsys);
+
+ p = find_filesystem("sysfs");
+
+ if (p)
+ /* make sure it's registered */
+ register_fs_subsys(*p);
}
static int fs_index(const char * __name)
extern struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
extern int do_remount_sb(struct super_block *sb, int flags, void * data);
extern int __init init_rootfs(void);
-extern int __init sysfs_init(void);
+extern int __init fs_subsys_init(void);
static struct list_head *mount_hashtable;
static int hash_mask, hash_bits;
d++;
i--;
} while (i);
- sysfs_init();
+ fs_subsys_init();
init_rootfs();
init_mount_tree();
}
#include <linux/stat.h>
#include <linux/cache.h>
#include <linux/radix-tree.h>
+#include <linux/kobject.h>
#include <asm/atomic.h>
struct iovec;
char s_id[32]; /* Informational name */
+ struct kobject kobj; /* anchor for sysfs */
void *s_fs_info; /* Filesystem private info */
/*
struct file_system_type {
const char *name;
+ struct subsystem subsys;
int fs_flags;
struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *);
void (*kill_sb) (struct super_block *);