]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.suse/mnt_clone_write.patch
Changed checkfs to auto reboot after correctable fsck fixes.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / mnt_clone_write.patch
CommitLineData
00e5a55c
BS
1From: Nick Piggin <npiggin@suse.de>
2Subject: fs: introduce mnt_clone_write
3References: bnc#436953
4Patch-upstream: no (could be submitted)
5
6This patch speeds up lmbench lat_mmap test by about another 2% after the
7first patch.
8
9Before:
10 avg = 462.286
11 std = 5.46106
12
13After:
14 avg = 453.12
15 std = 9.58257
16
17(50 runs of each, stddev gives a reasonable confidence)
18
19It does this by introducing mnt_clone_write, which avoids some heavyweight
20operations of mnt_want_write if called on a vfsmount which we know already
21has a write count; and mnt_want_write_file, which can call mnt_clone_write
22if the file is open for write.
23
24After these two patches, mnt_want_write and mnt_drop_write go from 7% on
25the profile down to 1.3% (including mnt_clone_write).
26
27---
28 fs/file_table.c | 3 +--
29 fs/inode.c | 2 +-
30 fs/namespace.c | 38 ++++++++++++++++++++++++++++++++++++++
31 fs/open.c | 4 ++--
32 fs/xattr.c | 4 ++--
33 include/linux/mount.h | 2 ++
34 6 files changed, 46 insertions(+), 7 deletions(-)
35
36--- a/fs/file_table.c
37+++ b/fs/file_table.c
38@@ -210,8 +210,7 @@ int init_file(struct file *file, struct
39 */
40 if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) {
41 file_take_write(file);
42- error = mnt_want_write(mnt);
43- WARN_ON(error);
44+ mnt_clone_write(mnt);
45 }
46 return error;
47 }
48--- a/fs/inode.c
49+++ b/fs/inode.c
50@@ -1256,7 +1256,7 @@ void file_update_time(struct file *file)
51 if (IS_NOCMTIME(inode))
52 return;
53
54- err = mnt_want_write(file->f_path.mnt);
55+ err = mnt_want_write_file(file->f_path.mnt, file);
56 if (err)
57 return;
58
59--- a/fs/namespace.c
60+++ b/fs/namespace.c
61@@ -264,6 +264,44 @@ out:
62 EXPORT_SYMBOL_GPL(mnt_want_write);
63
64 /**
65+ * mnt_clone_write - get write access to a mount
66+ * @mnt: the mount on which to take a write
67+ *
68+ * This is effectively like mnt_want_write, except
69+ * it must only be used to take an extra write reference
70+ * on a mountpoint that we already know has a write reference
71+ * on it. This allows some optimisation.
72+ *
73+ * After finished, mnt_drop_write must be called as usual to
74+ * drop the reference.
75+ */
76+void mnt_clone_write(struct vfsmount *mnt)
77+{
78+ preempt_disable();
79+ inc_mnt_writers(mnt);
80+ preempt_enable();
81+}
82+EXPORT_SYMBOL_GPL(mnt_clone_write);
83+
84+/**
85+ * mnt_want_write_file - get write access to a file's mount
86+ * @file: the file who's mount on which to take a write
87+ *
88+ * This is like mnt_want_write, but it takes a file and can
89+ * do some optimisations if the file is open for write already
90+ */
91+int mnt_want_write_file(struct vfsmount *mnt, struct file *file)
92+{
93+ if (!(file->f_mode & FMODE_WRITE))
94+ return mnt_want_write(mnt);
95+ else {
96+ mnt_clone_write(mnt);
97+ return 0;
98+ }
99+}
100+EXPORT_SYMBOL_GPL(mnt_want_write_file);
101+
102+/**
103 * mnt_drop_write - give up write access to a mount
104 * @mnt: the mount on which to give up write access
105 *
106--- a/fs/open.c
107+++ b/fs/open.c
108@@ -616,7 +616,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
109
110 audit_inode(NULL, dentry);
111
112- err = mnt_want_write(file->f_path.mnt);
113+ err = mnt_want_write_file(file->f_path.mnt, file);
114 if (err)
115 goto out_putf;
116 mutex_lock(&inode->i_mutex);
117@@ -765,7 +765,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd
118 if (!file)
119 goto out;
120
121- error = mnt_want_write(file->f_path.mnt);
122+ error = mnt_want_write_file(file->f_path.mnt, file);
123 if (error)
124 goto out_fput;
125 dentry = file->f_path.dentry;
126--- a/fs/xattr.c
127+++ b/fs/xattr.c
128@@ -301,7 +301,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
129 return error;
130 dentry = f->f_path.dentry;
131 audit_inode(NULL, dentry);
132- error = mnt_want_write(f->f_path.mnt);
133+ error = mnt_want_write_file(f->f_path.mnt, f);
134 if (!error) {
135 error = setxattr(dentry, name, value, size, flags);
136 mnt_drop_write(f->f_path.mnt);
137@@ -528,7 +528,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, c
138 return error;
139 dentry = f->f_path.dentry;
140 audit_inode(NULL, dentry);
141- error = mnt_want_write(f->f_path.mnt);
142+ error = mnt_want_write_file(f->f_path.mnt, f);
143 if (!error) {
144 error = removexattr(dentry, name);
145 mnt_drop_write(f->f_path.mnt);
146--- a/include/linux/mount.h
147+++ b/include/linux/mount.h
148@@ -99,6 +99,8 @@ static inline struct vfsmount *mntget(st
149 }
150
151 extern int mnt_want_write(struct vfsmount *mnt);
152+extern int mnt_want_write_file(struct vfsmount *mnt, struct file *file);
153+extern void mnt_clone_write(struct vfsmount *mnt);
154 extern void mnt_drop_write(struct vfsmount *mnt);
155 extern void mntput_no_expire(struct vfsmount *mnt);
156 extern void mnt_pin(struct vfsmount *mnt);