mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-24 09:57:08 -06:00
* fix(format): report a failed directory flush after a save instead of ignoring it atomic_write and the bundle writer discarded the directory fsync result once the rename had published the file, so a save whose rename might not survive a power loss reported success and its recovery data could be discarded. A real flush failure is now returned (the file is in place, the message says the save may not last), so callers keep the document unsaved and its recovery data, and a bundle save stops before removing objects the old manifest needs. A file system that can't flush directories at all (EINVAL, ENOTSUP, Unsupported) still counts as saved. Fixes #4968. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(format): a folder that can't be opened for a flush is not a failed save A write-and-search-only folder (no read permission) can't be opened to fsync it, so no flush can be attempted there. Treating that open failure as a failed flush made saves into such folders fail (the directory_symlinks permission tests on Linux). Only a flush that is attempted and fails is reported now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(format): flush bundle folders like atomic_write, and test a failed manifest flush The bundle writer flushed the folder with sync_all, which on Apple platforms is F_FULLFSYNC and fails on SMB shares; it now goes through the same RealFs::sync_dir as atomic_write (sync_file's plain-fsync fallback, #1336). open_dir_for_sync and dir_synced are crate-private. A test-only hook fails the manifest's folder flush: the save fails, and the objects the previous manifest references stay until the next save. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(format): keep stale previews until the manifest commits; errno 45 only where it is ENOTSUP A directory save removed a thumbnail or composite the new document no longer has before writing the new manifest, so a failed manifest flush left the previous manifest naming a preview that was gone. They are now removed after the manifest commits, best-effort like unreferenced objects; the failed-flush test checks the thumbnail survives. errno 45 counted as "can't flush directories" on every Unix, but it is ENOTSUP only on Apple platforms and the BSDs (illumos: EDEADLK). Other Unix targets now accept only EINVAL and ErrorKind::Unsupported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(format): flush the object folders before every manifest commit When an object's folder flush failed, a retried save found the object already written, reused it without flushing its folder, and then committed a manifest naming it: success was reported while the object's directory entry was still unconfirmed. Each directory save now flushes tiles/ and blobs/ once before writing the manifest, so a reused object is confirmed too. The flush error is shared with write_bundle_file (confirm_flushed), and a test retries a one-tile save whose tile folder flush failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(format): keep stale-preview removal before the manifest commit, as main requiresf77ffa3emoved stale-preview removal after the manifest commit. That broke the hardening in2d5a7497(#4957), whose test denied_stale_preview_cleanup_preserves_the_previous_manifest requires a committed manifest never to sit beside a stale preview, so a failed removal must fail the save. Restore main's ordering; the object-folder flush and the failed-flush tests stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(format): flush the composite folder after removing a stale composite The stale composite/preview.png was removed before the manifest commit, but nothing flushed composite/, so a crash could bring it back beside the new manifest. The folder is now flushed when a stale composite was removed (the thumbnail lives in the bundle root, flushed with the manifest). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>