aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c74
1 files changed, 61 insertions, 13 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 3e8023efaff7..9c9fb46ccd08 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -606,6 +606,7 @@ next_slot:
606 btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); 606 btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY);
607 607
608 btrfs_release_path(root, path); 608 btrfs_release_path(root, path);
609 path->leave_spinning = 1;
609 ret = btrfs_insert_empty_item(trans, root, path, &ins, 610 ret = btrfs_insert_empty_item(trans, root, path, &ins,
610 sizeof(*extent)); 611 sizeof(*extent));
611 BUG_ON(ret); 612 BUG_ON(ret);
@@ -639,17 +640,22 @@ next_slot:
639 ram_bytes); 640 ram_bytes);
640 btrfs_set_file_extent_type(leaf, extent, found_type); 641 btrfs_set_file_extent_type(leaf, extent, found_type);
641 642
643 btrfs_unlock_up_safe(path, 1);
642 btrfs_mark_buffer_dirty(path->nodes[0]); 644 btrfs_mark_buffer_dirty(path->nodes[0]);
645 btrfs_set_lock_blocking(path->nodes[0]);
643 646
644 if (disk_bytenr != 0) { 647 if (disk_bytenr != 0) {
645 ret = btrfs_update_extent_ref(trans, root, 648 ret = btrfs_update_extent_ref(trans, root,
646 disk_bytenr, orig_parent, 649 disk_bytenr,
650 le64_to_cpu(old.disk_num_bytes),
651 orig_parent,
647 leaf->start, 652 leaf->start,
648 root->root_key.objectid, 653 root->root_key.objectid,
649 trans->transid, ins.objectid); 654 trans->transid, ins.objectid);
650 655
651 BUG_ON(ret); 656 BUG_ON(ret);
652 } 657 }
658 path->leave_spinning = 0;
653 btrfs_release_path(root, path); 659 btrfs_release_path(root, path);
654 if (disk_bytenr != 0) 660 if (disk_bytenr != 0)
655 inode_add_bytes(inode, extent_end - end); 661 inode_add_bytes(inode, extent_end - end);
@@ -912,7 +918,7 @@ again:
912 btrfs_set_file_extent_other_encoding(leaf, fi, 0); 918 btrfs_set_file_extent_other_encoding(leaf, fi, 0);
913 919
914 if (orig_parent != leaf->start) { 920 if (orig_parent != leaf->start) {
915 ret = btrfs_update_extent_ref(trans, root, bytenr, 921 ret = btrfs_update_extent_ref(trans, root, bytenr, num_bytes,
916 orig_parent, leaf->start, 922 orig_parent, leaf->start,
917 root->root_key.objectid, 923 root->root_key.objectid,
918 trans->transid, inode->i_ino); 924 trans->transid, inode->i_ino);
@@ -1091,19 +1097,24 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1091 WARN_ON(num_pages > nrptrs); 1097 WARN_ON(num_pages > nrptrs);
1092 memset(pages, 0, sizeof(struct page *) * nrptrs); 1098 memset(pages, 0, sizeof(struct page *) * nrptrs);
1093 1099
1094 ret = btrfs_check_free_space(root, write_bytes, 0); 1100 ret = btrfs_check_data_free_space(root, inode, write_bytes);
1095 if (ret) 1101 if (ret)
1096 goto out; 1102 goto out;
1097 1103
1098 ret = prepare_pages(root, file, pages, num_pages, 1104 ret = prepare_pages(root, file, pages, num_pages,
1099 pos, first_index, last_index, 1105 pos, first_index, last_index,
1100 write_bytes); 1106 write_bytes);
1101 if (ret) 1107 if (ret) {
1108 btrfs_free_reserved_data_space(root, inode,
1109 write_bytes);
1102 goto out; 1110 goto out;
1111 }
1103 1112
1104 ret = btrfs_copy_from_user(pos, num_pages, 1113 ret = btrfs_copy_from_user(pos, num_pages,
1105 write_bytes, pages, buf); 1114 write_bytes, pages, buf);
1106 if (ret) { 1115 if (ret) {
1116 btrfs_free_reserved_data_space(root, inode,
1117 write_bytes);
1107 btrfs_drop_pages(pages, num_pages); 1118 btrfs_drop_pages(pages, num_pages);
1108 goto out; 1119 goto out;
1109 } 1120 }
@@ -1111,8 +1122,11 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1111 ret = dirty_and_release_pages(NULL, root, file, pages, 1122 ret = dirty_and_release_pages(NULL, root, file, pages,
1112 num_pages, pos, write_bytes); 1123 num_pages, pos, write_bytes);
1113 btrfs_drop_pages(pages, num_pages); 1124 btrfs_drop_pages(pages, num_pages);
1114 if (ret) 1125 if (ret) {
1126 btrfs_free_reserved_data_space(root, inode,
1127 write_bytes);
1115 goto out; 1128 goto out;
1129 }
1116 1130
1117 if (will_write) { 1131 if (will_write) {
1118 btrfs_fdatawrite_range(inode->i_mapping, pos, 1132 btrfs_fdatawrite_range(inode->i_mapping, pos,
@@ -1136,6 +1150,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1136 } 1150 }
1137out: 1151out:
1138 mutex_unlock(&inode->i_mutex); 1152 mutex_unlock(&inode->i_mutex);
1153 if (ret)
1154 err = ret;
1139 1155
1140out_nolock: 1156out_nolock:
1141 kfree(pages); 1157 kfree(pages);
@@ -1145,6 +1161,20 @@ out_nolock:
1145 page_cache_release(pinned[1]); 1161 page_cache_release(pinned[1]);
1146 *ppos = pos; 1162 *ppos = pos;
1147 1163
1164 /*
1165 * we want to make sure fsync finds this change
1166 * but we haven't joined a transaction running right now.
1167 *
1168 * Later on, someone is sure to update the inode and get the
1169 * real transid recorded.
1170 *
1171 * We set last_trans now to the fs_info generation + 1,
1172 * this will either be one more than the running transaction
1173 * or the generation used for the next transaction if there isn't
1174 * one running right now.
1175 */
1176 BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
1177
1148 if (num_written > 0 && will_write) { 1178 if (num_written > 0 && will_write) {
1149 struct btrfs_trans_handle *trans; 1179 struct btrfs_trans_handle *trans;
1150 1180
@@ -1157,8 +1187,11 @@ out_nolock:
1157 ret = btrfs_log_dentry_safe(trans, root, 1187 ret = btrfs_log_dentry_safe(trans, root,
1158 file->f_dentry); 1188 file->f_dentry);
1159 if (ret == 0) { 1189 if (ret == 0) {
1160 btrfs_sync_log(trans, root); 1190 ret = btrfs_sync_log(trans, root);
1161 btrfs_end_transaction(trans, root); 1191 if (ret == 0)
1192 btrfs_end_transaction(trans, root);
1193 else
1194 btrfs_commit_transaction(trans, root);
1162 } else { 1195 } else {
1163 btrfs_commit_transaction(trans, root); 1196 btrfs_commit_transaction(trans, root);
1164 } 1197 }
@@ -1175,6 +1208,18 @@ out_nolock:
1175 1208
1176int btrfs_release_file(struct inode *inode, struct file *filp) 1209int btrfs_release_file(struct inode *inode, struct file *filp)
1177{ 1210{
1211 /*
1212 * ordered_data_close is set by settattr when we are about to truncate
1213 * a file from a non-zero size to a zero size. This tries to
1214 * flush down new bytes that may have been written if the
1215 * application were using truncate to replace a file in place.
1216 */
1217 if (BTRFS_I(inode)->ordered_data_close) {
1218 BTRFS_I(inode)->ordered_data_close = 0;
1219 btrfs_add_ordered_operation(NULL, BTRFS_I(inode)->root, inode);
1220 if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT)
1221 filemap_flush(inode->i_mapping);
1222 }
1178 if (filp->private_data) 1223 if (filp->private_data)
1179 btrfs_ioctl_trans_end(filp); 1224 btrfs_ioctl_trans_end(filp);
1180 return 0; 1225 return 0;
@@ -1222,7 +1267,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1222 /* 1267 /*
1223 * ok we haven't committed the transaction yet, lets do a commit 1268 * ok we haven't committed the transaction yet, lets do a commit
1224 */ 1269 */
1225 if (file->private_data) 1270 if (file && file->private_data)
1226 btrfs_ioctl_trans_end(file); 1271 btrfs_ioctl_trans_end(file);
1227 1272
1228 trans = btrfs_start_transaction(root, 1); 1273 trans = btrfs_start_transaction(root, 1);
@@ -1231,7 +1276,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1231 goto out; 1276 goto out;
1232 } 1277 }
1233 1278
1234 ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); 1279 ret = btrfs_log_dentry_safe(trans, root, dentry);
1235 if (ret < 0) 1280 if (ret < 0)
1236 goto out; 1281 goto out;
1237 1282
@@ -1245,15 +1290,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1245 * file again, but that will end up using the synchronization 1290 * file again, but that will end up using the synchronization
1246 * inside btrfs_sync_log to keep things safe. 1291 * inside btrfs_sync_log to keep things safe.
1247 */ 1292 */
1248 mutex_unlock(&file->f_dentry->d_inode->i_mutex); 1293 mutex_unlock(&dentry->d_inode->i_mutex);
1249 1294
1250 if (ret > 0) { 1295 if (ret > 0) {
1251 ret = btrfs_commit_transaction(trans, root); 1296 ret = btrfs_commit_transaction(trans, root);
1252 } else { 1297 } else {
1253 btrfs_sync_log(trans, root); 1298 ret = btrfs_sync_log(trans, root);
1254 ret = btrfs_end_transaction(trans, root); 1299 if (ret == 0)
1300 ret = btrfs_end_transaction(trans, root);
1301 else
1302 ret = btrfs_commit_transaction(trans, root);
1255 } 1303 }
1256 mutex_lock(&file->f_dentry->d_inode->i_mutex); 1304 mutex_lock(&dentry->d_inode->i_mutex);
1257out: 1305out:
1258 return ret > 0 ? EIO : ret; 1306 return ret > 0 ? EIO : ret;
1259} 1307}