diff options
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 16 | 
1 files changed, 13 insertions, 3 deletions
| diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 872f104576e5..dc78954861b3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1091,19 +1091,24 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1091 | WARN_ON(num_pages > nrptrs); | 1091 | WARN_ON(num_pages > nrptrs); | 
| 1092 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 1092 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 
| 1093 | 1093 | ||
| 1094 | ret = btrfs_check_free_space(root, write_bytes, 0); | 1094 | ret = btrfs_check_data_free_space(root, inode, write_bytes); | 
| 1095 | if (ret) | 1095 | if (ret) | 
| 1096 | goto out; | 1096 | goto out; | 
| 1097 | 1097 | ||
| 1098 | ret = prepare_pages(root, file, pages, num_pages, | 1098 | ret = prepare_pages(root, file, pages, num_pages, | 
| 1099 | pos, first_index, last_index, | 1099 | pos, first_index, last_index, | 
| 1100 | write_bytes); | 1100 | write_bytes); | 
| 1101 | if (ret) | 1101 | if (ret) { | 
| 1102 | btrfs_free_reserved_data_space(root, inode, | ||
| 1103 | write_bytes); | ||
| 1102 | goto out; | 1104 | goto out; | 
| 1105 | } | ||
| 1103 | 1106 | ||
| 1104 | ret = btrfs_copy_from_user(pos, num_pages, | 1107 | ret = btrfs_copy_from_user(pos, num_pages, | 
| 1105 | write_bytes, pages, buf); | 1108 | write_bytes, pages, buf); | 
| 1106 | if (ret) { | 1109 | if (ret) { | 
| 1110 | btrfs_free_reserved_data_space(root, inode, | ||
| 1111 | write_bytes); | ||
| 1107 | btrfs_drop_pages(pages, num_pages); | 1112 | btrfs_drop_pages(pages, num_pages); | 
| 1108 | goto out; | 1113 | goto out; | 
| 1109 | } | 1114 | } | 
| @@ -1111,8 +1116,11 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1111 | ret = dirty_and_release_pages(NULL, root, file, pages, | 1116 | ret = dirty_and_release_pages(NULL, root, file, pages, | 
| 1112 | num_pages, pos, write_bytes); | 1117 | num_pages, pos, write_bytes); | 
| 1113 | btrfs_drop_pages(pages, num_pages); | 1118 | btrfs_drop_pages(pages, num_pages); | 
| 1114 | if (ret) | 1119 | if (ret) { | 
| 1120 | btrfs_free_reserved_data_space(root, inode, | ||
| 1121 | write_bytes); | ||
| 1115 | goto out; | 1122 | goto out; | 
| 1123 | } | ||
| 1116 | 1124 | ||
| 1117 | if (will_write) { | 1125 | if (will_write) { | 
| 1118 | btrfs_fdatawrite_range(inode->i_mapping, pos, | 1126 | btrfs_fdatawrite_range(inode->i_mapping, pos, | 
| @@ -1136,6 +1144,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1136 | } | 1144 | } | 
| 1137 | out: | 1145 | out: | 
| 1138 | mutex_unlock(&inode->i_mutex); | 1146 | mutex_unlock(&inode->i_mutex); | 
| 1147 | if (ret) | ||
| 1148 | err = ret; | ||
| 1139 | 1149 | ||
| 1140 | out_nolock: | 1150 | out_nolock: | 
| 1141 | kfree(pages); | 1151 | kfree(pages); | 
