Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67b9fbba authored by Joseph Pirozzo's avatar Joseph Pirozzo
Browse files

Flush buffer to filesystem before fsync

If power is lost immediately after updating a config file it is possible
to save an empty file in its place.  By flushing the stream buffer to
the filesystem before flushing the filesystem to the disk this risk is
mitigated;

Bug: 122607444
Test: Update Bluetooth Device name and interrupt power to device.
Change-Id: Iaf89c4d9c594e925507e713a9febbf23a7cdae43
parent 0d888e52
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -223,10 +223,11 @@ bool config_save(const config_t& config, const std::string& filename) {
  // Steps to ensure content of config file gets to disk:
  //
  // 1) Open and write to temp file (e.g. bt_config.conf.new).
  // 2) Sync the temp file to disk with fsync().
  // 3) Rename temp file to actual config file (e.g. bt_config.conf).
  // 2) Flush the stream buffer to the temp file.
  // 3) Sync the temp file to disk with fsync().
  // 4) Rename temp file to actual config file (e.g. bt_config.conf).
  //    This ensures atomic update.
  // 4) Sync directory that has the conf file with fsync().
  // 5) Sync directory that has the conf file with fsync().
  //    This ensures directory entries are up-to-date.
  int dir_fd = -1;
  FILE* fp = nullptr;
@@ -272,6 +273,13 @@ bool config_save(const config_t& config, const std::string& filename) {
    goto error;
  }

  // Flush the stream buffer to the temp file.
  if (fflush(fp) < 0) {
    LOG(ERROR) << __func__ << ": unable to write flush buffer to file '"
               << temp_filename << "': " << strerror(errno);
    goto error;
  }

  // Sync written temp file out to disk. fsync() is blocking until data makes it
  // to disk.
  if (fsync(fileno(fp)) < 0) {