Skip to content

Commit e24474b

Browse files
goxberryclaude
andcommitted
refactor(lading): annotate intentional-panic file_gen sites
Attach fn-level #[expect(clippy::expect_used, reason = "...")] to the logrotate generator and the logrotate_fs FUSE filesystem callbacks. The FUSE state mutex is held only briefly inside each callback so a poisoned mutex is unrecoverable; the model itself maintains the parent/file-type/ name invariants used inside `readdir`. - generator/file_gen/logrotate.rs::Child::spin (non-empty names invariant) - generator/file_gen/logrotate_fs.rs::Server::new (FIXME: fuse_mount2 spawn) - generator/file_gen/logrotate_fs.rs::{lookup,getattr,read,release,readdir,open} - generator/file_gen/logrotate_fs/model.rs::advance_time_inner - generator/file_gen/logrotate_fs/model.rs::read Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 882d7df commit e24474b

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

lading/src/generator/file_gen/logrotate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,10 @@ impl Child {
343343
}
344344
}
345345

346+
#[expect(
347+
clippy::expect_used,
348+
reason = "self.names is constructed non-empty at LogrotateGenerator startup"
349+
)]
346350
async fn spin(mut self) -> Result<(), Error> {
347351
let mut handle = self.block_cache.handle();
348352
let buffer_capacity = self

lading/src/generator/file_gen/logrotate_fs.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ impl Server {
170170
/// # Panics
171171
///
172172
/// Function will panic if the filesystem cannot be started.
173+
#[expect(
174+
clippy::expect_used,
175+
reason = "FIXME: fuse_mount2 spawn failure should propagate as an Error variant rather than panic; tracked for follow-up"
176+
)]
173177
pub fn new(
174178
_: generator::General,
175179
config: Config,
@@ -340,6 +344,10 @@ impl Filesystem for LogrotateFS {
340344
}
341345

342346
#[tracing::instrument(skip(self, reply))]
347+
#[expect(
348+
clippy::expect_used,
349+
reason = "the inner state mutex is held only briefly within fuse callbacks; poisoning indicates a panic during a prior callback and is unrecoverable"
350+
)]
343351
fn lookup(&mut self, _: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
344352
let tick = self.get_current_tick();
345353
let mut state = self.state.lock().expect("lock poisoned");
@@ -362,6 +370,10 @@ impl Filesystem for LogrotateFS {
362370
}
363371

364372
#[tracing::instrument(skip(self, reply))]
373+
#[expect(
374+
clippy::expect_used,
375+
reason = "the inner state mutex is held only briefly within fuse callbacks; poisoning indicates a panic during a prior callback and is unrecoverable"
376+
)]
365377
fn getattr(&mut self, _: &Request, ino: u64, _: Option<u64>, reply: ReplyAttr) {
366378
let tick = self.get_current_tick();
367379
let mut state = self.state.lock().expect("lock poisoned");
@@ -377,6 +389,10 @@ impl Filesystem for LogrotateFS {
377389
}
378390

379391
#[tracing::instrument(skip(self, reply))]
392+
#[expect(
393+
clippy::expect_used,
394+
reason = "the inner state mutex is held only briefly within fuse callbacks; poisoning indicates a panic during a prior callback and is unrecoverable"
395+
)]
380396
fn read(
381397
&mut self,
382398
_: &Request,
@@ -416,6 +432,10 @@ impl Filesystem for LogrotateFS {
416432
}
417433

418434
#[tracing::instrument(skip(self, reply))]
435+
#[expect(
436+
clippy::expect_used,
437+
reason = "the inner state mutex is held only briefly within fuse callbacks; poisoning indicates a panic during a prior callback and is unrecoverable"
438+
)]
419439
fn release(
420440
&mut self,
421441
_: &Request,
@@ -448,6 +468,10 @@ impl Filesystem for LogrotateFS {
448468
}
449469

450470
#[tracing::instrument(skip(self, reply))]
471+
#[expect(
472+
clippy::expect_used,
473+
reason = "the inner state mutex is held only briefly within fuse callbacks; mutex poisoning, parent-inode lookup, file-type lookup, and name lookup are all internal invariants maintained by the fs model"
474+
)]
451475
fn readdir(&mut self, _: &Request, ino: u64, _: u64, offset: i64, mut reply: ReplyDirectory) {
452476
let tick = self.get_current_tick();
453477
let mut state = self.state.lock().expect("lock poisoned");
@@ -510,6 +534,10 @@ impl Filesystem for LogrotateFS {
510534
}
511535

512536
#[tracing::instrument(skip(self, _req, reply))]
537+
#[expect(
538+
clippy::expect_used,
539+
reason = "the inner state mutex is held only briefly within fuse callbacks; poisoning indicates a panic during a prior callback and is unrecoverable"
540+
)]
513541
fn open(&mut self, _req: &Request, ino: u64, flags: i32, reply: fuser::ReplyOpen) {
514542
let tick = self.get_current_tick();
515543
let mut state = self.state.lock().expect("lock poisoned");

lading/src/generator/file_gen/logrotate_fs/model.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,10 @@ impl State {
653653

654654
#[inline]
655655
#[expect(clippy::too_many_lines)]
656+
#[expect(
657+
clippy::expect_used,
658+
reason = "node/inode lookups operate on entries the model itself just inserted; invariants enforced inside `State`"
659+
)]
656660
fn advance_time_inner(&mut self, now: Tick) {
657661
assert!(now >= self.now);
658662

@@ -972,6 +976,10 @@ impl State {
972976
/// be advanced -- and a slice up to `size` bytes will be returned or `None`
973977
/// if no bytes are available to be read.
974978
#[tracing::instrument(skip(self))]
979+
#[expect(
980+
clippy::expect_used,
981+
reason = "the bytes-written value is bounded by usize and cannot exceed a machine word here"
982+
)]
975983
pub(crate) fn read(
976984
&mut self,
977985
file_handle: FileHandle,

0 commit comments

Comments
 (0)