lcpfs 2026.1.102

LCP File System - A ZFS-inspired copy-on-write filesystem for Rust
// Copyright 2025 LunaOS Contributors
// SPDX-License-Identifier: Apache-2.0

//! # Online Defragmentation
//!
//! Compact fragmented files without unmounting the filesystem.
//!
//! ## Overview
//!
//! This module provides online defragmentation capabilities for LCPFS,
//! allowing files to be compacted while the filesystem is active.
//!
//! ## Example
//!
//! ```rust,ignore
//! use lcpfs::defrag::{Defrag, DefragOptions};
//!
//! // Check fragmentation level
//! let score = Defrag::fragmentation_score("pool/data", 42)?;
//! println!("Fragmentation: {}%", score);
//!
//! // Defragment a file
//! let stats = Defrag::defrag_file("pool/data", 42, &DefragOptions::default())?;
//! println!("Consolidated {} extents", stats.extents_before - stats.extents_after);
//! ```

mod defrag;
mod extents;
mod types;

pub use defrag::*;
pub use extents::*;
pub use types::*;

use alloc::string::String;
use alloc::vec::Vec;
use lazy_static::lazy_static;
use spin::Mutex;

lazy_static! {
    /// Global defragmentation task manager
    static ref DEFRAG_TASKS: Mutex<Vec<DefragTask>> = Mutex::new(Vec::new());
}

/// Online defragmentation interface
pub struct Defrag;

impl Defrag {
    /// Get fragmentation score for a file (0-100, higher = more fragmented)
    pub fn fragmentation_score(dataset: &str, object_id: u64) -> Result<u8, DefragError> {
        let extents = get_extents(dataset, object_id)?;
        Ok(calculate_fragmentation(&extents))
    }

    /// Defragment a single file
    pub fn defrag_file(
        dataset: &str,
        object_id: u64,
        options: &DefragOptions,
    ) -> Result<DefragStats, DefragError> {
        defrag_file(dataset, object_id, options)
    }

    /// Defragment all files in a dataset matching criteria
    pub fn defrag_dataset(
        dataset: &str,
        options: &DefragOptions,
    ) -> Result<DefragStats, DefragError> {
        defrag_dataset(dataset, options)
    }

    /// Start background defragmentation task
    pub fn start_background(dataset: &str, options: DefragOptions) -> Result<u64, DefragError> {
        let task_id = start_background_defrag(dataset, options)?;
        Ok(task_id)
    }

    /// Cancel a running defragmentation task
    pub fn cancel(task_id: u64) -> Result<(), DefragError> {
        cancel_defrag_task(task_id)
    }

    /// Get progress of a defragmentation task
    pub fn progress(task_id: u64) -> Result<DefragProgress, DefragError> {
        get_defrag_progress(task_id)
    }

    /// Recommend whether defragmentation is needed
    pub fn recommend(dataset: &str, object_id: u64) -> Result<DefragRecommendation, DefragError> {
        let score = Self::fragmentation_score(dataset, object_id)?;
        let extents = get_extents(dataset, object_id)?;
        Ok(recommend_action(score, &extents))
    }
}