OSDN Git Service

Merge tag 'v4.4.207' into 10
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / btrfs / file.c
index 0529736..73b547f 100644 (file)
@@ -1525,6 +1525,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
                }
 
                reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
+               only_release_metadata = false;
 
                if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
                                              BTRFS_INODE_PREALLOC)) &&
@@ -1659,7 +1660,6 @@ again:
                        set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
                                       lockend, EXTENT_NORESERVE, NULL,
                                       NULL, GFP_NOFS);
-                       only_release_metadata = false;
                }
 
                btrfs_drop_pages(pages, num_pages);
@@ -1901,6 +1901,18 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        u64 len;
 
        /*
+        * If the inode needs a full sync, make sure we use a full range to
+        * avoid log tree corruption, due to hole detection racing with ordered
+        * extent completion for adjacent ranges, and assertion failures during
+        * hole detection.
+        */
+       if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+                    &BTRFS_I(inode)->runtime_flags)) {
+               start = 0;
+               end = LLONG_MAX;
+       }
+
+       /*
         * The range length can be represented by u64, we have to do the typecasts
         * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
         */