Skip to content
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

linux: fix invalid cross-device link error #8437

Merged
merged 5 commits into from
Feb 28, 2024

Conversation

sjet47
Copy link
Contributor

@sjet47 sjet47 commented Feb 26, 2024

This PR fix the "invalid cross-device link" error occurred in linux when trying to write the settings file atomically, like when click the "Enable vim mode" checkbox at first start.

[2024-02-26T22:59:25+08:00 ERROR util] .../zed/crates/settings/src/settings_file.rs:135: Failed to write settings to file "/home/$USER/.config/zed/settings.json"

Caused by:
0: failed to persist temporary file: Invalid cross-device link (os error 18)
1: Invalid cross-device link (os error 18)

Currently the fs::RealFs::atomic_write() method write to a temp file created with NamedTempFile::new() and then call persist() method to write to the config file path, which actually do a rename syscall under the hood. As the issue said

NamedTempFile::new() will create a temporary file in your system's temporary file directory. You need NamedTempFile::new_in().

The temporary file directory in linux is in /tmp, which is mounted to tmpfs filesystem, and in most case(all case I guess) $HOME/.config/zed is mounted to a different filesystem. And the rename syscall between different filesystems will return a EXDEV errno, as described in the man page rename(2):

       EXDEV  oldpath and newpath are not on the same mounted
              filesystem.  (Linux permits a filesystem to be mounted at
              multiple points, but rename() does not work across
              different mount points, even if the same filesystem is
              mounted on both.)

And as the issue above said, use a different temp dir with NamedTempFile::new_in() for linux platform might be a solution, since the rename syscall provides atomicity.

Release Notes:

  • Fix settings.json save failed with invalid cross-device link error in linux

Copy link

cla-bot bot commented Feb 26, 2024

We require contributors to sign our Contributor License Agreement, and we don't have @ASjet on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@sjet47
Copy link
Contributor Author

sjet47 commented Feb 26, 2024

@cla-bot check

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Feb 26, 2024
Copy link

cla-bot bot commented Feb 26, 2024

The cla-bot has been summoned, and re-checked this pull request!

crates/util/src/paths.rs Outdated Show resolved Hide resolved
@mikayla-maki mikayla-maki self-assigned this Feb 26, 2024
In atomic_write use the write path as the temp dir can ensure the temp file is in the same filesystem. Use XDG_CACHE_DIR as a fallback
Copy link
Contributor

@mikayla-maki mikayla-maki left a comment

Choose a reason for hiding this comment

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

Thank you!

Copy link
Contributor

@mikayla-maki mikayla-maki left a comment

Choose a reason for hiding this comment

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

Thank you!

@@ -481,6 +481,11 @@ fn init_paths() {
std::fs::create_dir_all(&*util::paths::LANGUAGES_DIR).expect("could not create languages path");
std::fs::create_dir_all(&*util::paths::DB_DIR).expect("could not create database path");
std::fs::create_dir_all(&*util::paths::LOGS_DIR).expect("could not create logs path");

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we remove this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure!

@mikayla-maki
Copy link
Contributor

mikayla-maki commented Feb 26, 2024

It also looks like this needs a cargo fmt :)

@mikayla-maki mikayla-maki merged commit 2f6b290 into zed-industries:main Feb 28, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed The user has signed the Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants