diff --git a/disk-io.c b/disk-io.c index 8f9b5bc1..10550151 100644 --- a/disk-io.c +++ b/disk-io.c @@ -1613,6 +1613,17 @@ static int write_dev_supers(struct btrfs_fs_info *fs_info, u32 crc; int i, ret; + /* + * We need to write super block after all metadata written. + * This is the equivalent of kernel pre-flush for FUA. + */ + ret = fsync(device->fd); + if (ret < 0) { + error( + "failed to write super block for devid %llu: flush error: %m", + device->devid); + return -errno; + } if (fs_info->super_bytenr != BTRFS_SUPER_INFO_OFFSET) { btrfs_set_super_bytenr(sb, fs_info->super_bytenr); crc = ~(u32)0; @@ -1634,6 +1645,13 @@ static int write_dev_supers(struct btrfs_fs_info *fs_info, device->devid); return -EIO; } + ret = fsync(device->fd); + if (ret < 0) { + error( + "failed to write super block for devid %llu: flush error: %m", + device->devid); + return -errno; + } return 0; } @@ -1662,6 +1680,19 @@ static int write_dev_supers(struct btrfs_fs_info *fs_info, device->devid); return -errno; } + /* + * Flush after the primary sb write, this is the equivalent of + * kernel post-flush for FUA write. + */ + if (i == 0) { + ret = fsync(device->fd); + if (ret < 0) { + error( + "failed to write super block for devid %llu: flush error: %m", + device->devid); + return -errno; + } + } } return 0;