diff options
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 114 |
1 files changed, 62 insertions, 52 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 4b833972273a..06550affbd27 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -112,8 +112,6 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
| 112 | int err = 0; | 112 | int err = 0; |
| 113 | int i; | 113 | int i; |
| 114 | struct inode *inode = fdentry(file)->d_inode; | 114 | struct inode *inode = fdentry(file)->d_inode; |
| 115 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | ||
| 116 | u64 hint_byte; | ||
| 117 | u64 num_bytes; | 115 | u64 num_bytes; |
| 118 | u64 start_pos; | 116 | u64 start_pos; |
| 119 | u64 end_of_last_block; | 117 | u64 end_of_last_block; |
| @@ -125,23 +123,10 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
| 125 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 123 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
| 126 | 124 | ||
| 127 | end_of_last_block = start_pos + num_bytes - 1; | 125 | end_of_last_block = start_pos + num_bytes - 1; |
| 126 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); | ||
| 127 | if (err) | ||
| 128 | return err; | ||
| 128 | 129 | ||
| 129 | lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); | ||
| 130 | trans = btrfs_join_transaction(root, 1); | ||
| 131 | if (!trans) { | ||
| 132 | err = -ENOMEM; | ||
| 133 | goto out_unlock; | ||
| 134 | } | ||
| 135 | btrfs_set_trans_block_group(trans, inode); | ||
| 136 | hint_byte = 0; | ||
| 137 | |||
| 138 | set_extent_uptodate(io_tree, start_pos, end_of_last_block, GFP_NOFS); | ||
| 139 | |||
| 140 | /* check for reserved extents on each page, we don't want | ||
| 141 | * to reset the delalloc bit on things that already have | ||
| 142 | * extents reserved. | ||
| 143 | */ | ||
| 144 | btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); | ||
| 145 | for (i = 0; i < num_pages; i++) { | 130 | for (i = 0; i < num_pages; i++) { |
| 146 | struct page *p = pages[i]; | 131 | struct page *p = pages[i]; |
| 147 | SetPageUptodate(p); | 132 | SetPageUptodate(p); |
| @@ -155,9 +140,6 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
| 155 | * at this time. | 140 | * at this time. |
| 156 | */ | 141 | */ |
| 157 | } | 142 | } |
| 158 | err = btrfs_end_transaction(trans, root); | ||
| 159 | out_unlock: | ||
| 160 | unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); | ||
| 161 | return err; | 143 | return err; |
| 162 | } | 144 | } |
| 163 | 145 | ||
| @@ -189,18 +171,18 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
| 189 | if (!split2) | 171 | if (!split2) |
| 190 | split2 = alloc_extent_map(GFP_NOFS); | 172 | split2 = alloc_extent_map(GFP_NOFS); |
| 191 | 173 | ||
| 192 | spin_lock(&em_tree->lock); | 174 | write_lock(&em_tree->lock); |
| 193 | em = lookup_extent_mapping(em_tree, start, len); | 175 | em = lookup_extent_mapping(em_tree, start, len); |
| 194 | if (!em) { | 176 | if (!em) { |
| 195 | spin_unlock(&em_tree->lock); | 177 | write_unlock(&em_tree->lock); |
| 196 | break; | 178 | break; |
| 197 | } | 179 | } |
| 198 | flags = em->flags; | 180 | flags = em->flags; |
| 199 | if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { | 181 | if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { |
| 200 | spin_unlock(&em_tree->lock); | ||
| 201 | if (em->start <= start && | 182 | if (em->start <= start && |
| 202 | (!testend || em->start + em->len >= start + len)) { | 183 | (!testend || em->start + em->len >= start + len)) { |
| 203 | free_extent_map(em); | 184 | free_extent_map(em); |
| 185 | write_unlock(&em_tree->lock); | ||
| 204 | break; | 186 | break; |
| 205 | } | 187 | } |
| 206 | if (start < em->start) { | 188 | if (start < em->start) { |
| @@ -210,6 +192,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
| 210 | start = em->start + em->len; | 192 | start = em->start + em->len; |
| 211 | } | 193 | } |
| 212 | free_extent_map(em); | 194 | free_extent_map(em); |
| 195 | write_unlock(&em_tree->lock); | ||
| 213 | continue; | 196 | continue; |
| 214 | } | 197 | } |
| 215 | compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 198 | compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
| @@ -260,7 +243,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
| 260 | free_extent_map(split); | 243 | free_extent_map(split); |
| 261 | split = NULL; | 244 | split = NULL; |
| 262 | } | 245 | } |
| 263 | spin_unlock(&em_tree->lock); | 246 | write_unlock(&em_tree->lock); |
| 264 | 247 | ||
| 265 | /* once for us */ | 248 | /* once for us */ |
| 266 | free_extent_map(em); | 249 | free_extent_map(em); |
| @@ -289,7 +272,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
| 289 | noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, | 272 | noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, |
| 290 | struct btrfs_root *root, struct inode *inode, | 273 | struct btrfs_root *root, struct inode *inode, |
| 291 | u64 start, u64 end, u64 locked_end, | 274 | u64 start, u64 end, u64 locked_end, |
| 292 | u64 inline_limit, u64 *hint_byte) | 275 | u64 inline_limit, u64 *hint_byte, int drop_cache) |
| 293 | { | 276 | { |
| 294 | u64 extent_end = 0; | 277 | u64 extent_end = 0; |
| 295 | u64 search_start = start; | 278 | u64 search_start = start; |
| @@ -314,7 +297,8 @@ noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
| 314 | int ret; | 297 | int ret; |
| 315 | 298 | ||
| 316 | inline_limit = 0; | 299 | inline_limit = 0; |
| 317 | btrfs_drop_extent_cache(inode, start, end - 1, 0); | 300 | if (drop_cache) |
| 301 | btrfs_drop_extent_cache(inode, start, end - 1, 0); | ||
| 318 | 302 | ||
| 319 | path = btrfs_alloc_path(); | 303 | path = btrfs_alloc_path(); |
| 320 | if (!path) | 304 | if (!path) |
| @@ -894,7 +878,8 @@ again: | |||
| 894 | btrfs_put_ordered_extent(ordered); | 878 | btrfs_put_ordered_extent(ordered); |
| 895 | 879 | ||
| 896 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, | 880 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, |
| 897 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC, | 881 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
| 882 | EXTENT_DO_ACCOUNTING, | ||
| 898 | GFP_NOFS); | 883 | GFP_NOFS); |
| 899 | unlock_extent(&BTRFS_I(inode)->io_tree, | 884 | unlock_extent(&BTRFS_I(inode)->io_tree, |
| 900 | start_pos, last_pos - 1, GFP_NOFS); | 885 | start_pos, last_pos - 1, GFP_NOFS); |
| @@ -936,21 +921,35 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 936 | start_pos = pos; | 921 | start_pos = pos; |
| 937 | 922 | ||
| 938 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); | 923 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); |
| 924 | |||
| 925 | /* do the reserve before the mutex lock in case we have to do some | ||
| 926 | * flushing. We wouldn't deadlock, but this is more polite. | ||
| 927 | */ | ||
| 928 | err = btrfs_reserve_metadata_for_delalloc(root, inode, 1); | ||
| 929 | if (err) | ||
| 930 | goto out_nolock; | ||
| 931 | |||
| 932 | mutex_lock(&inode->i_mutex); | ||
| 933 | |||
| 939 | current->backing_dev_info = inode->i_mapping->backing_dev_info; | 934 | current->backing_dev_info = inode->i_mapping->backing_dev_info; |
| 940 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); | 935 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); |
| 941 | if (err) | 936 | if (err) |
| 942 | goto out_nolock; | 937 | goto out; |
| 938 | |||
| 943 | if (count == 0) | 939 | if (count == 0) |
| 944 | goto out_nolock; | 940 | goto out; |
| 945 | 941 | ||
| 946 | err = file_remove_suid(file); | 942 | err = file_remove_suid(file); |
| 947 | if (err) | 943 | if (err) |
| 948 | goto out_nolock; | 944 | goto out; |
| 945 | |||
| 949 | file_update_time(file); | 946 | file_update_time(file); |
| 950 | 947 | ||
| 951 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); | 948 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); |
| 952 | 949 | ||
| 953 | mutex_lock(&inode->i_mutex); | 950 | /* generic_write_checks can change our pos */ |
| 951 | start_pos = pos; | ||
| 952 | |||
| 954 | BTRFS_I(inode)->sequence++; | 953 | BTRFS_I(inode)->sequence++; |
| 955 | first_index = pos >> PAGE_CACHE_SHIFT; | 954 | first_index = pos >> PAGE_CACHE_SHIFT; |
| 956 | last_index = (pos + count) >> PAGE_CACHE_SHIFT; | 955 | last_index = (pos + count) >> PAGE_CACHE_SHIFT; |
| @@ -1024,9 +1023,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1024 | } | 1023 | } |
| 1025 | 1024 | ||
| 1026 | if (will_write) { | 1025 | if (will_write) { |
| 1027 | btrfs_fdatawrite_range(inode->i_mapping, pos, | 1026 | filemap_fdatawrite_range(inode->i_mapping, pos, |
| 1028 | pos + write_bytes - 1, | 1027 | pos + write_bytes - 1); |
| 1029 | WB_SYNC_ALL); | ||
| 1030 | } else { | 1028 | } else { |
| 1031 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, | 1029 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, |
| 1032 | num_pages); | 1030 | num_pages); |
| @@ -1047,6 +1045,7 @@ out: | |||
| 1047 | mutex_unlock(&inode->i_mutex); | 1045 | mutex_unlock(&inode->i_mutex); |
| 1048 | if (ret) | 1046 | if (ret) |
| 1049 | err = ret; | 1047 | err = ret; |
| 1048 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
| 1050 | 1049 | ||
| 1051 | out_nolock: | 1050 | out_nolock: |
| 1052 | kfree(pages); | 1051 | kfree(pages); |
| @@ -1087,8 +1086,10 @@ out_nolock: | |||
| 1087 | btrfs_end_transaction(trans, root); | 1086 | btrfs_end_transaction(trans, root); |
| 1088 | else | 1087 | else |
| 1089 | btrfs_commit_transaction(trans, root); | 1088 | btrfs_commit_transaction(trans, root); |
| 1090 | } else { | 1089 | } else if (ret != BTRFS_NO_LOG_SYNC) { |
| 1091 | btrfs_commit_transaction(trans, root); | 1090 | btrfs_commit_transaction(trans, root); |
| 1091 | } else { | ||
| 1092 | btrfs_end_transaction(trans, root); | ||
| 1092 | } | 1093 | } |
| 1093 | } | 1094 | } |
| 1094 | if (file->f_flags & O_DIRECT) { | 1095 | if (file->f_flags & O_DIRECT) { |
| @@ -1138,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1138 | int ret = 0; | 1139 | int ret = 0; |
| 1139 | struct btrfs_trans_handle *trans; | 1140 | struct btrfs_trans_handle *trans; |
| 1140 | 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 | |||
| 1141 | /* | 1149 | /* |
| 1142 | * check the transaction that last modified this inode | 1150 | * check the transaction that last modified this inode |
| 1143 | * and see if its already been committed | 1151 | * and see if its already been committed |
| @@ -1145,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1145 | if (!BTRFS_I(inode)->last_trans) | 1153 | if (!BTRFS_I(inode)->last_trans) |
| 1146 | goto out; | 1154 | goto out; |
| 1147 | 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 | */ | ||
| 1148 | mutex_lock(&root->fs_info->trans_mutex); | 1161 | mutex_lock(&root->fs_info->trans_mutex); |
| 1149 | if (BTRFS_I(inode)->last_trans <= | 1162 | if (BTRFS_I(inode)->last_trans <= |
| 1150 | root->fs_info->last_trans_committed) { | 1163 | root->fs_info->last_trans_committed) { |
| @@ -1154,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1154 | } | 1167 | } |
| 1155 | mutex_unlock(&root->fs_info->trans_mutex); | 1168 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1156 | 1169 | ||
| 1157 | root->log_batch++; | ||
| 1158 | filemap_fdatawrite(inode->i_mapping); | ||
| 1159 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
| 1160 | root->log_batch++; | ||
| 1161 | |||
| 1162 | if (datasync && !(inode->i_state & I_DIRTY_PAGES)) | ||
| 1163 | goto out; | ||
| 1164 | /* | 1170 | /* |
| 1165 | * 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 |
| 1166 | */ | 1172 | */ |
| @@ -1189,21 +1195,25 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1189 | */ | 1195 | */ |
| 1190 | mutex_unlock(&dentry->d_inode->i_mutex); | 1196 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1191 | 1197 | ||
| 1192 | if (ret > 0) { | 1198 | if (ret != BTRFS_NO_LOG_SYNC) { |
| 1193 | ret = btrfs_commit_transaction(trans, root); | 1199 | if (ret > 0) { |
| 1194 | } else { | ||
| 1195 | ret = btrfs_sync_log(trans, root); | ||
| 1196 | if (ret == 0) | ||
| 1197 | ret = btrfs_end_transaction(trans, root); | ||
| 1198 | else | ||
| 1199 | 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); | ||
| 1200 | } | 1210 | } |
| 1201 | mutex_lock(&dentry->d_inode->i_mutex); | 1211 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1202 | out: | 1212 | out: |
| 1203 | return ret > 0 ? EIO : ret; | 1213 | return ret > 0 ? EIO : ret; |
| 1204 | } | 1214 | } |
| 1205 | 1215 | ||
| 1206 | static struct vm_operations_struct btrfs_file_vm_ops = { | 1216 | static const struct vm_operations_struct btrfs_file_vm_ops = { |
| 1207 | .fault = filemap_fault, | 1217 | .fault = filemap_fault, |
| 1208 | .page_mkwrite = btrfs_page_mkwrite, | 1218 | .page_mkwrite = btrfs_page_mkwrite, |
| 1209 | }; | 1219 | }; |
| @@ -1215,7 +1225,7 @@ static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 1215 | return 0; | 1225 | return 0; |
| 1216 | } | 1226 | } |
| 1217 | 1227 | ||
| 1218 | struct file_operations btrfs_file_operations = { | 1228 | const struct file_operations btrfs_file_operations = { |
| 1219 | .llseek = generic_file_llseek, | 1229 | .llseek = generic_file_llseek, |
| 1220 | .read = do_sync_read, | 1230 | .read = do_sync_read, |
| 1221 | .aio_read = generic_file_aio_read, | 1231 | .aio_read = generic_file_aio_read, |
