diff options
author | Josef Bacik <josef@redhat.com> | 2009-10-08 15:30:04 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-10-08 15:30:04 -0400 |
commit | ff782e0a131c7f669445c07fe5c7ba91e043b7ed (patch) | |
tree | ff7773e6ce60bf977ed29897c13605f257647684 | |
parent | e3ccfa989752c083ceb23c823a84f7ce3a081e61 (diff) |
Btrfs: optimize fsync for the single writer case
This patch optimizes the tree logging stuff so it doesn't always wait 1 jiffie
for new people to join the logging transaction if there is only ever 1 writer.
This helps a little bit with latency where we have something like RPM where it
will fdatasync every file it writes, and so waiting the 1 jiffie for every
fdatasync really starts to add up.
Signed-off-by: Josef Bacik <jbacik@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 12 |
2 files changed, 13 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a362dd617e97..16ddb19dda86 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1010,6 +1010,8 @@ struct btrfs_root { | |||
1010 | atomic_t log_commit[2]; | 1010 | atomic_t log_commit[2]; |
1011 | unsigned long log_transid; | 1011 | unsigned long log_transid; |
1012 | unsigned long log_batch; | 1012 | unsigned long log_batch; |
1013 | pid_t log_start_pid; | ||
1014 | bool log_multiple_pids; | ||
1013 | 1015 | ||
1014 | u64 objectid; | 1016 | u64 objectid; |
1015 | u64 last_trans; | 1017 | u64 last_trans; |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 4d7d9abef42f..78f6254ac2d9 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -137,11 +137,20 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
137 | 137 | ||
138 | mutex_lock(&root->log_mutex); | 138 | mutex_lock(&root->log_mutex); |
139 | if (root->log_root) { | 139 | if (root->log_root) { |
140 | if (!root->log_start_pid) { | ||
141 | root->log_start_pid = current->pid; | ||
142 | root->log_multiple_pids = false; | ||
143 | } else if (root->log_start_pid != current->pid) { | ||
144 | root->log_multiple_pids = true; | ||
145 | } | ||
146 | |||
140 | root->log_batch++; | 147 | root->log_batch++; |
141 | atomic_inc(&root->log_writers); | 148 | atomic_inc(&root->log_writers); |
142 | mutex_unlock(&root->log_mutex); | 149 | mutex_unlock(&root->log_mutex); |
143 | return 0; | 150 | return 0; |
144 | } | 151 | } |
152 | root->log_multiple_pids = false; | ||
153 | root->log_start_pid = current->pid; | ||
145 | mutex_lock(&root->fs_info->tree_log_mutex); | 154 | mutex_lock(&root->fs_info->tree_log_mutex); |
146 | if (!root->fs_info->log_root_tree) { | 155 | if (!root->fs_info->log_root_tree) { |
147 | ret = btrfs_init_log_root_tree(trans, root->fs_info); | 156 | ret = btrfs_init_log_root_tree(trans, root->fs_info); |
@@ -1985,7 +1994,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
1985 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) | 1994 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) |
1986 | wait_log_commit(trans, root, root->log_transid - 1); | 1995 | wait_log_commit(trans, root, root->log_transid - 1); |
1987 | 1996 | ||
1988 | while (1) { | 1997 | while (root->log_multiple_pids) { |
1989 | unsigned long batch = root->log_batch; | 1998 | unsigned long batch = root->log_batch; |
1990 | mutex_unlock(&root->log_mutex); | 1999 | mutex_unlock(&root->log_mutex); |
1991 | schedule_timeout_uninterruptible(1); | 2000 | schedule_timeout_uninterruptible(1); |
@@ -2011,6 +2020,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2011 | root->log_batch = 0; | 2020 | root->log_batch = 0; |
2012 | root->log_transid++; | 2021 | root->log_transid++; |
2013 | log->log_transid = root->log_transid; | 2022 | log->log_transid = root->log_transid; |
2023 | root->log_start_pid = 0; | ||
2014 | smp_mb(); | 2024 | smp_mb(); |
2015 | /* | 2025 | /* |
2016 | * log tree has been flushed to disk, new modifications of | 2026 | * log tree has been flushed to disk, new modifications of |