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, |