diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f19e1259a971..06550affbd27 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -878,7 +878,8 @@ again: | |||
878 | btrfs_put_ordered_extent(ordered); | 878 | btrfs_put_ordered_extent(ordered); |
879 | 879 | ||
880 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, | 880 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, |
881 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC, | 881 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
882 | EXTENT_DO_ACCOUNTING, | ||
882 | GFP_NOFS); | 883 | GFP_NOFS); |
883 | unlock_extent(&BTRFS_I(inode)->io_tree, | 884 | unlock_extent(&BTRFS_I(inode)->io_tree, |
884 | start_pos, last_pos - 1, GFP_NOFS); | 885 | start_pos, last_pos - 1, GFP_NOFS); |
@@ -1085,8 +1086,10 @@ out_nolock: | |||
1085 | btrfs_end_transaction(trans, root); | 1086 | btrfs_end_transaction(trans, root); |
1086 | else | 1087 | else |
1087 | btrfs_commit_transaction(trans, root); | 1088 | btrfs_commit_transaction(trans, root); |
1088 | } else { | 1089 | } else if (ret != BTRFS_NO_LOG_SYNC) { |
1089 | btrfs_commit_transaction(trans, root); | 1090 | btrfs_commit_transaction(trans, root); |
1091 | } else { | ||
1092 | btrfs_end_transaction(trans, root); | ||
1090 | } | 1093 | } |
1091 | } | 1094 | } |
1092 | if (file->f_flags & O_DIRECT) { | 1095 | if (file->f_flags & O_DIRECT) { |
@@ -1136,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1136 | int ret = 0; | 1139 | int ret = 0; |
1137 | struct btrfs_trans_handle *trans; | 1140 | struct btrfs_trans_handle *trans; |
1138 | 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 | |||
1139 | /* | 1149 | /* |
1140 | * check the transaction that last modified this inode | 1150 | * check the transaction that last modified this inode |
1141 | * and see if its already been committed | 1151 | * and see if its already been committed |
@@ -1143,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1143 | if (!BTRFS_I(inode)->last_trans) | 1153 | if (!BTRFS_I(inode)->last_trans) |
1144 | goto out; | 1154 | goto out; |
1145 | 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 | */ | ||
1146 | mutex_lock(&root->fs_info->trans_mutex); | 1161 | mutex_lock(&root->fs_info->trans_mutex); |
1147 | if (BTRFS_I(inode)->last_trans <= | 1162 | if (BTRFS_I(inode)->last_trans <= |
1148 | root->fs_info->last_trans_committed) { | 1163 | root->fs_info->last_trans_committed) { |
@@ -1152,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1152 | } | 1167 | } |
1153 | mutex_unlock(&root->fs_info->trans_mutex); | 1168 | mutex_unlock(&root->fs_info->trans_mutex); |
1154 | 1169 | ||
1155 | root->log_batch++; | ||
1156 | filemap_fdatawrite(inode->i_mapping); | ||
1157 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
1158 | root->log_batch++; | ||
1159 | |||
1160 | if (datasync && !(inode->i_state & I_DIRTY_PAGES)) | ||
1161 | goto out; | ||
1162 | /* | 1170 | /* |
1163 | * 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 |
1164 | */ | 1172 | */ |
@@ -1187,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1187 | */ | 1195 | */ |
1188 | mutex_unlock(&dentry->d_inode->i_mutex); | 1196 | mutex_unlock(&dentry->d_inode->i_mutex); |
1189 | 1197 | ||
1190 | if (ret > 0) { | 1198 | if (ret != BTRFS_NO_LOG_SYNC) { |
1191 | ret = btrfs_commit_transaction(trans, root); | 1199 | if (ret > 0) { |
1192 | } else { | ||
1193 | ret = btrfs_sync_log(trans, root); | ||
1194 | if (ret == 0) | ||
1195 | ret = btrfs_end_transaction(trans, root); | ||
1196 | else | ||
1197 | 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); | ||
1198 | } | 1210 | } |
1199 | mutex_lock(&dentry->d_inode->i_mutex); | 1211 | mutex_lock(&dentry->d_inode->i_mutex); |
1200 | out: | 1212 | out: |