Implement VFS quota support
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

- Add VfsQuota and VfsQuotaUsage structs
- Add quota methods to VfsBackend trait:
  - set_quota: set space/file limits
  - get_quota: retrieve quota settings
  - get_quota_usage: current usage stats
  - check_quota: pre-write check
- Implement LocalFs quota support:
  - Uses .quota metadata file
  - JSON storage for quota limits
  - Recursive size/file counting
  - Hidden files excluded (.quota, .snapshots)

Enables SMB per-share/user quota enforcement.

All 229 tests pass.
This commit is contained in:
Warren
2026-06-20 22:17:50 +08:00
parent f016525687
commit 9c44bd5929
2 changed files with 154 additions and 1 deletions

View File

@@ -195,6 +195,28 @@ pub trait VfsBackend: Send + Sync {
fn snapshot_info(&self, _path: &Path, _name: &str) -> Result<VfsSnapshotInfo, VfsError> {
Err(VfsError::Unsupported("snapshot_info".to_string()))
}
// ===== Quota support =====
/// 设置配额限制(字节)
fn set_quota(&self, _path: &Path, _quota: &VfsQuota) -> Result<(), VfsError> {
Err(VfsError::Unsupported("set_quota".to_string()))
}
/// 获取配额信息
fn get_quota(&self, _path: &Path) -> Result<VfsQuota, VfsError> {
Err(VfsError::Unsupported("get_quota".to_string()))
}
/// 获取配额使用情况
fn get_quota_usage(&self, _path: &Path) -> Result<VfsQuotaUsage, VfsError> {
Err(VfsError::Unsupported("get_quota_usage".to_string()))
}
/// 检查配额(写入前检查)
fn check_quota(&self, _path: &Path, _size: u64) -> Result<bool, VfsError> {
Ok(true) // Default: no quota, always allow
}
}
/// 快照信息
@@ -209,3 +231,31 @@ pub struct VfsSnapshotInfo {
/// 是否只读
pub read_only: bool,
}
/// 配额设置
#[derive(Debug, Clone)]
pub struct VfsQuota {
/// 空间限制字节0表示无限制
pub space_limit: u64,
/// 文件数量限制0表示无限制
pub file_limit: u64,
/// 用户ID可选
pub user_id: Option<String>,
/// 软限制(字节),超过时警告
pub soft_limit: u64,
/// 宽限期(秒)
pub grace_period: u64,
}
/// 配额使用情况
#[derive(Debug, Clone)]
pub struct VfsQuotaUsage {
/// 已使用空间(字节)
pub space_used: u64,
/// 文件数量
pub files_used: u64,
/// 是否超过软限制
pub over_soft_limit: bool,
/// 是否超过硬限制
pub over_hard_limit: bool,
}