mount.c (2d8ad8719591fa803b0d589ed057fa46f49b7155) | mount.c (a685e08987d1edf1995b76511d4c98ea0e905377) |
---|---|
1/* 2 * fs/sysfs/symlink.c - operations for initializing and mounting sysfs 3 * 4 * Copyright (c) 2001-3 Patrick Mochel 5 * Copyright (c) 2007 SUSE Linux Products GmbH 6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de> 7 * 8 * This file is released under the GPLv2. --- 81 unchanged lines hidden (view full) --- 90{ 91 int error; 92 error = set_anon_super(sb, data); 93 if (!error) 94 sb->s_fs_info = data; 95 return error; 96} 97 | 1/* 2 * fs/sysfs/symlink.c - operations for initializing and mounting sysfs 3 * 4 * Copyright (c) 2001-3 Patrick Mochel 5 * Copyright (c) 2007 SUSE Linux Products GmbH 6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de> 7 * 8 * This file is released under the GPLv2. --- 81 unchanged lines hidden (view full) --- 90{ 91 int error; 92 error = set_anon_super(sb, data); 93 if (!error) 94 sb->s_fs_info = data; 95 return error; 96} 97 |
98static void free_sysfs_super_info(struct sysfs_super_info *info) 99{ 100 int type; 101 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) 102 kobj_ns_drop(type, info->ns[type]); 103 kfree(info); 104} 105 |
|
98static struct dentry *sysfs_mount(struct file_system_type *fs_type, 99 int flags, const char *dev_name, void *data) 100{ 101 struct sysfs_super_info *info; 102 enum kobj_ns_type type; 103 struct super_block *sb; 104 int error; 105 106 info = kzalloc(sizeof(*info), GFP_KERNEL); 107 if (!info) 108 return ERR_PTR(-ENOMEM); 109 110 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | 106static struct dentry *sysfs_mount(struct file_system_type *fs_type, 107 int flags, const char *dev_name, void *data) 108{ 109 struct sysfs_super_info *info; 110 enum kobj_ns_type type; 111 struct super_block *sb; 112 int error; 113 114 info = kzalloc(sizeof(*info), GFP_KERNEL); 115 if (!info) 116 return ERR_PTR(-ENOMEM); 117 118 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) |
111 info->ns[type] = kobj_ns_current(type); | 119 info->ns[type] = kobj_ns_grab_current(type); |
112 113 sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); 114 if (IS_ERR(sb) || sb->s_fs_info != info) | 120 121 sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); 122 if (IS_ERR(sb) || sb->s_fs_info != info) |
115 kfree(info); | 123 free_sysfs_super_info(info); |
116 if (IS_ERR(sb)) 117 return ERR_CAST(sb); 118 if (!sb->s_root) { 119 sb->s_flags = flags; 120 error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); 121 if (error) { 122 deactivate_locked_super(sb); 123 return ERR_PTR(error); 124 } 125 sb->s_flags |= MS_ACTIVE; 126 } 127 128 return dget(sb->s_root); 129} 130 131static void sysfs_kill_sb(struct super_block *sb) 132{ 133 struct sysfs_super_info *info = sysfs_info(sb); | 124 if (IS_ERR(sb)) 125 return ERR_CAST(sb); 126 if (!sb->s_root) { 127 sb->s_flags = flags; 128 error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); 129 if (error) { 130 deactivate_locked_super(sb); 131 return ERR_PTR(error); 132 } 133 sb->s_flags |= MS_ACTIVE; 134 } 135 136 return dget(sb->s_root); 137} 138 139static void sysfs_kill_sb(struct super_block *sb) 140{ 141 struct sysfs_super_info *info = sysfs_info(sb); |
134 | |
135 /* Remove the superblock from fs_supers/s_instances 136 * so we can't find it, before freeing sysfs_super_info. 137 */ 138 kill_anon_super(sb); | 142 /* Remove the superblock from fs_supers/s_instances 143 * so we can't find it, before freeing sysfs_super_info. 144 */ 145 kill_anon_super(sb); |
139 kfree(info); | 146 free_sysfs_super_info(info); |
140} 141 142static struct file_system_type sysfs_fs_type = { 143 .name = "sysfs", 144 .mount = sysfs_mount, 145 .kill_sb = sysfs_kill_sb, 146}; 147 | 147} 148 149static struct file_system_type sysfs_fs_type = { 150 .name = "sysfs", 151 .mount = sysfs_mount, 152 .kill_sb = sysfs_kill_sb, 153}; 154 |
148void sysfs_exit_ns(enum kobj_ns_type type, const void *ns) 149{ 150 struct super_block *sb; 151 152 mutex_lock(&sysfs_mutex); 153 spin_lock(&sb_lock); 154 list_for_each_entry(sb, &sysfs_fs_type.fs_supers, s_instances) { 155 struct sysfs_super_info *info = sysfs_info(sb); 156 /* 157 * If we see a superblock on the fs_supers/s_instances 158 * list the unmount has not completed and sb->s_fs_info 159 * points to a valid struct sysfs_super_info. 160 */ 161 /* Ignore superblocks with the wrong ns */ 162 if (info->ns[type] != ns) 163 continue; 164 info->ns[type] = NULL; 165 } 166 spin_unlock(&sb_lock); 167 mutex_unlock(&sysfs_mutex); 168} 169 | |
170int __init sysfs_init(void) 171{ 172 int err = -ENOMEM; 173 174 sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", 175 sizeof(struct sysfs_dirent), 176 0, 0, NULL); 177 if (!sysfs_dir_cachep) --- 39 unchanged lines hidden --- | 155int __init sysfs_init(void) 156{ 157 int err = -ENOMEM; 158 159 sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", 160 sizeof(struct sysfs_dirent), 161 0, 0, NULL); 162 if (!sysfs_dir_cachep) --- 39 unchanged lines hidden --- |