diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2011-05-10 14:52:07 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2011-05-10 16:50:41 -0400 |
commit | 020abf03cd659388f94cb328e1e1df0656e0d7ff (patch) | |
tree | 40d05011708ad1b4a05928d167eb120420581aa6 /fs/fs_struct.c | |
parent | 0ff8fbc61727c926883eec381fbd3d32d1fab504 (diff) | |
parent | 693d92a1bbc9e42681c42ed190bd42b636ca876f (diff) |
Merge tag 'v2.6.39-rc7'
in order to pull in changes in drivers/media/dvb/firewire/ and
sound/firewire/.
Diffstat (limited to 'fs/fs_struct.c')
-rw-r--r-- | fs/fs_struct.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/fs/fs_struct.c b/fs/fs_struct.c index ed45a9cf5f3d..78b519c13536 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c | |||
@@ -4,6 +4,19 @@ | |||
4 | #include <linux/path.h> | 4 | #include <linux/path.h> |
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
6 | #include <linux/fs_struct.h> | 6 | #include <linux/fs_struct.h> |
7 | #include "internal.h" | ||
8 | |||
9 | static inline void path_get_longterm(struct path *path) | ||
10 | { | ||
11 | path_get(path); | ||
12 | mnt_make_longterm(path->mnt); | ||
13 | } | ||
14 | |||
15 | static inline void path_put_longterm(struct path *path) | ||
16 | { | ||
17 | mnt_make_shortterm(path->mnt); | ||
18 | path_put(path); | ||
19 | } | ||
7 | 20 | ||
8 | /* | 21 | /* |
9 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. | 22 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. |
@@ -14,12 +27,14 @@ void set_fs_root(struct fs_struct *fs, struct path *path) | |||
14 | struct path old_root; | 27 | struct path old_root; |
15 | 28 | ||
16 | spin_lock(&fs->lock); | 29 | spin_lock(&fs->lock); |
30 | write_seqcount_begin(&fs->seq); | ||
17 | old_root = fs->root; | 31 | old_root = fs->root; |
18 | fs->root = *path; | 32 | fs->root = *path; |
19 | path_get(path); | 33 | path_get_longterm(path); |
34 | write_seqcount_end(&fs->seq); | ||
20 | spin_unlock(&fs->lock); | 35 | spin_unlock(&fs->lock); |
21 | if (old_root.dentry) | 36 | if (old_root.dentry) |
22 | path_put(&old_root); | 37 | path_put_longterm(&old_root); |
23 | } | 38 | } |
24 | 39 | ||
25 | /* | 40 | /* |
@@ -31,13 +46,15 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) | |||
31 | struct path old_pwd; | 46 | struct path old_pwd; |
32 | 47 | ||
33 | spin_lock(&fs->lock); | 48 | spin_lock(&fs->lock); |
49 | write_seqcount_begin(&fs->seq); | ||
34 | old_pwd = fs->pwd; | 50 | old_pwd = fs->pwd; |
35 | fs->pwd = *path; | 51 | fs->pwd = *path; |
36 | path_get(path); | 52 | path_get_longterm(path); |
53 | write_seqcount_end(&fs->seq); | ||
37 | spin_unlock(&fs->lock); | 54 | spin_unlock(&fs->lock); |
38 | 55 | ||
39 | if (old_pwd.dentry) | 56 | if (old_pwd.dentry) |
40 | path_put(&old_pwd); | 57 | path_put_longterm(&old_pwd); |
41 | } | 58 | } |
42 | 59 | ||
43 | void chroot_fs_refs(struct path *old_root, struct path *new_root) | 60 | void chroot_fs_refs(struct path *old_root, struct path *new_root) |
@@ -52,31 +69,33 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
52 | fs = p->fs; | 69 | fs = p->fs; |
53 | if (fs) { | 70 | if (fs) { |
54 | spin_lock(&fs->lock); | 71 | spin_lock(&fs->lock); |
72 | write_seqcount_begin(&fs->seq); | ||
55 | if (fs->root.dentry == old_root->dentry | 73 | if (fs->root.dentry == old_root->dentry |
56 | && fs->root.mnt == old_root->mnt) { | 74 | && fs->root.mnt == old_root->mnt) { |
57 | path_get(new_root); | 75 | path_get_longterm(new_root); |
58 | fs->root = *new_root; | 76 | fs->root = *new_root; |
59 | count++; | 77 | count++; |
60 | } | 78 | } |
61 | if (fs->pwd.dentry == old_root->dentry | 79 | if (fs->pwd.dentry == old_root->dentry |
62 | && fs->pwd.mnt == old_root->mnt) { | 80 | && fs->pwd.mnt == old_root->mnt) { |
63 | path_get(new_root); | 81 | path_get_longterm(new_root); |
64 | fs->pwd = *new_root; | 82 | fs->pwd = *new_root; |
65 | count++; | 83 | count++; |
66 | } | 84 | } |
85 | write_seqcount_end(&fs->seq); | ||
67 | spin_unlock(&fs->lock); | 86 | spin_unlock(&fs->lock); |
68 | } | 87 | } |
69 | task_unlock(p); | 88 | task_unlock(p); |
70 | } while_each_thread(g, p); | 89 | } while_each_thread(g, p); |
71 | read_unlock(&tasklist_lock); | 90 | read_unlock(&tasklist_lock); |
72 | while (count--) | 91 | while (count--) |
73 | path_put(old_root); | 92 | path_put_longterm(old_root); |
74 | } | 93 | } |
75 | 94 | ||
76 | void free_fs_struct(struct fs_struct *fs) | 95 | void free_fs_struct(struct fs_struct *fs) |
77 | { | 96 | { |
78 | path_put(&fs->root); | 97 | path_put_longterm(&fs->root); |
79 | path_put(&fs->pwd); | 98 | path_put_longterm(&fs->pwd); |
80 | kmem_cache_free(fs_cachep, fs); | 99 | kmem_cache_free(fs_cachep, fs); |
81 | } | 100 | } |
82 | 101 | ||
@@ -88,8 +107,10 @@ void exit_fs(struct task_struct *tsk) | |||
88 | int kill; | 107 | int kill; |
89 | task_lock(tsk); | 108 | task_lock(tsk); |
90 | spin_lock(&fs->lock); | 109 | spin_lock(&fs->lock); |
110 | write_seqcount_begin(&fs->seq); | ||
91 | tsk->fs = NULL; | 111 | tsk->fs = NULL; |
92 | kill = !--fs->users; | 112 | kill = !--fs->users; |
113 | write_seqcount_end(&fs->seq); | ||
93 | spin_unlock(&fs->lock); | 114 | spin_unlock(&fs->lock); |
94 | task_unlock(tsk); | 115 | task_unlock(tsk); |
95 | if (kill) | 116 | if (kill) |
@@ -105,8 +126,15 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) | |||
105 | fs->users = 1; | 126 | fs->users = 1; |
106 | fs->in_exec = 0; | 127 | fs->in_exec = 0; |
107 | spin_lock_init(&fs->lock); | 128 | spin_lock_init(&fs->lock); |
129 | seqcount_init(&fs->seq); | ||
108 | fs->umask = old->umask; | 130 | fs->umask = old->umask; |
109 | get_fs_root_and_pwd(old, &fs->root, &fs->pwd); | 131 | |
132 | spin_lock(&old->lock); | ||
133 | fs->root = old->root; | ||
134 | path_get_longterm(&fs->root); | ||
135 | fs->pwd = old->pwd; | ||
136 | path_get_longterm(&fs->pwd); | ||
137 | spin_unlock(&old->lock); | ||
110 | } | 138 | } |
111 | return fs; | 139 | return fs; |
112 | } | 140 | } |
@@ -144,6 +172,7 @@ EXPORT_SYMBOL(current_umask); | |||
144 | struct fs_struct init_fs = { | 172 | struct fs_struct init_fs = { |
145 | .users = 1, | 173 | .users = 1, |
146 | .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), | 174 | .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), |
175 | .seq = SEQCNT_ZERO, | ||
147 | .umask = 0022, | 176 | .umask = 0022, |
148 | }; | 177 | }; |
149 | 178 | ||