aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs_struct.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 15:27:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 15:27:27 -0400
commita66d2c8f7ec1284206ca7c14569e2a607583f1e3 (patch)
tree08cf68bcef3559b370843cab8191e5cc0f740bde /fs/fs_struct.c
parenta6be1fcbc57f95bb47ef3c8e4ee3d83731b8f21e (diff)
parent8cae6f7158ec1fa44c8a04a43db7d8020ec60437 (diff)
Merge branch 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull the big VFS changes from Al Viro: "This one is *big* and changes quite a few things around VFS. What's in there: - the first of two really major architecture changes - death to open intents. The former is finally there; it was very long in making, but with Miklos getting through really hard and messy final push in fs/namei.c, we finally have it. Unlike his variant, this one doesn't introduce struct opendata; what we have instead is ->atomic_open() taking preallocated struct file * and passing everything via its fields. Instead of returning struct file *, it returns -E... on error, 0 on success and 1 in "deal with it yourself" case (e.g. symlink found on server, etc.). See comments before fs/namei.c:atomic_open(). That made a lot of goodies finally possible and quite a few are in that pile: ->lookup(), ->d_revalidate() and ->create() do not get struct nameidata * anymore; ->lookup() and ->d_revalidate() get lookup flags instead, ->create() gets "do we want it exclusive" flag. With the introduction of new helper (kern_path_locked()) we are rid of all struct nameidata instances outside of fs/namei.c; it's still visible in namei.h, but not for long. Come the next cycle, declaration will move either to fs/internal.h or to fs/namei.c itself. [me, miklos, hch] - The second major change: behaviour of final fput(). Now we have __fput() done without any locks held by caller *and* not from deep in call stack. That obviously lifts a lot of constraints on the locking in there. Moreover, it's legal now to call fput() from atomic contexts (which has immediately simplified life for aio.c). We also don't need anti-recursion logics in __scm_destroy() anymore. There is a price, though - the damn thing has become partially asynchronous. For fput() from normal process we are guaranteed that pending __fput() will be done before the caller returns to userland, exits or gets stopped for ptrace. For kernel threads and atomic contexts it's done via schedule_work(), so theoretically we might need a way to make sure it's finished; so far only one such place had been found, but there might be more. There's flush_delayed_fput() (do all pending __fput()) and there's __fput_sync() (fput() analog doing __fput() immediately). I hope we won't need them often; see warnings in fs/file_table.c for details. [me, based on task_work series from Oleg merged last cycle] - sync series from Jan - large part of "death to sync_supers()" work from Artem; the only bits missing here are exofs and ext4 ones. As far as I understand, those are going via the exofs and ext4 trees resp.; once they are in, we can put ->write_super() to the rest, along with the thread calling it. - preparatory bits from unionmount series (from dhowells). - assorted cleanups and fixes all over the place, as usual. This is not the last pile for this cycle; there's at least jlayton's ESTALE work and fsfreeze series (the latter - in dire need of fixes, so I'm not sure it'll make the cut this cycle). I'll probably throw symlink/hardlink restrictions stuff from Kees into the next pile, too. Plus there's a lot of misc patches I hadn't thrown into that one - it's large enough as it is..." * 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (127 commits) ext4: switch EXT4_IOC_RESIZE_FS to mnt_want_write_file() btrfs: switch btrfs_ioctl_balance() to mnt_want_write_file() switch dentry_open() to struct path, make it grab references itself spufs: shift dget/mntget towards dentry_open() zoran: don't bother with struct file * in zoran_map ecryptfs: don't reinvent the wheels, please - use struct completion don't expose I_NEW inodes via dentry->d_inode tidy up namei.c a bit unobfuscate follow_up() a bit ext3: pass custom EOF to generic_file_llseek_size() ext4: use core vfs llseek code for dir seeks vfs: allow custom EOF in generic_file_llseek code vfs: Avoid unnecessary WB_SYNC_NONE writeback during sys_sync and reorder sync passes vfs: Remove unnecessary flushing of block devices vfs: Make sys_sync writeout also block device inodes vfs: Create function for iterating over block devices vfs: Reorder operations during sys_sync quota: Move quota syncing to ->sync_fs method quota: Split dquot_quota_sync() to writeback and cache flushing part vfs: Move noop_backing_dev_info check from sync into writeback ...
Diffstat (limited to 'fs/fs_struct.c')
-rw-r--r--fs/fs_struct.c32
1 files changed, 10 insertions, 22 deletions
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index e159e682ad4c..5df4775fea03 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -6,18 +6,6 @@
6#include <linux/fs_struct.h> 6#include <linux/fs_struct.h>
7#include "internal.h" 7#include "internal.h"
8 8
9static inline void path_get_longterm(struct path *path)
10{
11 path_get(path);
12 mnt_make_longterm(path->mnt);
13}
14
15static inline void path_put_longterm(struct path *path)
16{
17 mnt_make_shortterm(path->mnt);
18 path_put(path);
19}
20
21/* 9/*
22 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. 10 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
23 * It can block. 11 * It can block.
@@ -26,7 +14,7 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
26{ 14{
27 struct path old_root; 15 struct path old_root;
28 16
29 path_get_longterm(path); 17 path_get(path);
30 spin_lock(&fs->lock); 18 spin_lock(&fs->lock);
31 write_seqcount_begin(&fs->seq); 19 write_seqcount_begin(&fs->seq);
32 old_root = fs->root; 20 old_root = fs->root;
@@ -34,7 +22,7 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
34 write_seqcount_end(&fs->seq); 22 write_seqcount_end(&fs->seq);
35 spin_unlock(&fs->lock); 23 spin_unlock(&fs->lock);
36 if (old_root.dentry) 24 if (old_root.dentry)
37 path_put_longterm(&old_root); 25 path_put(&old_root);
38} 26}
39 27
40/* 28/*
@@ -45,7 +33,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
45{ 33{
46 struct path old_pwd; 34 struct path old_pwd;
47 35
48 path_get_longterm(path); 36 path_get(path);
49 spin_lock(&fs->lock); 37 spin_lock(&fs->lock);
50 write_seqcount_begin(&fs->seq); 38 write_seqcount_begin(&fs->seq);
51 old_pwd = fs->pwd; 39 old_pwd = fs->pwd;
@@ -54,7 +42,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
54 spin_unlock(&fs->lock); 42 spin_unlock(&fs->lock);
55 43
56 if (old_pwd.dentry) 44 if (old_pwd.dentry)
57 path_put_longterm(&old_pwd); 45 path_put(&old_pwd);
58} 46}
59 47
60static inline int replace_path(struct path *p, const struct path *old, const struct path *new) 48static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
@@ -84,7 +72,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
84 write_seqcount_end(&fs->seq); 72 write_seqcount_end(&fs->seq);
85 while (hits--) { 73 while (hits--) {
86 count++; 74 count++;
87 path_get_longterm(new_root); 75 path_get(new_root);
88 } 76 }
89 spin_unlock(&fs->lock); 77 spin_unlock(&fs->lock);
90 } 78 }
@@ -92,13 +80,13 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
92 } while_each_thread(g, p); 80 } while_each_thread(g, p);
93 read_unlock(&tasklist_lock); 81 read_unlock(&tasklist_lock);
94 while (count--) 82 while (count--)
95 path_put_longterm(old_root); 83 path_put(old_root);
96} 84}
97 85
98void free_fs_struct(struct fs_struct *fs) 86void free_fs_struct(struct fs_struct *fs)
99{ 87{
100 path_put_longterm(&fs->root); 88 path_put(&fs->root);
101 path_put_longterm(&fs->pwd); 89 path_put(&fs->pwd);
102 kmem_cache_free(fs_cachep, fs); 90 kmem_cache_free(fs_cachep, fs);
103} 91}
104 92
@@ -132,9 +120,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
132 120
133 spin_lock(&old->lock); 121 spin_lock(&old->lock);
134 fs->root = old->root; 122 fs->root = old->root;
135 path_get_longterm(&fs->root); 123 path_get(&fs->root);
136 fs->pwd = old->pwd; 124 fs->pwd = old->pwd;
137 path_get_longterm(&fs->pwd); 125 path_get(&fs->pwd);
138 spin_unlock(&old->lock); 126 spin_unlock(&old->lock);
139 } 127 }
140 return fs; 128 return fs;