aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-08-16 16:32:06 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-01 15:19:02 -0400
commit224ecce517af3a952321202cdf304c12e138caca (patch)
tree086997611ebc47bf99fddeb91b52f45a499a484d /fs/btrfs/file.c
parent54338b5cc4fa3cfe260e8e4ade8b62a9079ea3f9 (diff)
Btrfs: fix possible corruption when fsyncing written prealloced extents
While working on my fsync patch my fsync tester kept hitting mismatching md5sums when I would randomly write to a prealloc'ed region, syncfs() and then write to the prealloced region some more and then fsync() and then immediately reboot. This is because the tree logging code will skip writing csums for file extents who's generation is less than the current running transaction. When we mark extents as written we haven't been updating their generation so they were always being skipped. This wouldn't happen if you were to preallocate and then write in the same transaction, but if you for example prealloced a VM you could definitely run into this problem. This patch makes my fsync tester happy again. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 5caf285c6e4d..b7c885c8423f 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -935,12 +935,16 @@ again:
935 btrfs_set_item_key_safe(trans, root, path, &new_key); 935 btrfs_set_item_key_safe(trans, root, path, &new_key);
936 fi = btrfs_item_ptr(leaf, path->slots[0], 936 fi = btrfs_item_ptr(leaf, path->slots[0],
937 struct btrfs_file_extent_item); 937 struct btrfs_file_extent_item);
938 btrfs_set_file_extent_generation(leaf, fi,
939 trans->transid);
938 btrfs_set_file_extent_num_bytes(leaf, fi, 940 btrfs_set_file_extent_num_bytes(leaf, fi,
939 extent_end - end); 941 extent_end - end);
940 btrfs_set_file_extent_offset(leaf, fi, 942 btrfs_set_file_extent_offset(leaf, fi,
941 end - orig_offset); 943 end - orig_offset);
942 fi = btrfs_item_ptr(leaf, path->slots[0] - 1, 944 fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
943 struct btrfs_file_extent_item); 945 struct btrfs_file_extent_item);
946 btrfs_set_file_extent_generation(leaf, fi,
947 trans->transid);
944 btrfs_set_file_extent_num_bytes(leaf, fi, 948 btrfs_set_file_extent_num_bytes(leaf, fi,
945 end - other_start); 949 end - other_start);
946 btrfs_mark_buffer_dirty(leaf); 950 btrfs_mark_buffer_dirty(leaf);
@@ -958,12 +962,16 @@ again:
958 struct btrfs_file_extent_item); 962 struct btrfs_file_extent_item);
959 btrfs_set_file_extent_num_bytes(leaf, fi, 963 btrfs_set_file_extent_num_bytes(leaf, fi,
960 start - key.offset); 964 start - key.offset);
965 btrfs_set_file_extent_generation(leaf, fi,
966 trans->transid);
961 path->slots[0]++; 967 path->slots[0]++;
962 new_key.offset = start; 968 new_key.offset = start;
963 btrfs_set_item_key_safe(trans, root, path, &new_key); 969 btrfs_set_item_key_safe(trans, root, path, &new_key);
964 970
965 fi = btrfs_item_ptr(leaf, path->slots[0], 971 fi = btrfs_item_ptr(leaf, path->slots[0],
966 struct btrfs_file_extent_item); 972 struct btrfs_file_extent_item);
973 btrfs_set_file_extent_generation(leaf, fi,
974 trans->transid);
967 btrfs_set_file_extent_num_bytes(leaf, fi, 975 btrfs_set_file_extent_num_bytes(leaf, fi,
968 other_end - start); 976 other_end - start);
969 btrfs_set_file_extent_offset(leaf, fi, 977 btrfs_set_file_extent_offset(leaf, fi,
@@ -991,12 +999,14 @@ again:
991 leaf = path->nodes[0]; 999 leaf = path->nodes[0];
992 fi = btrfs_item_ptr(leaf, path->slots[0] - 1, 1000 fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
993 struct btrfs_file_extent_item); 1001 struct btrfs_file_extent_item);
1002 btrfs_set_file_extent_generation(leaf, fi, trans->transid);
994 btrfs_set_file_extent_num_bytes(leaf, fi, 1003 btrfs_set_file_extent_num_bytes(leaf, fi,
995 split - key.offset); 1004 split - key.offset);
996 1005
997 fi = btrfs_item_ptr(leaf, path->slots[0], 1006 fi = btrfs_item_ptr(leaf, path->slots[0],
998 struct btrfs_file_extent_item); 1007 struct btrfs_file_extent_item);
999 1008
1009 btrfs_set_file_extent_generation(leaf, fi, trans->transid);
1000 btrfs_set_file_extent_offset(leaf, fi, split - orig_offset); 1010 btrfs_set_file_extent_offset(leaf, fi, split - orig_offset);
1001 btrfs_set_file_extent_num_bytes(leaf, fi, 1011 btrfs_set_file_extent_num_bytes(leaf, fi,
1002 extent_end - split); 1012 extent_end - split);
@@ -1056,12 +1066,14 @@ again:
1056 struct btrfs_file_extent_item); 1066 struct btrfs_file_extent_item);
1057 btrfs_set_file_extent_type(leaf, fi, 1067 btrfs_set_file_extent_type(leaf, fi,
1058 BTRFS_FILE_EXTENT_REG); 1068 BTRFS_FILE_EXTENT_REG);
1069 btrfs_set_file_extent_generation(leaf, fi, trans->transid);
1059 btrfs_mark_buffer_dirty(leaf); 1070 btrfs_mark_buffer_dirty(leaf);
1060 } else { 1071 } else {
1061 fi = btrfs_item_ptr(leaf, del_slot - 1, 1072 fi = btrfs_item_ptr(leaf, del_slot - 1,
1062 struct btrfs_file_extent_item); 1073 struct btrfs_file_extent_item);
1063 btrfs_set_file_extent_type(leaf, fi, 1074 btrfs_set_file_extent_type(leaf, fi,
1064 BTRFS_FILE_EXTENT_REG); 1075 BTRFS_FILE_EXTENT_REG);
1076 btrfs_set_file_extent_generation(leaf, fi, trans->transid);
1065 btrfs_set_file_extent_num_bytes(leaf, fi, 1077 btrfs_set_file_extent_num_bytes(leaf, fi,
1066 extent_end - key.offset); 1078 extent_end - key.offset);
1067 btrfs_mark_buffer_dirty(leaf); 1079 btrfs_mark_buffer_dirty(leaf);