diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 90268334145e..dc78954861b3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/writeback.h> | 29 | #include <linux/writeback.h> |
30 | #include <linux/statfs.h> | 30 | #include <linux/statfs.h> |
31 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
32 | #include <linux/version.h> | ||
33 | #include "ctree.h" | 32 | #include "ctree.h" |
34 | #include "disk-io.h" | 33 | #include "disk-io.h" |
35 | #include "transaction.h" | 34 | #include "transaction.h" |
@@ -1092,19 +1091,24 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1092 | WARN_ON(num_pages > nrptrs); | 1091 | WARN_ON(num_pages > nrptrs); |
1093 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 1092 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
1094 | 1093 | ||
1095 | ret = btrfs_check_free_space(root, write_bytes, 0); | 1094 | ret = btrfs_check_data_free_space(root, inode, write_bytes); |
1096 | if (ret) | 1095 | if (ret) |
1097 | goto out; | 1096 | goto out; |
1098 | 1097 | ||
1099 | ret = prepare_pages(root, file, pages, num_pages, | 1098 | ret = prepare_pages(root, file, pages, num_pages, |
1100 | pos, first_index, last_index, | 1099 | pos, first_index, last_index, |
1101 | write_bytes); | 1100 | write_bytes); |
1102 | if (ret) | 1101 | if (ret) { |
1102 | btrfs_free_reserved_data_space(root, inode, | ||
1103 | write_bytes); | ||
1103 | goto out; | 1104 | goto out; |
1105 | } | ||
1104 | 1106 | ||
1105 | ret = btrfs_copy_from_user(pos, num_pages, | 1107 | ret = btrfs_copy_from_user(pos, num_pages, |
1106 | write_bytes, pages, buf); | 1108 | write_bytes, pages, buf); |
1107 | if (ret) { | 1109 | if (ret) { |
1110 | btrfs_free_reserved_data_space(root, inode, | ||
1111 | write_bytes); | ||
1108 | btrfs_drop_pages(pages, num_pages); | 1112 | btrfs_drop_pages(pages, num_pages); |
1109 | goto out; | 1113 | goto out; |
1110 | } | 1114 | } |
@@ -1112,8 +1116,11 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1112 | ret = dirty_and_release_pages(NULL, root, file, pages, | 1116 | ret = dirty_and_release_pages(NULL, root, file, pages, |
1113 | num_pages, pos, write_bytes); | 1117 | num_pages, pos, write_bytes); |
1114 | btrfs_drop_pages(pages, num_pages); | 1118 | btrfs_drop_pages(pages, num_pages); |
1115 | if (ret) | 1119 | if (ret) { |
1120 | btrfs_free_reserved_data_space(root, inode, | ||
1121 | write_bytes); | ||
1116 | goto out; | 1122 | goto out; |
1123 | } | ||
1117 | 1124 | ||
1118 | if (will_write) { | 1125 | if (will_write) { |
1119 | btrfs_fdatawrite_range(inode->i_mapping, pos, | 1126 | btrfs_fdatawrite_range(inode->i_mapping, pos, |
@@ -1137,6 +1144,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1137 | } | 1144 | } |
1138 | out: | 1145 | out: |
1139 | mutex_unlock(&inode->i_mutex); | 1146 | mutex_unlock(&inode->i_mutex); |
1147 | if (ret) | ||
1148 | err = ret; | ||
1140 | 1149 | ||
1141 | out_nolock: | 1150 | out_nolock: |
1142 | kfree(pages); | 1151 | kfree(pages); |
@@ -1215,15 +1224,15 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1215 | } | 1224 | } |
1216 | mutex_unlock(&root->fs_info->trans_mutex); | 1225 | mutex_unlock(&root->fs_info->trans_mutex); |
1217 | 1226 | ||
1218 | root->fs_info->tree_log_batch++; | 1227 | root->log_batch++; |
1219 | filemap_fdatawrite(inode->i_mapping); | 1228 | filemap_fdatawrite(inode->i_mapping); |
1220 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 1229 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
1221 | root->fs_info->tree_log_batch++; | 1230 | root->log_batch++; |
1222 | 1231 | ||
1223 | /* | 1232 | /* |
1224 | * ok we haven't committed the transaction yet, lets do a commit | 1233 | * ok we haven't committed the transaction yet, lets do a commit |
1225 | */ | 1234 | */ |
1226 | if (file->private_data) | 1235 | if (file && file->private_data) |
1227 | btrfs_ioctl_trans_end(file); | 1236 | btrfs_ioctl_trans_end(file); |
1228 | 1237 | ||
1229 | trans = btrfs_start_transaction(root, 1); | 1238 | trans = btrfs_start_transaction(root, 1); |
@@ -1232,7 +1241,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1232 | goto out; | 1241 | goto out; |
1233 | } | 1242 | } |
1234 | 1243 | ||
1235 | ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); | 1244 | ret = btrfs_log_dentry_safe(trans, root, dentry); |
1236 | if (ret < 0) | 1245 | if (ret < 0) |
1237 | goto out; | 1246 | goto out; |
1238 | 1247 | ||
@@ -1246,7 +1255,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1246 | * file again, but that will end up using the synchronization | 1255 | * file again, but that will end up using the synchronization |
1247 | * inside btrfs_sync_log to keep things safe. | 1256 | * inside btrfs_sync_log to keep things safe. |
1248 | */ | 1257 | */ |
1249 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 1258 | mutex_unlock(&dentry->d_inode->i_mutex); |
1250 | 1259 | ||
1251 | if (ret > 0) { | 1260 | if (ret > 0) { |
1252 | ret = btrfs_commit_transaction(trans, root); | 1261 | ret = btrfs_commit_transaction(trans, root); |
@@ -1254,7 +1263,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1254 | btrfs_sync_log(trans, root); | 1263 | btrfs_sync_log(trans, root); |
1255 | ret = btrfs_end_transaction(trans, root); | 1264 | ret = btrfs_end_transaction(trans, root); |
1256 | } | 1265 | } |
1257 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | 1266 | mutex_lock(&dentry->d_inode->i_mutex); |
1258 | out: | 1267 | out: |
1259 | return ret > 0 ? EIO : ret; | 1268 | return ret > 0 ? EIO : ret; |
1260 | } | 1269 | } |