btrfs fixes from next
[opensuse:kernel-source.git] / patches.suse / btrfs-8135-fix-possible-corruption-when-fsyncing-written-.patch
1 From: Josef Bacik <jbacik@fusionio.com>
2 Date: Thu, 16 Aug 2012 16:32:06 -0400
3 Patch-mainline: pending
4 References: FATE#306586
5 Subject: [PATCH] Btrfs: fix possible corruption when fsyncing written
6  prealloced extents
7
8 While working on my fsync patch my fsync tester kept hitting mismatching
9 md5sums when I would randomly write to a prealloc'ed region, syncfs() and
10 then write to the prealloced region some more and then fsync() and then
11 immediately reboot.  This is because the tree logging code will skip writing
12 csums for file extents who's generation is less than the current running
13 transaction.  When we mark extents as written we haven't been updating their
14 generation so they were always being skipped.  This wouldn't happen if you
15 were to preallocate and then write in the same transaction, but if you for
16 example prealloced a VM you could definitely run into this problem.  This
17 patch makes my fsync tester happy again.  Thanks,
18
19 Signed-off-by: Josef Bacik <jbacik@fusionio.com>
20 Signed-off-by: David Sterba <dsterba@suse.cz>
21 ---
22  fs/btrfs/file.c |   12 ++++++++++++
23  1 files changed, 12 insertions(+), 0 deletions(-)
24
25 diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
26 index 5caf285..b7c885c 100644
27 --- a/fs/btrfs/file.c
28 +++ b/fs/btrfs/file.c
29 @@ -935,12 +935,16 @@ again:
30                         btrfs_set_item_key_safe(trans, root, path, &new_key);
31                         fi = btrfs_item_ptr(leaf, path->slots[0],
32                                             struct btrfs_file_extent_item);
33 +                       btrfs_set_file_extent_generation(leaf, fi,
34 +                                                        trans->transid);
35                         btrfs_set_file_extent_num_bytes(leaf, fi,
36                                                         extent_end - end);
37                         btrfs_set_file_extent_offset(leaf, fi,
38                                                      end - orig_offset);
39                         fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
40                                             struct btrfs_file_extent_item);
41 +                       btrfs_set_file_extent_generation(leaf, fi,
42 +                                                        trans->transid);
43                         btrfs_set_file_extent_num_bytes(leaf, fi,
44                                                         end - other_start);
45                         btrfs_mark_buffer_dirty(leaf);
46 @@ -958,12 +962,16 @@ again:
47                                             struct btrfs_file_extent_item);
48                         btrfs_set_file_extent_num_bytes(leaf, fi,
49                                                         start - key.offset);
50 +                       btrfs_set_file_extent_generation(leaf, fi,
51 +                                                        trans->transid);
52                         path->slots[0]++;
53                         new_key.offset = start;
54                         btrfs_set_item_key_safe(trans, root, path, &new_key);
55  
56                         fi = btrfs_item_ptr(leaf, path->slots[0],
57                                             struct btrfs_file_extent_item);
58 +                       btrfs_set_file_extent_generation(leaf, fi,
59 +                                                        trans->transid);
60                         btrfs_set_file_extent_num_bytes(leaf, fi,
61                                                         other_end - start);
62                         btrfs_set_file_extent_offset(leaf, fi,
63 @@ -991,12 +999,14 @@ again:
64                 leaf = path->nodes[0];
65                 fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
66                                     struct btrfs_file_extent_item);
67 +               btrfs_set_file_extent_generation(leaf, fi, trans->transid);
68                 btrfs_set_file_extent_num_bytes(leaf, fi,
69                                                 split - key.offset);
70  
71                 fi = btrfs_item_ptr(leaf, path->slots[0],
72                                     struct btrfs_file_extent_item);
73  
74 +               btrfs_set_file_extent_generation(leaf, fi, trans->transid);
75                 btrfs_set_file_extent_offset(leaf, fi, split - orig_offset);
76                 btrfs_set_file_extent_num_bytes(leaf, fi,
77                                                 extent_end - split);
78 @@ -1056,12 +1066,14 @@ again:
79                            struct btrfs_file_extent_item);
80                 btrfs_set_file_extent_type(leaf, fi,
81                                            BTRFS_FILE_EXTENT_REG);
82 +               btrfs_set_file_extent_generation(leaf, fi, trans->transid);
83                 btrfs_mark_buffer_dirty(leaf);
84         } else {
85                 fi = btrfs_item_ptr(leaf, del_slot - 1,
86                            struct btrfs_file_extent_item);
87                 btrfs_set_file_extent_type(leaf, fi,
88                                            BTRFS_FILE_EXTENT_REG);
89 +               btrfs_set_file_extent_generation(leaf, fi, trans->transid);
90                 btrfs_set_file_extent_num_bytes(leaf, fi,
91                                                 extent_end - key.offset);
92                 btrfs_mark_buffer_dirty(leaf);
93 -- 
94 1.7.9
95