瀏覽代碼

Btrfs: avoid potential super block corruption

The data in fs_info->super_for_commit are zeros before the
first transaction commit. If tree log sync and system crash
both occur before the first transaction commit, super block
will get corrupted.

This fixes it by properly filling in the super_for_commit field at
open time.

Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Yan Zheng 16 年之前
父節點
當前提交
2d69a0f884
共有 1 個文件被更改,包括 3 次插入1 次删除
  1. 3 1
      fs/btrfs/disk-io.c

+ 3 - 1
fs/btrfs/disk-io.c

@@ -1609,6 +1609,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 		goto fail_iput;
 		goto fail_iput;
 
 
 	memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy));
 	memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy));
+	memcpy(&fs_info->super_for_commit, &fs_info->super_copy,
+	       sizeof(fs_info->super_for_commit));
 	brelse(bh);
 	brelse(bh);
 
 
 	memcpy(fs_info->fsid, fs_info->super_copy.fsid, BTRFS_FSID_SIZE);
 	memcpy(fs_info->fsid, fs_info->super_copy.fsid, BTRFS_FSID_SIZE);
@@ -1790,7 +1792,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
 
 	btrfs_read_block_groups(extent_root);
 	btrfs_read_block_groups(extent_root);
 
 
-	fs_info->generation = generation + 1;
+	fs_info->generation = generation;
 	fs_info->last_trans_committed = generation;
 	fs_info->last_trans_committed = generation;
 	fs_info->data_alloc_profile = (u64)-1;
 	fs_info->data_alloc_profile = (u64)-1;
 	fs_info->metadata_alloc_profile = (u64)-1;
 	fs_info->metadata_alloc_profile = (u64)-1;