# Loop Device 架构设计

本文档阐述 DragonOS 中 loop 设备子系统的架构设计思路，用于指导开发和后续演进。

## 问题背景

在操作系统开发中，我们经常面临这样的需求：
- 如何将一个镜像文件当作块设备使用？
- 如何在不重启系统的情况下动态创建/删除虚拟块设备？

loop 设备正是解决这些问题的关键组件。

## 系统架构定位

loop 设备在 DragonOS 架构中扮演着"虚拟化桥梁"的角色：

```
用户态应用
     ↓
loop-control 接口 (字符设备)
     ↓
LoopManager (设备生命周期管理)
     ↓
LoopDevice[] (虚拟块设备数组)
     ↓
块设备层 ←→ 后端文件系统
```

这种分层设计的核心思想是：**将控制平面与数据平面分离**。

## 核心设计哲学

### 1. 状态驱动的设备管理

我们仿照linux设计引入状态机来管理设备生命周期

```
Unbound → Bound → Rundown → Deleting
    ↓       ↓         ↓
Deleting  Unbound  Deleting
```

**设计考量**：
- 防止非法状态转换（如直接在 Bound 状态删除设备）
- 提供清晰的设备生命周期语义
- 为未来的扩展（如设备热插拔）奠定基础

### 2. 双重接口策略

我们的设计刻意区分了两种接口：

**字符控制接口** (`/dev/loop-control`)：
- 负责设备的生命周期管理
- 提供用户友好的设备分配/回收机制
- 与 Linux 标准接口保持兼容

**块设备接口** (`/dev/loopX`)：
- 专注于数据读写功能
- 提供标准的块设备语义
- 支持偏移、大小限制等高级功能

**设计价值**：这种分离使得控制逻辑与数据路径互不干扰，提高了系统的可维护性。

### 3. 安全性优先

在与用户态交互时，我们采用了多重安全检查：

- **参数边界检查**：所有偏移和大小都必须 LBA 对齐
- **内存安全**：使用 `UserBufferReader/Writer` 进行用户态数据拷贝
- **权限验证**：只读设备拒绝写入操作
- **状态验证**：每个操作前都检查当前设备状态是否允许

## 模块协作架构

### LoopManager 的定位
LoopManager 不是简单的设备数组管理器，而是整个子系统的"调度中心"：

- **设备分配策略**：采用"就近分配"原则，优先复用空闲设备
- **资源池管理**：预注册 8 个设备，避免运行时分配开销
- **并发安全**：所有设备操作都在锁保护下进行

### LoopDevice 的抽象设计
LoopDevice 的核心抽象是"**后端文件的块设备视图**"：

```
用户视角          内部实现
/dev/loop0  ←→   文件偏移 + 大小限制
  块0-100           文件偏移0-51200
  块101-200         文件偏移51200-102400
```

这种设计允许用户将文件的任意部分映射为块设备，为容器等应用场景提供了极大的灵活性。

## 关键设计

### 为什么选择 256 个设备上限？
- 足够满足大多数应用场景需求
- 避免无限制增长导致的资源耗尽
- 与 Linux 系统默认上限保持一致，保证兼容性

### 为什么预注册 8 个设备？
- 覆盖常见的测试场景（通常不超过 4-5 个）
- 减少首次使用的等待时间
- 提供一个合理的初始工作集

### 为什么使用 SpinLock 而不是其他锁？
- loop 设备操作大多是短时操作
- 避免复杂的锁层级和死锁问题
- 简化实现，提高性能

## 兼容性考量

我们的设计在很大程度上参考了 Linux loop 驱动的接口，这是有意的选择：

1. **用户态软件兼容**：现有的 loop 工具无需修改即可使用
2. **API 契约一致性**：避免因接口差异导致的潜在问题
3. **社区知识复用**：开发者可以复用现有的 loop 设备知识

## 总结

DragonOS 的 loop 设备设计遵循以下核心原则：
1. **架构清晰**：控制平面与数据平面分离
2. **状态安全**：基于状态机的设备生命周期管理
3. **接口兼容**：与 Linux 标准接口保持兼容
4. **扩展友好**：为未来功能预留架构空间
5. **测试完备**：通过多层级测试保证质量

