From: npiggin@suse.de
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
Dave Hansen <haveblue@us.ibm.com>
Subject: [patch 3/5] fs: introduce mnt_clone_write
Date: Sun, 26 Apr 2009 20:25:55 +1000 [thread overview]
Message-ID: <20090426102953.436066523@suse.de> (raw)
In-Reply-To: 20090426102552.947523845@suse.de
[-- Attachment #1: mnt_clone_write.patch --]
[-- Type: text/plain, Size: 5336 bytes --]
This patch speeds up lmbench lat_mmap test by about another 2% after the
first patch.
Before:
avg = 462.286
std = 5.46106
After:
avg = 453.12
std = 9.58257
(50 runs of each, stddev gives a reasonable confidence)
It does this by introducing mnt_clone_write, which avoids some heavyweight
operations of mnt_want_write if called on a vfsmount which we know already
has a write count; and mnt_want_write_file, which can call mnt_clone_write
if the file is open for write.
After these two patches, mnt_want_write and mnt_drop_write go from 7% on
the profile down to 1.3% (including mnt_clone_write).
Cc: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Nick Piggin <npiggin@suse.de>
---
fs/file_table.c | 2 +-
fs/inode.c | 2 +-
fs/namespace.c | 40 ++++++++++++++++++++++++++++++++++++++++
fs/open.c | 4 ++--
fs/xattr.c | 4 ++--
include/linux/mount.h | 4 ++++
6 files changed, 50 insertions(+), 6 deletions(-)
Index: linux-2.6/fs/file_table.c
===================================================================
--- linux-2.6.orig/fs/file_table.c
+++ linux-2.6/fs/file_table.c
@@ -214,7 +214,7 @@ int init_file(struct file *file, struct
*/
if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) {
file_take_write(file);
- error = mnt_want_write(mnt);
+ error = mnt_clone_write(mnt);
WARN_ON(error);
}
return error;
Index: linux-2.6/fs/inode.c
===================================================================
--- linux-2.6.orig/fs/inode.c
+++ linux-2.6/fs/inode.c
@@ -1401,7 +1401,7 @@ void file_update_time(struct file *file)
if (IS_NOCMTIME(inode))
return;
- err = mnt_want_write(file->f_path.mnt);
+ err = mnt_want_write_file(file->f_path.mnt, file);
if (err)
return;
Index: linux-2.6/fs/namespace.c
===================================================================
--- linux-2.6.orig/fs/namespace.c
+++ linux-2.6/fs/namespace.c
@@ -265,6 +265,46 @@ out:
EXPORT_SYMBOL_GPL(mnt_want_write);
/**
+ * mnt_clone_write - get write access to a mount
+ * @mnt: the mount on which to take a write
+ *
+ * This is effectively like mnt_want_write, except
+ * it must only be used to take an extra write reference
+ * on a mountpoint that we already know has a write reference
+ * on it. This allows some optimisation.
+ *
+ * After finished, mnt_drop_write must be called as usual to
+ * drop the reference.
+ */
+int mnt_clone_write(struct vfsmount *mnt)
+{
+ /* superblock may be r/o */
+ if (__mnt_is_readonly(mnt))
+ return -EROFS;
+ preempt_disable();
+ inc_mnt_writers(mnt);
+ preempt_enable();
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mnt_clone_write);
+
+/**
+ * mnt_want_write_file - get write access to a file's mount
+ * @file: the file who's mount on which to take a write
+ *
+ * This is like mnt_want_write, but it takes a file and can
+ * do some optimisations if the file is open for write already
+ */
+int mnt_want_write_file(struct vfsmount *mnt, struct file *file)
+{
+ if (!(file->f_mode & FMODE_WRITE))
+ return mnt_want_write(mnt);
+ else
+ return mnt_clone_write(mnt);
+}
+EXPORT_SYMBOL_GPL(mnt_want_write_file);
+
+/**
* mnt_drop_write - give up write access to a mount
* @mnt: the mount on which to give up write access
*
Index: linux-2.6/fs/open.c
===================================================================
--- linux-2.6.orig/fs/open.c
+++ linux-2.6/fs/open.c
@@ -612,7 +612,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
audit_inode(NULL, dentry);
- err = mnt_want_write(file->f_path.mnt);
+ err = mnt_want_write_file(file->f_path.mnt, file);
if (err)
goto out_putf;
mutex_lock(&inode->i_mutex);
@@ -761,7 +761,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd
if (!file)
goto out;
- error = mnt_want_write(file->f_path.mnt);
+ error = mnt_want_write_file(file->f_path.mnt, file);
if (error)
goto out_fput;
dentry = file->f_path.dentry;
Index: linux-2.6/fs/xattr.c
===================================================================
--- linux-2.6.orig/fs/xattr.c
+++ linux-2.6/fs/xattr.c
@@ -297,7 +297,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
return error;
dentry = f->f_path.dentry;
audit_inode(NULL, dentry);
- error = mnt_want_write(f->f_path.mnt);
+ error = mnt_want_write_file(f->f_path.mnt, f);
if (!error) {
error = setxattr(dentry, name, value, size, flags);
mnt_drop_write(f->f_path.mnt);
@@ -524,7 +524,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, c
return error;
dentry = f->f_path.dentry;
audit_inode(NULL, dentry);
- error = mnt_want_write(f->f_path.mnt);
+ error = mnt_want_write_file(f->f_path.mnt, f);
if (!error) {
error = removexattr(dentry, name);
mnt_drop_write(f->f_path.mnt);
Index: linux-2.6/include/linux/mount.h
===================================================================
--- linux-2.6.orig/include/linux/mount.h
+++ linux-2.6/include/linux/mount.h
@@ -88,7 +88,11 @@ static inline struct vfsmount *mntget(st
return mnt;
}
+struct file; /* forward dec */
+
extern int mnt_want_write(struct vfsmount *mnt);
+extern int mnt_want_write_file(struct vfsmount *mnt, struct file *file);
+extern int mnt_clone_write(struct vfsmount *mnt);
extern void mnt_drop_write(struct vfsmount *mnt);
extern void mntput_no_expire(struct vfsmount *mnt);
extern void mnt_pin(struct vfsmount *mnt);
next prev parent reply other threads:[~2009-04-26 10:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-26 10:25 [patch 0/5] initial fs patches npiggin
2009-04-26 10:25 ` [patch 1/5] fs: dcache fix LRU ordering npiggin
2009-04-26 10:25 ` [patch 2/5] fs: mnt_want_write speedup npiggin
2009-04-26 10:25 ` npiggin [this message]
2009-04-26 10:25 ` [patch 4/5] fs: move mark_files_ro into file_table.c npiggin
2009-04-26 10:25 ` [patch 5/5] fs: cleanup files_lock npiggin
2009-04-26 22:37 ` James Morris
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090426102953.436066523@suse.de \
--to=npiggin@suse.de \
--cc=haveblue@us.ibm.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.