Btrfs: fix file extent discount problem in the, snapshot
[deliverable/linux.git] / fs / btrfs / ordered-data.c
index 051c7fe551dd38bb7e391e5abaeff992f32b90f7..cd8ecb73c05c6519981193069a3dc0d034fc7662 100644 (file)
@@ -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;
        u64 disk_i_size;
        u64 new_i_size;
-       u64 i_size_test;
        u64 i_size = i_size_read(inode);
        struct rb_node *node;
        struct rb_node *prev = NULL;
@@ -835,55 +834,30 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
                        break;
                if (test->file_offset >= i_size)
                        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;
-       }
-       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;
        ret = 0;
 out:
This page took 0.031846 seconds and 5 git commands to generate.