Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
sysfs
mount.c
Go to the documentation of this file.
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 <
[email protected]
>
7
*
8
* This file is released under the GPLv2.
9
*
10
* Please see Documentation/filesystems/sysfs.txt for more information.
11
*/
12
13
#define DEBUG
14
15
#include <linux/fs.h>
16
#include <
linux/mount.h
>
17
#include <
linux/pagemap.h
>
18
#include <
linux/init.h
>
19
#include <linux/module.h>
20
#include <linux/magic.h>
21
#include <linux/slab.h>
22
23
#include "
sysfs.h
"
24
25
26
static
struct
vfsmount
*sysfs_mnt;
27
struct
kmem_cache
*
sysfs_dir_cachep
;
28
29
static
const
struct
super_operations
sysfs_ops
= {
30
.statfs =
simple_statfs
,
31
.drop_inode =
generic_delete_inode
,
32
.evict_inode =
sysfs_evict_inode
,
33
};
34
35
struct
sysfs_dirent
sysfs_root
= {
36
.s_name =
""
,
37
.s_count =
ATOMIC_INIT
(1),
38
.s_flags =
SYSFS_DIR
| (
KOBJ_NS_TYPE_NONE
<<
SYSFS_NS_TYPE_SHIFT
),
39
.
s_mode
=
S_IFDIR
|
S_IRUGO
|
S_IXUGO
,
40
.
s_ino
= 1,
41
};
42
43
static
int
sysfs_fill_super(
struct
super_block
*
sb
,
void
*
data
,
int
silent)
44
{
45
struct
inode
*
inode
;
46
struct
dentry
*
root
;
47
48
sb->
s_blocksize
=
PAGE_CACHE_SIZE
;
49
sb->
s_blocksize_bits
=
PAGE_CACHE_SHIFT
;
50
sb->
s_magic
=
SYSFS_MAGIC
;
51
sb->
s_op
= &sysfs_ops;
52
sb->
s_time_gran
= 1;
53
54
/* get root inode, initialize and unlock it */
55
mutex_lock
(&
sysfs_mutex
);
56
inode =
sysfs_get_inode
(sb, &sysfs_root);
57
mutex_unlock
(&
sysfs_mutex
);
58
if
(!inode) {
59
pr_debug
(
"sysfs: could not get root inode\n"
);
60
return
-
ENOMEM
;
61
}
62
63
/* instantiate and link root dentry */
64
root =
d_make_root
(inode);
65
if
(!root) {
66
pr_debug
(
"%s: could not get root dentry!\n"
,__func__);
67
return
-
ENOMEM
;
68
}
69
root->
d_fsdata
= &
sysfs_root
;
70
sb->
s_root
= root;
71
sb->
s_d_op
= &
sysfs_dentry_ops
;
72
return
0;
73
}
74
75
static
int
sysfs_test_super(
struct
super_block
*sb,
void
*data)
76
{
77
struct
sysfs_super_info
*sb_info =
sysfs_info
(sb);
78
struct
sysfs_super_info
*
info
=
data
;
79
enum
kobj_ns_type
type
;
80
int
found = 1;
81
82
for
(type =
KOBJ_NS_TYPE_NONE
; type <
KOBJ_NS_TYPES
; type++) {
83
if
(sb_info->
ns
[type] != info->
ns
[type])
84
found = 0;
85
}
86
return
found;
87
}
88
89
static
int
sysfs_set_super(
struct
super_block
*sb,
void
*data)
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
98
static
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
106
static
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++)
119
info->
ns
[type] =
kobj_ns_grab_current
(type);
120
121
sb =
sget
(fs_type, sysfs_test_super, sysfs_set_super, flags, info);
122
if
(IS_ERR(sb) || sb->
s_fs_info
!= info)
123
free_sysfs_super_info(info);
124
if
(IS_ERR(sb))
125
return
ERR_CAST(sb);
126
if
(!sb->
s_root
) {
127
error = sysfs_fill_super(sb, data, flags &
MS_SILENT
? 1 : 0);
128
if
(error) {
129
deactivate_locked_super
(sb);
130
return
ERR_PTR(error);
131
}
132
sb->
s_flags
|=
MS_ACTIVE
;
133
}
134
135
return
dget(sb->
s_root
);
136
}
137
138
static
void
sysfs_kill_sb(
struct
super_block
*sb)
139
{
140
struct
sysfs_super_info
*info =
sysfs_info
(sb);
141
/* Remove the superblock from fs_supers/s_instances
142
* so we can't find it, before freeing sysfs_super_info.
143
*/
144
kill_anon_super
(sb);
145
free_sysfs_super_info(info);
146
}
147
148
static
struct
file_system_type
sysfs_fs_type = {
149
.
name
=
"sysfs"
,
150
.mount = sysfs_mount,
151
.kill_sb = sysfs_kill_sb,
152
};
153
154
int
__init
sysfs_init
(
void
)
155
{
156
int
err
= -
ENOMEM
;
157
158
sysfs_dir_cachep =
kmem_cache_create
(
"sysfs_dir_cache"
,
159
sizeof
(
struct
sysfs_dirent
),
160
0, 0,
NULL
);
161
if
(!sysfs_dir_cachep)
162
goto
out
;
163
164
err =
sysfs_inode_init
();
165
if
(err)
166
goto
out_err;
167
168
err =
register_filesystem
(&sysfs_fs_type);
169
if
(!err) {
170
sysfs_mnt =
kern_mount
(&sysfs_fs_type);
171
if
(IS_ERR(sysfs_mnt)) {
172
printk
(
KERN_ERR
"sysfs: could not mount!\n"
);
173
err = PTR_ERR(sysfs_mnt);
174
sysfs_mnt =
NULL
;
175
unregister_filesystem
(&sysfs_fs_type);
176
goto
out_err;
177
}
178
}
else
179
goto
out_err;
180
out
:
181
return
err
;
182
out_err:
183
kmem_cache_destroy
(sysfs_dir_cachep);
184
sysfs_dir_cachep =
NULL
;
185
goto
out
;
186
}
187
188
#undef sysfs_get
189
struct
sysfs_dirent
*
sysfs_get
(
struct
sysfs_dirent
*
sd
)
190
{
191
return
__sysfs_get(sd);
192
}
193
EXPORT_SYMBOL_GPL
(
sysfs_get
);
194
195
#undef sysfs_put
196
void
sysfs_put
(
struct
sysfs_dirent
*
sd
)
197
{
198
__sysfs_put(sd);
199
}
200
EXPORT_SYMBOL_GPL
(
sysfs_put
);
Generated on Thu Jan 10 2013 14:46:21 for Linux Kernel by
1.8.2