aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c128
1 files changed, 98 insertions, 30 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 5c2a9e78a949..e56c72bc5add 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -16,7 +16,6 @@
16 * Boston, MA 021110-1307, USA. 16 * Boston, MA 021110-1307, USA.
17 */ 17 */
18 18
19#include <linux/gfp.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/blkdev.h> 20#include <linux/blkdev.h>
22#include <linux/writeback.h> 21#include <linux/writeback.h>
@@ -125,6 +124,15 @@ static int offset_in_entry(struct btrfs_ordered_extent *entry, u64 file_offset)
125 return 1; 124 return 1;
126} 125}
127 126
127static int range_overlaps(struct btrfs_ordered_extent *entry, u64 file_offset,
128 u64 len)
129{
130 if (file_offset + len <= entry->file_offset ||
131 entry->file_offset + entry->len <= file_offset)
132 return 0;
133 return 1;
134}
135
128/* 136/*
129 * look find the first ordered struct that has this offset, otherwise 137 * look find the first ordered struct that has this offset, otherwise
130 * the first one less than this offset 138 * the first one less than this offset
@@ -162,8 +170,9 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,
162 * The tree is given a single reference on the ordered extent that was 170 * The tree is given a single reference on the ordered extent that was
163 * inserted. 171 * inserted.
164 */ 172 */
165int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, 173static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
166 u64 start, u64 len, u64 disk_len, int type) 174 u64 start, u64 len, u64 disk_len,
175 int type, int dio)
167{ 176{
168 struct btrfs_ordered_inode_tree *tree; 177 struct btrfs_ordered_inode_tree *tree;
169 struct rb_node *node; 178 struct rb_node *node;
@@ -174,7 +183,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
174 if (!entry) 183 if (!entry)
175 return -ENOMEM; 184 return -ENOMEM;
176 185
177 mutex_lock(&tree->mutex);
178 entry->file_offset = file_offset; 186 entry->file_offset = file_offset;
179 entry->start = start; 187 entry->start = start;
180 entry->len = len; 188 entry->len = len;
@@ -184,26 +192,44 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
184 if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) 192 if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)
185 set_bit(type, &entry->flags); 193 set_bit(type, &entry->flags);
186 194
195 if (dio)
196 set_bit(BTRFS_ORDERED_DIRECT, &entry->flags);
197
187 /* one ref for the tree */ 198 /* one ref for the tree */
188 atomic_set(&entry->refs, 1); 199 atomic_set(&entry->refs, 1);
189 init_waitqueue_head(&entry->wait); 200 init_waitqueue_head(&entry->wait);
190 INIT_LIST_HEAD(&entry->list); 201 INIT_LIST_HEAD(&entry->list);
191 INIT_LIST_HEAD(&entry->root_extent_list); 202 INIT_LIST_HEAD(&entry->root_extent_list);
192 203
204 spin_lock(&tree->lock);
193 node = tree_insert(&tree->tree, file_offset, 205 node = tree_insert(&tree->tree, file_offset,
194 &entry->rb_node); 206 &entry->rb_node);
195 BUG_ON(node); 207 BUG_ON(node);
208 spin_unlock(&tree->lock);
196 209
197 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); 210 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
198 list_add_tail(&entry->root_extent_list, 211 list_add_tail(&entry->root_extent_list,
199 &BTRFS_I(inode)->root->fs_info->ordered_extents); 212 &BTRFS_I(inode)->root->fs_info->ordered_extents);
200 spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); 213 spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
201 214
202 mutex_unlock(&tree->mutex);
203 BUG_ON(node); 215 BUG_ON(node);
204 return 0; 216 return 0;
205} 217}
206 218
219int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
220 u64 start, u64 len, u64 disk_len, int type)
221{
222 return __btrfs_add_ordered_extent(inode, file_offset, start, len,
223 disk_len, type, 0);
224}
225
226int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,
227 u64 start, u64 len, u64 disk_len, int type)
228{
229 return __btrfs_add_ordered_extent(inode, file_offset, start, len,
230 disk_len, type, 1);
231}
232
207/* 233/*
208 * Add a struct btrfs_ordered_sum into the list of checksums to be inserted 234 * Add a struct btrfs_ordered_sum into the list of checksums to be inserted
209 * when an ordered extent is finished. If the list covers more than one 235 * when an ordered extent is finished. If the list covers more than one
@@ -216,9 +242,9 @@ int btrfs_add_ordered_sum(struct inode *inode,
216 struct btrfs_ordered_inode_tree *tree; 242 struct btrfs_ordered_inode_tree *tree;
217 243
218 tree = &BTRFS_I(inode)->ordered_tree; 244 tree = &BTRFS_I(inode)->ordered_tree;
219 mutex_lock(&tree->mutex); 245 spin_lock(&tree->lock);
220 list_add_tail(&sum->list, &entry->list); 246 list_add_tail(&sum->list, &entry->list);
221 mutex_unlock(&tree->mutex); 247 spin_unlock(&tree->lock);
222 return 0; 248 return 0;
223} 249}
224 250
@@ -232,15 +258,16 @@ int btrfs_add_ordered_sum(struct inode *inode,
232 * to make sure this function only returns 1 once for a given ordered extent. 258 * to make sure this function only returns 1 once for a given ordered extent.
233 */ 259 */
234int btrfs_dec_test_ordered_pending(struct inode *inode, 260int btrfs_dec_test_ordered_pending(struct inode *inode,
261 struct btrfs_ordered_extent **cached,
235 u64 file_offset, u64 io_size) 262 u64 file_offset, u64 io_size)
236{ 263{
237 struct btrfs_ordered_inode_tree *tree; 264 struct btrfs_ordered_inode_tree *tree;
238 struct rb_node *node; 265 struct rb_node *node;
239 struct btrfs_ordered_extent *entry; 266 struct btrfs_ordered_extent *entry = NULL;
240 int ret; 267 int ret;
241 268
242 tree = &BTRFS_I(inode)->ordered_tree; 269 tree = &BTRFS_I(inode)->ordered_tree;
243 mutex_lock(&tree->mutex); 270 spin_lock(&tree->lock);
244 node = tree_search(tree, file_offset); 271 node = tree_search(tree, file_offset);
245 if (!node) { 272 if (!node) {
246 ret = 1; 273 ret = 1;
@@ -264,7 +291,11 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
264 else 291 else
265 ret = 1; 292 ret = 1;
266out: 293out:
267 mutex_unlock(&tree->mutex); 294 if (!ret && cached && entry) {
295 *cached = entry;
296 atomic_inc(&entry->refs);
297 }
298 spin_unlock(&tree->lock);
268 return ret == 0; 299 return ret == 0;
269} 300}
270 301
@@ -291,13 +322,14 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
291 322
292/* 323/*
293 * remove an ordered extent from the tree. No references are dropped 324 * remove an ordered extent from the tree. No references are dropped
294 * and you must wake_up entry->wait. You must hold the tree mutex 325 * and you must wake_up entry->wait. You must hold the tree lock
295 * while you call this function. 326 * while you call this function.
296 */ 327 */
297static int __btrfs_remove_ordered_extent(struct inode *inode, 328static int __btrfs_remove_ordered_extent(struct inode *inode,
298 struct btrfs_ordered_extent *entry) 329 struct btrfs_ordered_extent *entry)
299{ 330{
300 struct btrfs_ordered_inode_tree *tree; 331 struct btrfs_ordered_inode_tree *tree;
332 struct btrfs_root *root = BTRFS_I(inode)->root;
301 struct rb_node *node; 333 struct rb_node *node;
302 334
303 tree = &BTRFS_I(inode)->ordered_tree; 335 tree = &BTRFS_I(inode)->ordered_tree;
@@ -306,13 +338,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
306 tree->last = NULL; 338 tree->last = NULL;
307 set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); 339 set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
308 340
309 spin_lock(&BTRFS_I(inode)->accounting_lock); 341 spin_lock(&root->fs_info->ordered_extent_lock);
310 BTRFS_I(inode)->outstanding_extents--;
311 spin_unlock(&BTRFS_I(inode)->accounting_lock);
312 btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root,
313 inode, 1);
314
315 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
316 list_del_init(&entry->root_extent_list); 342 list_del_init(&entry->root_extent_list);
317 343
318 /* 344 /*
@@ -324,7 +350,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
324 !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { 350 !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) {
325 list_del_init(&BTRFS_I(inode)->ordered_operations); 351 list_del_init(&BTRFS_I(inode)->ordered_operations);
326 } 352 }
327 spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); 353 spin_unlock(&root->fs_info->ordered_extent_lock);
328 354
329 return 0; 355 return 0;
330} 356}
@@ -340,9 +366,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
340 int ret; 366 int ret;
341 367
342 tree = &BTRFS_I(inode)->ordered_tree; 368 tree = &BTRFS_I(inode)->ordered_tree;
343 mutex_lock(&tree->mutex); 369 spin_lock(&tree->lock);
344 ret = __btrfs_remove_ordered_extent(inode, entry); 370 ret = __btrfs_remove_ordered_extent(inode, entry);
345 mutex_unlock(&tree->mutex); 371 spin_unlock(&tree->lock);
346 wake_up(&entry->wait); 372 wake_up(&entry->wait);
347 373
348 return ret; 374 return ret;
@@ -485,7 +511,8 @@ void btrfs_start_ordered_extent(struct inode *inode,
485 * start IO on any dirty ones so the wait doesn't stall waiting 511 * start IO on any dirty ones so the wait doesn't stall waiting
486 * for pdflush to find them 512 * for pdflush to find them
487 */ 513 */
488 filemap_fdatawrite_range(inode->i_mapping, start, end); 514 if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags))
515 filemap_fdatawrite_range(inode->i_mapping, start, end);
489 if (wait) { 516 if (wait) {
490 wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE, 517 wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE,
491 &entry->flags)); 518 &entry->flags));
@@ -567,7 +594,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
567 struct btrfs_ordered_extent *entry = NULL; 594 struct btrfs_ordered_extent *entry = NULL;
568 595
569 tree = &BTRFS_I(inode)->ordered_tree; 596 tree = &BTRFS_I(inode)->ordered_tree;
570 mutex_lock(&tree->mutex); 597 spin_lock(&tree->lock);
571 node = tree_search(tree, file_offset); 598 node = tree_search(tree, file_offset);
572 if (!node) 599 if (!node)
573 goto out; 600 goto out;
@@ -578,7 +605,48 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
578 if (entry) 605 if (entry)
579 atomic_inc(&entry->refs); 606 atomic_inc(&entry->refs);
580out: 607out:
581 mutex_unlock(&tree->mutex); 608 spin_unlock(&tree->lock);
609 return entry;
610}
611
612/* Since the DIO code tries to lock a wide area we need to look for any ordered
613 * extents that exist in the range, rather than just the start of the range.
614 */
615struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode,
616 u64 file_offset,
617 u64 len)
618{
619 struct btrfs_ordered_inode_tree *tree;
620 struct rb_node *node;
621 struct btrfs_ordered_extent *entry = NULL;
622
623 tree = &BTRFS_I(inode)->ordered_tree;
624 spin_lock(&tree->lock);
625 node = tree_search(tree, file_offset);
626 if (!node) {
627 node = tree_search(tree, file_offset + len);
628 if (!node)
629 goto out;
630 }
631
632 while (1) {
633 entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
634 if (range_overlaps(entry, file_offset, len))
635 break;
636
637 if (entry->file_offset >= file_offset + len) {
638 entry = NULL;
639 break;
640 }
641 entry = NULL;
642 node = rb_next(node);
643 if (!node)
644 break;
645 }
646out:
647 if (entry)
648 atomic_inc(&entry->refs);
649 spin_unlock(&tree->lock);
582 return entry; 650 return entry;
583} 651}
584 652
@@ -594,7 +662,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
594 struct btrfs_ordered_extent *entry = NULL; 662 struct btrfs_ordered_extent *entry = NULL;
595 663
596 tree = &BTRFS_I(inode)->ordered_tree; 664 tree = &BTRFS_I(inode)->ordered_tree;
597 mutex_lock(&tree->mutex); 665 spin_lock(&tree->lock);
598 node = tree_search(tree, file_offset); 666 node = tree_search(tree, file_offset);
599 if (!node) 667 if (!node)
600 goto out; 668 goto out;
@@ -602,7 +670,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
602 entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); 670 entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
603 atomic_inc(&entry->refs); 671 atomic_inc(&entry->refs);
604out: 672out:
605 mutex_unlock(&tree->mutex); 673 spin_unlock(&tree->lock);
606 return entry; 674 return entry;
607} 675}
608 676
@@ -629,7 +697,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
629 else 697 else
630 offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); 698 offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
631 699
632 mutex_lock(&tree->mutex); 700 spin_lock(&tree->lock);
633 disk_i_size = BTRFS_I(inode)->disk_i_size; 701 disk_i_size = BTRFS_I(inode)->disk_i_size;
634 702
635 /* truncate file */ 703 /* truncate file */
@@ -735,7 +803,7 @@ out:
735 */ 803 */
736 if (ordered) 804 if (ordered)
737 __btrfs_remove_ordered_extent(inode, ordered); 805 __btrfs_remove_ordered_extent(inode, ordered);
738 mutex_unlock(&tree->mutex); 806 spin_unlock(&tree->lock);
739 if (ordered) 807 if (ordered)
740 wake_up(&ordered->wait); 808 wake_up(&ordered->wait);
741 return ret; 809 return ret;
@@ -762,7 +830,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
762 if (!ordered) 830 if (!ordered)
763 return 1; 831 return 1;
764 832
765 mutex_lock(&tree->mutex); 833 spin_lock(&tree->lock);
766 list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { 834 list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
767 if (disk_bytenr >= ordered_sum->bytenr) { 835 if (disk_bytenr >= ordered_sum->bytenr) {
768 num_sectors = ordered_sum->len / sectorsize; 836 num_sectors = ordered_sum->len / sectorsize;
@@ -777,7 +845,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
777 } 845 }
778 } 846 }
779out: 847out:
780 mutex_unlock(&tree->mutex); 848 spin_unlock(&tree->lock);
781 btrfs_put_ordered_extent(ordered); 849 btrfs_put_ordered_extent(ordered);
782 return ret; 850 return ret;
783} 851}