Mercurial > hg-stable
changeset 49669:be019ac8c1e4 stable
dirstate-v2: don't mmap the data file when on NFS
`mmap` on NFS will trigger a SIGBUS when the mmap'ed file is deleted, which
wouldn't work in our case. Also, the performance advantage of using mmap on
NFS is debatable at best.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 28 Nov 2022 12:33:20 +0100 |
parents | f2e13d8d30e0 |
children | 6515d9a6592d |
files | rust/hg-core/src/repo.rs rust/hg-core/src/vfs.rs |
diffstat | 2 files changed, 29 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/repo.rs Thu Dec 08 16:38:39 2022 +0100 +++ b/rust/hg-core/src/repo.rs Mon Nov 28 12:33:20 2022 +0100 @@ -320,7 +320,14 @@ .set(Some(docket.uuid.to_owned())); let data_size = docket.data_size(); let metadata = docket.tree_metadata(); - if let Some(data_mmap) = self + if crate::vfs::is_on_nfs_mount(docket.data_filename()) { + // Don't mmap on NFS to prevent `SIGBUS` error on deletion + OwningDirstateMap::new_v2( + self.hg_vfs().read(docket.data_filename())?, + data_size, + metadata, + ) + } else if let Some(data_mmap) = self .hg_vfs() .mmap_open(docket.data_filename()) .io_not_found_as_none()?
--- a/rust/hg-core/src/vfs.rs Thu Dec 08 16:38:39 2022 +0100 +++ b/rust/hg-core/src/vfs.rs Mon Nov 28 12:33:20 2022 +0100 @@ -172,3 +172,24 @@ pub(crate) fn is_file(path: impl AsRef<Path>) -> Result<bool, HgError> { Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_file())) } + +/// Returns whether the given `path` is on a network file system. +/// Taken from `cargo`'s codebase. +#[cfg(target_os = "linux")] +pub(crate) fn is_on_nfs_mount(path: impl AsRef<Path>) -> bool { + use std::ffi::CString; + use std::mem; + use std::os::unix::prelude::*; + + let path = match CString::new(path.as_ref().as_os_str().as_bytes()) { + Ok(path) => path, + Err(_) => return false, + }; + + unsafe { + let mut buf: libc::statfs = mem::zeroed(); + let r = libc::statfs(path.as_ptr(), &mut buf); + + r == 0 && buf.f_type as u32 == libc::NFS_SUPER_MAGIC as u32 + } +}