Skip to content

[Filesystem] Try to rename directories before deleting them #39984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

danepowell
Copy link
Contributor

Q A
Branch? 5.x
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #27578
License MIT

This is a proof of concept solution for #27578. The bug is so old that I'm no longer in a position where I see it regularly, but I'm confident that it is still a bug. This is totally untested but hopefully points people on the right track.

@carsonbot carsonbot changed the title Fix #27578: Rename directories before deleting them [Filesystem] Fix #27578: Rename directories before deleting them Jan 26, 2021
@jderusse
Copy link
Member

for 4.4?

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for opening

@@ -170,6 +170,12 @@ public function remove($files)
throw new IOException(sprintf('Failed to remove symlink "%s": ', $file).self::$lastError);
}
} elseif (is_dir($file)) {
// Rename directory before removing it to mitigate the chance of
// another process writing to it during the operation.
// @see https://github.com/symfony/symfony/issues/27578
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be removed: we don't link to github in the source

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job for fabbot!?

cc @fabpot

// another process writing to it during the operation.
// @see https://github.com/symfony/symfony/issues/27578
$orig_file = $file;
$file = '.symfony-tmp.' . substr(sha1(rand()), 0, 7);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the temporary dir has to be in the same parent directory

also, we don't want to rename when removing nested folders of an already renamed one

about the tmp name, we should not use rand nor sha1 imho. Using strrev(strtr(base64_encode(random_bytes(2)), '/=', '-.')) would look better to me. We would delete the previously existing folder in case of collision, to have some very basic last-resort garbage collection...

// @see https://github.com/symfony/symfony/issues/27578
$orig_file = $file;
$file = '.symfony-tmp.' . substr(sha1(rand()), 0, 7);
$this->rename($orig_file, $file);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the rename fails, we should ignore and still proceed with the removal to me

@xabbuh xabbuh added this to the 4.4 milestone Jan 28, 2021
@nicolas-grekas nicolas-grekas changed the title [Filesystem] Fix #27578: Rename directories before deleting them [Filesystem] Try to rename directories before deleting them Feb 10, 2021
@nicolas-grekas
Copy link
Member

Thank you for the PR.
I opened #40144 to account for the comments I made a few days ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Filesystem remove() function can fail when run concurrently
6 participants