Don't unconditionally sync directory in fixate_user_ce_key()

Directory syncs can be expensive, so only sync the directory in
fixate_user_ce_key() if something was actually done, i.e. if at least
one key directory was deleted or renamed.  Previously, the unconditional
sync in this function was being executed whenever the CE key was
retrieved or stored.  Note that all the syncs needed when storing the
key already happen in storeKeyAtomically(); this one was unrelated.

Bug: 232452368
Bug: 251131631
Bug: 251147505
Ignore-AOSP-First: depends on other changes in internal master
Change-Id: Ib0f2b9e27cdd11e359a1618cddc1f5480bd2fd37
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index a3ef9ba..d964a33 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -181,17 +181,20 @@
 // Discard all keys but the named one; rename it to canonical name.
 static bool fixate_user_ce_key(const std::string& directory_path, const std::string& to_fix,
                                const std::vector<std::string>& paths) {
+    bool need_sync = false;
     for (auto const other_path : paths) {
         if (other_path != to_fix) {
             android::vold::destroyKey(other_path);
+            need_sync = true;
         }
     }
     auto const current_path = get_ce_key_current_path(directory_path);
     if (to_fix != current_path) {
         LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
         if (!android::vold::RenameKeyDir(to_fix, current_path)) return false;
+        need_sync = true;
     }
-    if (!android::vold::FsyncDirectory(directory_path)) return false;
+    if (need_sync && !android::vold::FsyncDirectory(directory_path)) return false;
     return true;
 }