Skip to content

Commit eed6ccd

Browse files
committed
feat(locking): Disable locking on network file systems
1 parent c1c60f4 commit eed6ccd

File tree

6 files changed

+32
-15
lines changed

6 files changed

+32
-15
lines changed

src/cargo/core/compiler/build_runner/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::core::compiler::locking::LockingMode;
1010
use crate::core::compiler::{self, Unit, artifact};
1111
use crate::util::cache_lock::CacheLockMode;
1212
use crate::util::errors::CargoResult;
13+
use crate::util::flock::is_on_nfs_mount;
1314
use crate::util::rlimit;
1415
use annotate_snippets::{Level, Message};
1516
use anyhow::{Context as _, bail};
@@ -748,6 +749,11 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
748749
pub fn determine_locking_mode(bcx: &BuildContext<'_, '_>) -> CargoResult<LockingMode> {
749750
let total_units = bcx.unit_graph.keys().len() as u64;
750751

752+
if is_on_nfs_mount(bcx.ws.build_dir().as_path_unlocked()) {
753+
debug!("NFS detected. Disabling file system locking");
754+
return Ok(LockingMode::None);
755+
}
756+
751757
// This is a bit arbitrary but if we do not have at least 10 times the remaining file
752758
// descriptors than total build units there is a chance we could hit the limit.
753759
// This is a fairly conservative estimate to make sure we don't hit max fd errors.

src/cargo/core/compiler/layout.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,25 +155,29 @@ impl Layout {
155155
// directory, so just lock the entire thing for the duration of this
156156
// compile.
157157
let artifact_dir_lock = match locking_mode {
158+
LockingMode::None => None,
158159
LockingMode::Fine => {
159-
dest.open_ro_shared_create(".cargo-lock", ws.gctx(), "build directory")?
160+
Some(dest.open_ro_shared_create(".cargo-lock", ws.gctx(), "build directory")?)
160161
}
161162
LockingMode::Coarse => {
162-
dest.open_rw_exclusive_create(".cargo-lock", ws.gctx(), "build directory")?
163+
Some(dest.open_rw_exclusive_create(".cargo-lock", ws.gctx(), "build directory")?)
163164
}
164165
};
165166

166167
let build_dir_lock = if root != build_root {
167-
Some(match locking_mode {
168-
LockingMode::Fine => {
169-
build_dest.open_ro_shared_create(".cargo-lock", ws.gctx(), "build directory")?
170-
}
171-
LockingMode::Coarse => build_dest.open_rw_exclusive_create(
168+
match locking_mode {
169+
LockingMode::None => None,
170+
LockingMode::Fine => Some(build_dest.open_ro_shared_create(
172171
".cargo-lock",
173172
ws.gctx(),
174173
"build directory",
175-
)?,
176-
})
174+
)?),
175+
LockingMode::Coarse => Some(build_dest.open_rw_exclusive_create(
176+
".cargo-lock",
177+
ws.gctx(),
178+
"build directory",
179+
)?),
180+
}
177181
} else {
178182
None
179183
};
@@ -235,7 +239,7 @@ pub struct ArtifactDirLayout {
235239
timings: PathBuf,
236240
/// The lockfile for a build (`.cargo-lock`). Will be unlocked when this
237241
/// struct is `drop`ped.
238-
_lock: FileLock,
242+
_lock: Option<FileLock>,
239243
}
240244

241245
impl ArtifactDirLayout {

src/cargo/core/compiler/locking.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ use crate::{
4949
/// The locking mode that will be used for output directories.
5050
#[derive(Debug)]
5151
pub enum LockingMode {
52+
/// Completely disables locking (used for filesystems that do not support locking)
53+
None,
5254
/// Fine grain locking (Build unit level)
5355
Fine,
5456
/// Coarse grain locking (Profile level)

src/cargo/ops/cargo_clean.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::ops;
66
use crate::util::HumanBytes;
77
use crate::util::edit_distance;
88
use crate::util::errors::CargoResult;
9+
use crate::util::flock::is_on_nfs_mount;
910
use crate::util::interning::InternedString;
1011
use crate::util::{GlobalContext, Progress, ProgressStyle};
1112
use anyhow::bail;
@@ -117,13 +118,17 @@ fn clean_specs(
117118
let target_data = RustcTargetData::new(ws, &requested_kinds)?;
118119
let (pkg_set, resolve) = ops::resolve_ws(ws, dry_run)?;
119120
let prof_dir_name = profiles.get_dir_name();
120-
let host_layout = Layout::new(ws, None, &prof_dir_name, &LockingMode::Coarse)?;
121+
let locking_mode = match is_on_nfs_mount(ws.build_dir().as_path_unlocked()) {
122+
true => LockingMode::None,
123+
false => LockingMode::Coarse,
124+
};
125+
let host_layout = Layout::new(ws, None, &prof_dir_name, &locking_mode)?;
121126
// Convert requested kinds to a Vec of layouts.
122127
let target_layouts: Vec<(CompileKind, Layout)> = requested_kinds
123128
.into_iter()
124129
.filter_map(|kind| match kind {
125130
CompileKind::Target(target) => {
126-
match Layout::new(ws, Some(target), &prof_dir_name, &LockingMode::Coarse) {
131+
match Layout::new(ws, Some(target), &prof_dir_name, &locking_mode) {
127132
Ok(layout) => Some(Ok((kind, layout))),
128133
Err(e) => Some(Err(e)),
129134
}

src/cargo/util/flock.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ fn acquire(
427427
}
428428

429429
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
430-
fn is_on_nfs_mount(path: &Path) -> bool {
430+
pub fn is_on_nfs_mount(path: &Path) -> bool {
431431
use std::ffi::CString;
432432
use std::mem;
433433
use std::os::unix::prelude::*;
@@ -445,7 +445,7 @@ fn is_on_nfs_mount(path: &Path) -> bool {
445445
}
446446

447447
#[cfg(any(not(target_os = "linux"), target_env = "musl"))]
448-
fn is_on_nfs_mount(_path: &Path) -> bool {
448+
pub fn is_on_nfs_mount(_path: &Path) -> bool {
449449
false
450450
}
451451

src/cargo/util/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ mod dependency_queue;
4141
pub mod diagnostic_server;
4242
pub mod edit_distance;
4343
pub mod errors;
44-
mod flock;
44+
pub mod flock;
4545
pub mod frontmatter;
4646
pub mod graph;
4747
mod hasher;

0 commit comments

Comments
 (0)