Skip to content

Commit d58af58

Browse files
committed
Various tidying up for freebsd support
1 parent 475e2f3 commit d58af58

File tree

8 files changed

+46
-11
lines changed

8 files changed

+46
-11
lines changed

README.adoc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ Efficiently removing data, and creating read snapshots requires hole punching, a
2424

2525
== Supported systems
2626

27-
macOS, Linux and Windows are supported. FreeBSD doesn't work yet, unfortunately file cloning and open file description locking is missing, but there are fallbacks that can be used. Solaris requires a small amount of work to complete the implementation. On systems where block cloning is not supported (ext4 on Linux, and NTFS on Windows are notable examples), the implementation falls back to file region locking (except for FreeBSD which will have to fall back to whole-file locking).
27+
macOS, Linux and Windows.
28+
29+
FreeBSD 14+. Unfortunately file cloning and open file description locking are missing. The implementation falls back on flock(2) and has to separate write and read files.
30+
31+
Solaris requires a small amount of work to complete the implementation.
32+
33+
On filesystems where block cloning is not supported (ext4 on Linux, and NTFS on Windows are notable examples), the implementation falls back to file region locking unless that is also not available (FreeBSD).
2834

2935
== anacrolix/squirrel
3036

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ Efficiently removing data, and creating read snapshots requires hole punching, a
2424

2525
## Supported systems
2626

27-
macOS, Linux and Windows are supported. FreeBSD doesn’t work yet, unfortunately file cloning and open file description locking is missing, but there are fallbacks that can be used. Solaris requires a small amount of work to complete the implementation. On systems where block cloning is not supported (ext4 on Linux, and NTFS on Windows are notable examples), the implementation falls back to file region locking (except for FreeBSD which will have to fall back to whole-file locking).
27+
macOS, Linux and Windows.
28+
29+
FreeBSD 14+. Unfortunately file cloning and open file description locking are missing. The implementation falls back on flock(2) and has to separate write and read files.
30+
31+
Solaris requires a small amount of work to complete the implementation.
32+
33+
On filesystems where block cloning is not supported (ext4 on Linux, and NTFS on Windows are notable examples), the implementation falls back to file region locking unless that is also not available (FreeBSD).
2834

2935
## anacrolix/squirrel
3036

src/env.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ pub(crate) fn emulate_freebsd() -> bool {
88
use once_cell::sync::OnceCell;
99
static CELL: OnceCell<bool> = OnceCell::new();
1010
*CELL.get_or_init(|| {
11-
!matches!(
11+
let emulate = !matches!(
1212
std::env::var("POSSUM_EMULATE_FREEBSD"),
1313
Err(std::env::VarError::NotPresent)
14-
)
14+
);
15+
if emulate {
16+
super::error!("emulating freebsd");
17+
}
18+
emulate
1519
})
1620
}
1721
}

src/exclusive_file.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use crate::FileId;
88

99
#[derive(Debug)]
1010
enum LockLevel {
11+
// On systems that don't implement flock, downgrades never occur.
12+
#[allow(dead_code)]
1113
Shared,
1214
Exclusive,
1315
}

src/handle.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub struct Handle {
2323
pub(crate) instance_limits: Limits,
2424
deleted_values: Option<DeletedValuesSender>,
2525
_value_puncher: Option<std::thread::JoinHandle<()>>,
26-
pub(crate) value_puncher_done: Arc<Mutex<std::sync::mpsc::Receiver<()>>>,
26+
value_puncher_done: ValuePuncherDone,
2727
}
2828

2929
/// 4 bytes stored in the database header https://sqlite.org/fileformat2.html#database_header.
@@ -108,7 +108,7 @@ impl Handle {
108108
Self::init_sqlite_conn(&mut conn)?;
109109
let (deleted_values, receiver) = std::sync::mpsc::sync_channel(10);
110110
let (value_puncher_done_sender, value_puncher_done) = std::sync::mpsc::sync_channel(0);
111-
let value_puncher_done = Arc::new(Mutex::new(value_puncher_done));
111+
let value_puncher_done = ValuePuncherDone(Arc::new(Mutex::new(value_puncher_done)));
112112
let handle = Self {
113113
conn: Mutex::new(conn),
114114
exclusive_files: Default::default(),
@@ -350,7 +350,6 @@ impl Handle {
350350
file_id,
351351
file_offset,
352352
length,
353-
..
354353
} = &v;
355354
let value_length = length;
356355
let msg = format!(
@@ -390,6 +389,11 @@ impl Handle {
390389
}
391390
}
392391
}
392+
393+
/// Returns something that can be used to test if the value puncher routine for this Handle has returned.
394+
pub fn get_value_puncher_done(&self) -> ValuePuncherDone {
395+
ValuePuncherDone(Arc::clone(&self.value_puncher_done.0))
396+
}
393397
}
394398

395399
use item::Item;
@@ -407,3 +411,15 @@ impl Drop for Handle {
407411
// }
408412
}
409413
}
414+
415+
#[derive(Debug)]
416+
pub struct ValuePuncherDone(Arc<Mutex<std::sync::mpsc::Receiver<()>>>);
417+
418+
impl ValuePuncherDone {
419+
pub fn wait(&self) {
420+
assert!(matches!(
421+
self.0.lock().unwrap().recv(),
422+
Err(std::sync::mpsc::RecvError)
423+
))
424+
}
425+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,7 @@ impl<'a> Reader<'a> {
816816
if flocking() {
817817
// Possibly we want to block if we're flocking.
818818
assert!(file.flock(LockShared)?);
819+
return Ok(());
819820
}
820821
for extent in read_extents {
821822
assert!(file.lock_segment(LockSharedNonblock, Some(extent.len), extent.offset)?);

src/sys/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use flock::*;
1515
pub(crate) use pathconf::*;
1616
pub use punchfile::*;
1717

18-
use crate::env::flocking;
18+
use crate::env::{emulate_freebsd, flocking};
1919

2020
cfg_if! {
2121
if #[cfg(windows)] {
@@ -88,7 +88,7 @@ impl FileSystemFlags for UnixFilesystemFlags {
8888
// AFAIK there's no way to check if a filesystem supports block cloning on non-Windows
8989
// platforms, and even then it depends on where you're copying to/from, sometimes even on
9090
// the same filesystem.
91-
if flocking() {
91+
if emulate_freebsd() {
9292
Some(false)
9393
} else {
9494
None

src/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ fn test_replace_keys() -> Result<()> {
7474
);
7575

7676
let dir = handle.dir.clone();
77-
let values_punched = Arc::clone(&handle.value_puncher_done);
77+
let values_punched = handle.get_value_puncher_done();
7878
drop(handle);
7979
// Wait for it to recv, which should be a disconnect when the value_puncher hangs up.
80-
values_punched.lock().unwrap().recv();
80+
values_punched.wait();
8181

8282
let entries = dir.walk_dir()?;
8383
let values_files: Vec<_> = entries

0 commit comments

Comments
 (0)