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
fs_struct.c
Go to the documentation of this file.
1
#include <linux/export.h>
2
#include <linux/sched.h>
3
#include <linux/fs.h>
4
#include <
linux/path.h
>
5
#include <linux/slab.h>
6
#include <
linux/fs_struct.h
>
7
#include "
internal.h
"
8
9
/*
10
* Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
11
* It can block.
12
*/
13
void
set_fs_root
(
struct
fs_struct
*
fs
,
struct
path
*
path
)
14
{
15
struct
path old_root;
16
17
path_get
(path);
18
spin_lock(&fs->
lock
);
19
write_seqcount_begin(&fs->
seq
);
20
old_root = fs->root;
21
fs->root = *
path
;
22
write_seqcount_end(&fs->
seq
);
23
spin_unlock(&fs->
lock
);
24
if
(old_root.
dentry
)
25
path_put
(&old_root);
26
}
27
28
/*
29
* Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
30
* It can block.
31
*/
32
void
set_fs_pwd
(
struct
fs_struct
*
fs
,
struct
path
*
path
)
33
{
34
struct
path old_pwd;
35
36
path_get
(path);
37
spin_lock(&fs->
lock
);
38
write_seqcount_begin(&fs->
seq
);
39
old_pwd = fs->
pwd
;
40
fs->
pwd
= *
path
;
41
write_seqcount_end(&fs->
seq
);
42
spin_unlock(&fs->
lock
);
43
44
if
(old_pwd.
dentry
)
45
path_put
(&old_pwd);
46
}
47
48
static
inline
int
replace_path(
struct
path
*
p
,
const
struct
path
*old,
const
struct
path
*
new
)
49
{
50
if
(
likely
(p->
dentry
!= old->
dentry
|| p->
mnt
!= old->
mnt
))
51
return
0;
52
*p = *
new
;
53
return
1;
54
}
55
56
void
chroot_fs_refs
(
struct
path
*old_root,
struct
path
*new_root)
57
{
58
struct
task_struct
*
g
, *
p
;
59
struct
fs_struct
*
fs
;
60
int
count
= 0;
61
62
read_lock
(&
tasklist_lock
);
63
do_each_thread
(g, p) {
64
task_lock(p);
65
fs = p->
fs
;
66
if
(fs) {
67
int
hits = 0;
68
spin_lock(&fs->
lock
);
69
write_seqcount_begin(&fs->
seq
);
70
hits += replace_path(&fs->root, old_root, new_root);
71
hits += replace_path(&fs->
pwd
, old_root, new_root);
72
write_seqcount_end(&fs->
seq
);
73
while
(hits--) {
74
count++;
75
path_get
(new_root);
76
}
77
spin_unlock(&fs->
lock
);
78
}
79
task_unlock(p);
80
}
while_each_thread
(g, p);
81
read_unlock
(&
tasklist_lock
);
82
while
(count--)
83
path_put
(old_root);
84
}
85
86
void
free_fs_struct
(
struct
fs_struct
*
fs
)
87
{
88
path_put
(&fs->root);
89
path_put
(&fs->
pwd
);
90
kmem_cache_free
(
fs_cachep
, fs);
91
}
92
93
void
exit_fs
(
struct
task_struct
*tsk)
94
{
95
struct
fs_struct
*
fs
= tsk->
fs
;
96
97
if
(fs) {
98
int
kill;
99
task_lock(tsk);
100
spin_lock(&fs->
lock
);
101
tsk->
fs
=
NULL
;
102
kill = !--fs->
users
;
103
spin_unlock(&fs->
lock
);
104
task_unlock(tsk);
105
if
(kill)
106
free_fs_struct
(fs);
107
}
108
}
109
110
struct
fs_struct
*
copy_fs_struct
(
struct
fs_struct
*old)
111
{
112
struct
fs_struct
*
fs
=
kmem_cache_alloc
(
fs_cachep
,
GFP_KERNEL
);
113
/* We don't need to lock fs - think why ;-) */
114
if
(fs) {
115
fs->
users
= 1;
116
fs->
in_exec
= 0;
117
spin_lock_init
(&fs->
lock
);
118
seqcount_init
(&fs->
seq
);
119
fs->
umask
= old->
umask
;
120
121
spin_lock(&old->
lock
);
122
fs->root = old->root;
123
path_get
(&fs->root);
124
fs->
pwd
= old->
pwd
;
125
path_get
(&fs->
pwd
);
126
spin_unlock(&old->
lock
);
127
}
128
return
fs
;
129
}
130
131
int
unshare_fs_struct
(
void
)
132
{
133
struct
fs_struct
*
fs
=
current
->fs;
134
struct
fs_struct
*new_fs =
copy_fs_struct
(fs);
135
int
kill;
136
137
if
(!new_fs)
138
return
-
ENOMEM
;
139
140
task_lock(
current
);
141
spin_lock(&fs->
lock
);
142
kill = !--fs->
users
;
143
current
->fs = new_fs;
144
spin_unlock(&fs->
lock
);
145
task_unlock(
current
);
146
147
if
(kill)
148
free_fs_struct
(fs);
149
150
return
0;
151
}
152
EXPORT_SYMBOL_GPL
(
unshare_fs_struct
);
153
154
int
current_umask
(
void
)
155
{
156
return
current
->fs->umask;
157
}
158
EXPORT_SYMBOL
(
current_umask
);
159
160
/* to be mentioned only in INIT_TASK */
161
struct
fs_struct
init_fs
= {
162
.users = 1,
163
.lock =
__SPIN_LOCK_UNLOCKED
(init_fs.
lock
),
164
.seq =
SEQCNT_ZERO
,
165
.umask = 0022,
166
};
167
168
void
daemonize_fs_struct
(
void
)
169
{
170
struct
fs_struct
*
fs
=
current
->fs;
171
172
if
(fs) {
173
int
kill;
174
175
task_lock(
current
);
176
177
spin_lock(&init_fs.
lock
);
178
init_fs.
users
++;
179
spin_unlock(&init_fs.
lock
);
180
181
spin_lock(&fs->
lock
);
182
current
->fs = &
init_fs
;
183
kill = !--fs->
users
;
184
spin_unlock(&fs->
lock
);
185
186
task_unlock(
current
);
187
if
(kill)
188
free_fs_struct
(fs);
189
}
190
}
Generated on Thu Jan 10 2013 14:47:06 for Linux Kernel by
1.8.2