|
@@ -775,7 +775,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
|
|
struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
|
|
struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
|
|
u64 disk_i_size;
|
|
u64 disk_i_size;
|
|
u64 new_i_size;
|
|
u64 new_i_size;
|
|
- u64 i_size_test;
|
|
|
|
u64 i_size = i_size_read(inode);
|
|
u64 i_size = i_size_read(inode);
|
|
struct rb_node *node;
|
|
struct rb_node *node;
|
|
struct rb_node *prev = NULL;
|
|
struct rb_node *prev = NULL;
|
|
@@ -835,55 +834,30 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
|
|
break;
|
|
break;
|
|
if (test->file_offset >= i_size)
|
|
if (test->file_offset >= i_size)
|
|
break;
|
|
break;
|
|
- if (test->file_offset >= disk_i_size)
|
|
|
|
|
|
+ if (test->file_offset >= disk_i_size) {
|
|
|
|
+ /*
|
|
|
|
+ * we don't update disk_i_size now, so record this
|
|
|
|
+ * undealt i_size. Or we will not know the real
|
|
|
|
+ * i_size.
|
|
|
|
+ */
|
|
|
|
+ if (test->outstanding_isize < offset)
|
|
|
|
+ test->outstanding_isize = offset;
|
|
|
|
+ if (ordered &&
|
|
|
|
+ ordered->outstanding_isize >
|
|
|
|
+ test->outstanding_isize)
|
|
|
|
+ test->outstanding_isize =
|
|
|
|
+ ordered->outstanding_isize;
|
|
goto out;
|
|
goto out;
|
|
- }
|
|
|
|
- new_i_size = min_t(u64, offset, i_size);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * at this point, we know we can safely update i_size to at least
|
|
|
|
- * the offset from this ordered extent. But, we need to
|
|
|
|
- * walk forward and see if ios from higher up in the file have
|
|
|
|
- * finished.
|
|
|
|
- */
|
|
|
|
- if (ordered) {
|
|
|
|
- node = rb_next(&ordered->rb_node);
|
|
|
|
- } else {
|
|
|
|
- if (prev)
|
|
|
|
- node = rb_next(prev);
|
|
|
|
- else
|
|
|
|
- node = rb_first(&tree->tree);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * We are looking for an area between our current extent and the next
|
|
|
|
- * ordered extent to update the i_size to. There are 3 cases here
|
|
|
|
- *
|
|
|
|
- * 1) We don't actually have anything and we can update to i_size.
|
|
|
|
- * 2) We have stuff but they already did their i_size update so again we
|
|
|
|
- * can just update to i_size.
|
|
|
|
- * 3) We have an outstanding ordered extent so the most we can update
|
|
|
|
- * our disk_i_size to is the start of the next offset.
|
|
|
|
- */
|
|
|
|
- i_size_test = i_size;
|
|
|
|
- for (; node; node = rb_next(node)) {
|
|
|
|
- test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
|
|
|
|
-
|
|
|
|
- if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
|
|
|
|
- continue;
|
|
|
|
- if (test->file_offset > offset) {
|
|
|
|
- i_size_test = test->file_offset;
|
|
|
|
- break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ new_i_size = min_t(u64, offset, i_size);
|
|
|
|
|
|
/*
|
|
/*
|
|
- * i_size_test is the end of a region after this ordered
|
|
|
|
- * extent where there are no ordered extents, we can safely set
|
|
|
|
- * disk_i_size to this.
|
|
|
|
|
|
+ * Some ordered extents may completed before the current one, and
|
|
|
|
+ * we hold the real i_size in ->outstanding_isize.
|
|
*/
|
|
*/
|
|
- if (i_size_test > offset)
|
|
|
|
- new_i_size = min_t(u64, i_size_test, i_size);
|
|
|
|
|
|
+ if (ordered && ordered->outstanding_isize > new_i_size)
|
|
|
|
+ new_i_size = min_t(u64, ordered->outstanding_isize, i_size);
|
|
BTRFS_I(inode)->disk_i_size = new_i_size;
|
|
BTRFS_I(inode)->disk_i_size = new_i_size;
|
|
ret = 0;
|
|
ret = 0;
|
|
out:
|
|
out:
|