tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit cc4d11497f2204648db0516f785617124617fa18
parent c35177695e41167b01ce65e6c2198e0fb31c5781
Author: David P <daparks@mozilla.com>
Date:   Thu,  2 Oct 2025 22:38:21 +0000

Bug 1985141: Allow retryReadonly when removing internal files for backup r=sthompson

We don't expect these files to ever adopt read-only status, but, if they
ever do (say, due to user action), the read-only status should not be
allowed to prevent internal file removal.  Staging folders are also
internal but are expected to sometimes have read-only status and are
handled specially in another patch in this series.

Differential Revision: https://phabricator.services.mozilla.com/D263491

Diffstat:
Mbrowser/components/backup/BackupService.sys.mjs | 28+++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/browser/components/backup/BackupService.sys.mjs b/browser/components/backup/BackupService.sys.mjs @@ -1417,7 +1417,9 @@ export class BackupService extends EventTarget { this.#encState, manifest.meta ).finally(async () => { - await IOUtils.remove(compressedStagingPath); + await IOUtils.remove(compressedStagingPath, { + retryReadonly: true, + }); }); // Record the size of the complete single-file archive @@ -1590,7 +1592,10 @@ export class BackupService extends EventTarget { // A pre-existing staging folder exists. A previous backup attempt must // have failed or been interrupted. We'll clear it out. lazy.logConsole.warn("A pre-existing staging folder exists. Clearing."); - await IOUtils.remove(stagingPath, { recursive: true }); + await IOUtils.remove(stagingPath, { + recursive: true, + retryReadonly: true, + }); } await IOUtils.makeDirectory(stagingPath); @@ -2373,7 +2378,10 @@ export class BackupService extends EventTarget { ); } - await IOUtils.remove(extractionDestPath, { ignoreAbsent: true }); + await IOUtils.remove(extractionDestPath, { + ignoreAbsent: true, + retryReadonly: true, + }); let archiveFile = await IOUtils.getFile(archivePath); let archiveStream = await this.createBinaryReadableStream( @@ -2600,7 +2608,7 @@ export class BackupService extends EventTarget { // Now that we've decompressed it, reclaim some disk space by getting rid of // the ZIP file. try { - await IOUtils.remove(RECOVERY_FILE_DEST_PATH); + await IOUtils.remove(RECOVERY_FILE_DEST_PATH, { retryReadonly: true }); } catch (_) { lazy.logConsole.warn("Could not remove ", RECOVERY_FILE_DEST_PATH); } @@ -2914,7 +2922,10 @@ export class BackupService extends EventTarget { lazy.logConsole.debug(`Done post-recovery step for ${resourceKey}`); } } finally { - await IOUtils.remove(postRecoveryFile, { ignoreAbsent: true }); + await IOUtils.remove(postRecoveryFile, { + ignoreAbsent: true, + retryReadonly: true, + }); this.#postRecoveryResolver(); } } @@ -3234,7 +3245,10 @@ export class BackupService extends EventTarget { // It'd be pretty strange, but not impossible, for something else to have // gotten rid of the encryption state file at this point. We'll ignore it // if that's the case. - await IOUtils.remove(encStateFile, { ignoreAbsent: true }); + await IOUtils.remove(encStateFile, { + ignoreAbsent: true, + retryReadonly: true, + }); this.#encState = null; this.#_state.encryptionEnabled = false; @@ -3908,7 +3922,7 @@ export class BackupService extends EventTarget { // folder. If not, delete that folder too. let children = await IOUtils.getChildren(lazy.backupDirPref); if (!children.length) { - await IOUtils.remove(lazy.backupDirPref); + await IOUtils.remove(lazy.backupDirPref, { retryReadony: true }); } } }