diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 11:56:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 11:56:33 -0500 |
commit | b4a45f5fe8078bfc10837dbd5b98735058bc4698 (patch) | |
tree | df6f13a27610a3ec7eb4a661448cd779a8f84c79 /fs/fs_struct.c | |
parent | 01539ba2a706ab7d35fc0667dff919ade7f87d63 (diff) | |
parent | b3e19d924b6eaf2ca7d22cba99a517c5171007b6 (diff) |
Merge branch 'vfs-scale-working' of git://git.kernel.org/pub/scm/linux/kernel/git/npiggin/linux-npiggin
* 'vfs-scale-working' of git://git.kernel.org/pub/scm/linux/kernel/git/npiggin/linux-npiggin: (57 commits)
fs: scale mntget/mntput
fs: rename vfsmount counter helpers
fs: implement faster dentry memcmp
fs: prefetch inode data in dcache lookup
fs: improve scalability of pseudo filesystems
fs: dcache per-inode inode alias locking
fs: dcache per-bucket dcache hash locking
bit_spinlock: add required includes
kernel: add bl_list
xfs: provide simple rcu-walk ACL implementation
btrfs: provide simple rcu-walk ACL implementation
ext2,3,4: provide simple rcu-walk ACL implementation
fs: provide simple rcu-walk generic_check_acl implementation
fs: provide rcu-walk aware permission i_ops
fs: rcu-walk aware d_revalidate method
fs: cache optimise dentry and inode for rcu-walk
fs: dcache reduce branches in lookup path
fs: dcache remove d_mounted
fs: fs_struct use seqlock
fs: rcu-walk for path lookup
...
Diffstat (limited to 'fs/fs_struct.c')
-rw-r--r-- | fs/fs_struct.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/fs_struct.c b/fs/fs_struct.c index ed45a9cf5f3d..68ca487bedb1 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c | |||
@@ -14,12 +14,14 @@ void set_fs_root(struct fs_struct *fs, struct path *path) | |||
14 | struct path old_root; | 14 | struct path old_root; |
15 | 15 | ||
16 | spin_lock(&fs->lock); | 16 | spin_lock(&fs->lock); |
17 | write_seqcount_begin(&fs->seq); | ||
17 | old_root = fs->root; | 18 | old_root = fs->root; |
18 | fs->root = *path; | 19 | fs->root = *path; |
19 | path_get(path); | 20 | path_get_long(path); |
21 | write_seqcount_end(&fs->seq); | ||
20 | spin_unlock(&fs->lock); | 22 | spin_unlock(&fs->lock); |
21 | if (old_root.dentry) | 23 | if (old_root.dentry) |
22 | path_put(&old_root); | 24 | path_put_long(&old_root); |
23 | } | 25 | } |
24 | 26 | ||
25 | /* | 27 | /* |
@@ -31,13 +33,15 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) | |||
31 | struct path old_pwd; | 33 | struct path old_pwd; |
32 | 34 | ||
33 | spin_lock(&fs->lock); | 35 | spin_lock(&fs->lock); |
36 | write_seqcount_begin(&fs->seq); | ||
34 | old_pwd = fs->pwd; | 37 | old_pwd = fs->pwd; |
35 | fs->pwd = *path; | 38 | fs->pwd = *path; |
36 | path_get(path); | 39 | path_get_long(path); |
40 | write_seqcount_end(&fs->seq); | ||
37 | spin_unlock(&fs->lock); | 41 | spin_unlock(&fs->lock); |
38 | 42 | ||
39 | if (old_pwd.dentry) | 43 | if (old_pwd.dentry) |
40 | path_put(&old_pwd); | 44 | path_put_long(&old_pwd); |
41 | } | 45 | } |
42 | 46 | ||
43 | void chroot_fs_refs(struct path *old_root, struct path *new_root) | 47 | void chroot_fs_refs(struct path *old_root, struct path *new_root) |
@@ -52,31 +56,33 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
52 | fs = p->fs; | 56 | fs = p->fs; |
53 | if (fs) { | 57 | if (fs) { |
54 | spin_lock(&fs->lock); | 58 | spin_lock(&fs->lock); |
59 | write_seqcount_begin(&fs->seq); | ||
55 | if (fs->root.dentry == old_root->dentry | 60 | if (fs->root.dentry == old_root->dentry |
56 | && fs->root.mnt == old_root->mnt) { | 61 | && fs->root.mnt == old_root->mnt) { |
57 | path_get(new_root); | 62 | path_get_long(new_root); |
58 | fs->root = *new_root; | 63 | fs->root = *new_root; |
59 | count++; | 64 | count++; |
60 | } | 65 | } |
61 | if (fs->pwd.dentry == old_root->dentry | 66 | if (fs->pwd.dentry == old_root->dentry |
62 | && fs->pwd.mnt == old_root->mnt) { | 67 | && fs->pwd.mnt == old_root->mnt) { |
63 | path_get(new_root); | 68 | path_get_long(new_root); |
64 | fs->pwd = *new_root; | 69 | fs->pwd = *new_root; |
65 | count++; | 70 | count++; |
66 | } | 71 | } |
72 | write_seqcount_end(&fs->seq); | ||
67 | spin_unlock(&fs->lock); | 73 | spin_unlock(&fs->lock); |
68 | } | 74 | } |
69 | task_unlock(p); | 75 | task_unlock(p); |
70 | } while_each_thread(g, p); | 76 | } while_each_thread(g, p); |
71 | read_unlock(&tasklist_lock); | 77 | read_unlock(&tasklist_lock); |
72 | while (count--) | 78 | while (count--) |
73 | path_put(old_root); | 79 | path_put_long(old_root); |
74 | } | 80 | } |
75 | 81 | ||
76 | void free_fs_struct(struct fs_struct *fs) | 82 | void free_fs_struct(struct fs_struct *fs) |
77 | { | 83 | { |
78 | path_put(&fs->root); | 84 | path_put_long(&fs->root); |
79 | path_put(&fs->pwd); | 85 | path_put_long(&fs->pwd); |
80 | kmem_cache_free(fs_cachep, fs); | 86 | kmem_cache_free(fs_cachep, fs); |
81 | } | 87 | } |
82 | 88 | ||
@@ -88,8 +94,10 @@ void exit_fs(struct task_struct *tsk) | |||
88 | int kill; | 94 | int kill; |
89 | task_lock(tsk); | 95 | task_lock(tsk); |
90 | spin_lock(&fs->lock); | 96 | spin_lock(&fs->lock); |
97 | write_seqcount_begin(&fs->seq); | ||
91 | tsk->fs = NULL; | 98 | tsk->fs = NULL; |
92 | kill = !--fs->users; | 99 | kill = !--fs->users; |
100 | write_seqcount_end(&fs->seq); | ||
93 | spin_unlock(&fs->lock); | 101 | spin_unlock(&fs->lock); |
94 | task_unlock(tsk); | 102 | task_unlock(tsk); |
95 | if (kill) | 103 | if (kill) |
@@ -105,8 +113,15 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) | |||
105 | fs->users = 1; | 113 | fs->users = 1; |
106 | fs->in_exec = 0; | 114 | fs->in_exec = 0; |
107 | spin_lock_init(&fs->lock); | 115 | spin_lock_init(&fs->lock); |
116 | seqcount_init(&fs->seq); | ||
108 | fs->umask = old->umask; | 117 | fs->umask = old->umask; |
109 | get_fs_root_and_pwd(old, &fs->root, &fs->pwd); | 118 | |
119 | spin_lock(&old->lock); | ||
120 | fs->root = old->root; | ||
121 | path_get_long(&fs->root); | ||
122 | fs->pwd = old->pwd; | ||
123 | path_get_long(&fs->pwd); | ||
124 | spin_unlock(&old->lock); | ||
110 | } | 125 | } |
111 | return fs; | 126 | return fs; |
112 | } | 127 | } |
@@ -144,6 +159,7 @@ EXPORT_SYMBOL(current_umask); | |||
144 | struct fs_struct init_fs = { | 159 | struct fs_struct init_fs = { |
145 | .users = 1, | 160 | .users = 1, |
146 | .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), | 161 | .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), |
162 | .seq = SEQCNT_ZERO, | ||
147 | .umask = 0022, | 163 | .umask = 0022, |
148 | }; | 164 | }; |
149 | 165 | ||