diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-15 18:06:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-15 18:06:37 -0400 |
commit | dcbeb0bec5f2695c3ff53f174efb8e03c209f3f3 (patch) | |
tree | 30d223a3a3c7470c657284ef030657bd1753d4d3 /fs/btrfs/file.c | |
parent | 2b650df2cea96e487f2fd9ecaa68e533ea9b5ed7 (diff) | |
parent | 444528b3e614f7f2391488d9bca8e0b872db909b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
Btrfs: always pin metadata in discard mode
Btrfs: enable discard support
Btrfs: add -o discard option
Btrfs: properly wait log writers during log sync
Btrfs: fix possible ENOSPC problems with truncate
Btrfs: fix btrfs acl #ifdef checks
Btrfs: streamline tree-log btree block writeout
Btrfs: avoid tree log commit when there are no changes
Btrfs: only write one super copy during fsync
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 2d623aa0625f..06550affbd27 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1086,8 +1086,10 @@ out_nolock: | |||
1086 | btrfs_end_transaction(trans, root); | 1086 | btrfs_end_transaction(trans, root); |
1087 | else | 1087 | else |
1088 | btrfs_commit_transaction(trans, root); | 1088 | btrfs_commit_transaction(trans, root); |
1089 | } else { | 1089 | } else if (ret != BTRFS_NO_LOG_SYNC) { |
1090 | btrfs_commit_transaction(trans, root); | 1090 | btrfs_commit_transaction(trans, root); |
1091 | } else { | ||
1092 | btrfs_end_transaction(trans, root); | ||
1091 | } | 1093 | } |
1092 | } | 1094 | } |
1093 | if (file->f_flags & O_DIRECT) { | 1095 | if (file->f_flags & O_DIRECT) { |
@@ -1137,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1137 | int ret = 0; | 1139 | int ret = 0; |
1138 | struct btrfs_trans_handle *trans; | 1140 | struct btrfs_trans_handle *trans; |
1139 | 1141 | ||
1142 | |||
1143 | /* we wait first, since the writeback may change the inode */ | ||
1144 | root->log_batch++; | ||
1145 | /* the VFS called filemap_fdatawrite for us */ | ||
1146 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
1147 | root->log_batch++; | ||
1148 | |||
1140 | /* | 1149 | /* |
1141 | * check the transaction that last modified this inode | 1150 | * check the transaction that last modified this inode |
1142 | * and see if its already been committed | 1151 | * and see if its already been committed |
@@ -1144,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1144 | if (!BTRFS_I(inode)->last_trans) | 1153 | if (!BTRFS_I(inode)->last_trans) |
1145 | goto out; | 1154 | goto out; |
1146 | 1155 | ||
1156 | /* | ||
1157 | * if the last transaction that changed this file was before | ||
1158 | * the current transaction, we can bail out now without any | ||
1159 | * syncing | ||
1160 | */ | ||
1147 | mutex_lock(&root->fs_info->trans_mutex); | 1161 | mutex_lock(&root->fs_info->trans_mutex); |
1148 | if (BTRFS_I(inode)->last_trans <= | 1162 | if (BTRFS_I(inode)->last_trans <= |
1149 | root->fs_info->last_trans_committed) { | 1163 | root->fs_info->last_trans_committed) { |
@@ -1153,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1153 | } | 1167 | } |
1154 | mutex_unlock(&root->fs_info->trans_mutex); | 1168 | mutex_unlock(&root->fs_info->trans_mutex); |
1155 | 1169 | ||
1156 | root->log_batch++; | ||
1157 | filemap_fdatawrite(inode->i_mapping); | ||
1158 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
1159 | root->log_batch++; | ||
1160 | |||
1161 | if (datasync && !(inode->i_state & I_DIRTY_PAGES)) | ||
1162 | goto out; | ||
1163 | /* | 1170 | /* |
1164 | * ok we haven't committed the transaction yet, lets do a commit | 1171 | * ok we haven't committed the transaction yet, lets do a commit |
1165 | */ | 1172 | */ |
@@ -1188,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1188 | */ | 1195 | */ |
1189 | mutex_unlock(&dentry->d_inode->i_mutex); | 1196 | mutex_unlock(&dentry->d_inode->i_mutex); |
1190 | 1197 | ||
1191 | if (ret > 0) { | 1198 | if (ret != BTRFS_NO_LOG_SYNC) { |
1192 | ret = btrfs_commit_transaction(trans, root); | 1199 | if (ret > 0) { |
1193 | } else { | ||
1194 | ret = btrfs_sync_log(trans, root); | ||
1195 | if (ret == 0) | ||
1196 | ret = btrfs_end_transaction(trans, root); | ||
1197 | else | ||
1198 | ret = btrfs_commit_transaction(trans, root); | 1200 | ret = btrfs_commit_transaction(trans, root); |
1201 | } else { | ||
1202 | ret = btrfs_sync_log(trans, root); | ||
1203 | if (ret == 0) | ||
1204 | ret = btrfs_end_transaction(trans, root); | ||
1205 | else | ||
1206 | ret = btrfs_commit_transaction(trans, root); | ||
1207 | } | ||
1208 | } else { | ||
1209 | ret = btrfs_end_transaction(trans, root); | ||
1199 | } | 1210 | } |
1200 | mutex_lock(&dentry->d_inode->i_mutex); | 1211 | mutex_lock(&dentry->d_inode->i_mutex); |
1201 | out: | 1212 | out: |