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.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 6513270f054c..d86a953ae51d 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -406,3 +406,92 @@ out:
406 mutex_unlock(&tree->mutex); 406 mutex_unlock(&tree->mutex);
407 return entry; 407 return entry;
408} 408}
409
410int btrfs_ordered_update_i_size(struct inode *inode,
411 struct btrfs_ordered_extent *ordered)
412{
413 struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
414 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
415 u64 disk_i_size;
416 u64 new_i_size;
417 u64 i_size_test;
418 struct rb_node *node;
419 struct btrfs_ordered_extent *test;
420
421 mutex_lock(&tree->mutex);
422 disk_i_size = BTRFS_I(inode)->disk_i_size;
423
424 /*
425 * if the disk i_size is already at the inode->i_size, or
426 * this ordered extent is inside the disk i_size, we're done
427 */
428 if (disk_i_size >= inode->i_size ||
429 ordered->file_offset + ordered->len <= disk_i_size) {
430 goto out;
431 }
432
433 /*
434 * we can't update the disk_isize if there are delalloc bytes
435 * between disk_i_size and this ordered extent
436 */
437 if (test_range_bit(io_tree, disk_i_size,
438 ordered->file_offset + ordered->len - 1,
439 EXTENT_DELALLOC, 0)) {
440 goto out;
441 }
442 /*
443 * walk backward from this ordered extent to disk_i_size.
444 * if we find an ordered extent then we can't update disk i_size
445 * yet
446 */
447 while(1) {
448 node = rb_prev(&ordered->rb_node);
449 if (!node)
450 break;
451 test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
452 if (test->file_offset + test->len <= disk_i_size)
453 break;
454 if (test->file_offset >= inode->i_size)
455 break;
456 if (test->file_offset >= disk_i_size)
457 goto out;
458 }
459 new_i_size = min_t(u64, entry_end(ordered), i_size_read(inode));
460
461 /*
462 * at this point, we know we can safely update i_size to at least
463 * the offset from this ordered extent. But, we need to
464 * walk forward and see if ios from higher up in the file have
465 * finished.
466 */
467 node = rb_next(&ordered->rb_node);
468 i_size_test = 0;
469 if (node) {
470 /*
471 * do we have an area where IO might have finished
472 * between our ordered extent and the next one.
473 */
474 test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
475 if (test->file_offset > entry_end(ordered)) {
476 i_size_test = test->file_offset - 1;
477 }
478 } else {
479 i_size_test = i_size_read(inode);
480 }
481
482 /*
483 * i_size_test is the end of a region after this ordered
484 * extent where there are no ordered extents. As long as there
485 * are no delalloc bytes in this area, it is safe to update
486 * disk_i_size to the end of the region.
487 */
488 if (i_size_test > entry_end(ordered) &&
489 !test_range_bit(io_tree, entry_end(ordered), i_size_test,
490 EXTENT_DELALLOC, 0)) {
491 new_i_size = min_t(u64, i_size_test, i_size_read(inode));
492 }
493 BTRFS_I(inode)->disk_i_size = new_i_size;
494out:
495 mutex_unlock(&tree->mutex);
496 return 0;
497}