diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-02-28 01:01:50 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-02-28 01:01:50 -0500 |
commit | 59528398cf367df1e84372946b7031a2e3eb2b7e (patch) | |
tree | 542f805458e9afa541ebfa6a06d081397aee7fcd | |
parent | a999dc0a9f22a2f403defa26d09257f7600a4312 (diff) | |
download | bcachefs-tools-59528398cf367df1e84372946b7031a2e3eb2b7e.tar.gz |
rust: BkeySC
Implement a rust equivalent to bkey_s_c, which uses references with the
correct lifetimes: now cmd_list.rs doesn't need unsafe.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | rust-src/bch_bindgen/src/btree.rs | 49 | ||||
-rw-r--r-- | rust-src/bch_bindgen/src/lib.rs | 23 | ||||
-rw-r--r-- | rust-src/src/cmd_list.rs | 6 |
3 files changed, 44 insertions, 34 deletions
diff --git a/rust-src/bch_bindgen/src/btree.rs b/rust-src/bch_bindgen/src/btree.rs index db5d6c6d..4b5e86d9 100644 --- a/rust-src/bch_bindgen/src/btree.rs +++ b/rust-src/bch_bindgen/src/btree.rs @@ -6,6 +6,8 @@ use std::marker::PhantomData; use std::mem::MaybeUninit; use std::ptr; use bitflags::bitflags; +use std::ffi::CStr; +use std::fmt; pub struct BtreeTrans { raw: c::btree_trans, @@ -54,8 +56,8 @@ pub struct BtreeIter<'a> { trans: PhantomData<&'a BtreeTrans>, } -impl<'a> BtreeIter<'a> { - pub fn new(trans: &'a BtreeTrans, btree: c::btree_id, pos: c::bpos, flags: BtreeIterFlags) -> BtreeIter { +impl<'t> BtreeIter<'t> { + pub fn new(trans: &'t BtreeTrans, btree: c::btree_id, pos: c::bpos, flags: BtreeIterFlags) -> BtreeIter { unsafe { let mut iter: MaybeUninit<c::btree_iter> = MaybeUninit::uninit(); @@ -70,23 +72,24 @@ impl<'a> BtreeIter<'a> { } } - pub fn peek_upto(&mut self, end: c::bpos) -> Result<c::bkey_s_c, bch_errcode> { + pub fn peek_upto<'i>(&'i mut self, end: c::bpos) -> Result<Option<BkeySC>, bch_errcode> { unsafe { let k = c::bch2_btree_iter_peek_upto(&mut self.raw, end); - errptr_to_result_c(k.k).map(|_| k) + errptr_to_result_c(k.k) + .map(|_| if !k.k.is_null() { Some(BkeySC { k: &*k.k, v: &*k.v }) } else { None } ) } } - pub fn peek(&mut self) -> Result<c::bkey_s_c, bch_errcode> { + pub fn peek(&mut self) -> Result<Option<BkeySC>, bch_errcode> { self.peek_upto(SPOS_MAX) } - pub fn peek_and_restart(&mut self) -> Result<Option<c::bkey_s_c>, bch_errcode> { + pub fn peek_and_restart(&mut self) -> Result<Option<BkeySC>, bch_errcode> { unsafe { let k = c::bch2_btree_iter_peek_and_restart_outlined(&mut self.raw); errptr_to_result_c(k.k) - .map(|_| if !k.k.is_null() { Some(k) } else { None } ) + .map(|_| if !k.k.is_null() { Some(BkeySC{ k: &*k.k, v: &*k.v }) } else { None } ) } } @@ -102,3 +105,35 @@ impl<'a> Drop for BtreeIter<'a> { unsafe { c::bch2_trans_iter_exit(self.raw.trans, &mut self.raw) } } } + +pub struct BkeySC<'a> { + pub k: &'a c::bkey, + pub v: &'a c::bch_val, +} + +impl<'a, 'b> BkeySC<'a> { + unsafe fn to_raw(&self) -> c::bkey_s_c { + c::bkey_s_c { k: self.k, v: self.v } + } + + pub fn to_text(&'a self, fs: &'b Fs) -> BkeySCToText<'a, 'b> { + BkeySCToText { k: self, fs } + } +} + +pub struct BkeySCToText<'a, 'b> { + k: &'a BkeySC<'a>, + fs: &'b Fs, +} + +impl<'a, 'b> fmt::Display for BkeySCToText<'a, 'b> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buf = c::printbuf::new(); + + unsafe { c::bch2_bkey_val_to_text(&mut buf, self.fs.raw, self.k.to_raw()) }; + + let s = unsafe { CStr::from_ptr(buf.buf) }; + let s = s.to_str().unwrap(); + write!(f, "{}", s) + } +} diff --git a/rust-src/bch_bindgen/src/lib.rs b/rust-src/bch_bindgen/src/lib.rs index b1474bc2..e853edbb 100644 --- a/rust-src/bch_bindgen/src/lib.rs +++ b/rust-src/bch_bindgen/src/lib.rs @@ -154,26 +154,3 @@ impl FromStr for c::bpos { Ok(c::bpos { inode: ino, offset: off, snapshot: snp }) } } - -pub struct BkeySCToText<'a, 'b> { - k: &'a c::bkey_s_c, - fs: &'b fs::Fs, -} - -impl<'a, 'b> fmt::Display for BkeySCToText<'a, 'b> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buf = c::printbuf::new(); - - unsafe { c::bch2_bkey_val_to_text(&mut buf, self.fs.raw, *self.k) }; - - let s = unsafe { CStr::from_ptr(buf.buf) }; - let s = s.to_str().unwrap(); - write!(f, "{}", s) - } -} - -impl c::bkey_s_c { - pub fn to_text<'a, 'b>(&'a self, fs: &'b fs::Fs) -> BkeySCToText<'a, 'b> { - BkeySCToText { k: self, fs } - } -} diff --git a/rust-src/src/cmd_list.rs b/rust-src/src/cmd_list.rs index 1d71bf9e..15f3f71f 100644 --- a/rust-src/src/cmd_list.rs +++ b/rust-src/src/cmd_list.rs @@ -17,10 +17,8 @@ fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> { BtreeIterFlags::PREFETCH); while let Some(k) = iter.peek_and_restart()? { - unsafe { - if (*k.k).p > opt.end { - break; - } + if k.k.p > opt.end { + break; } println!("{}", k.to_text(fs)); |