You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux 0.11块设备读操作为何用锁互斥?非仅写操作需锁?

Understanding Buffer Locks for Reads in Linux 0.11

Great question—let's break this down using the Linux 0.11 make_request code you shared. Early kernels like 0.11 prioritize simplicity and correctness over fine-grained concurrency, which explains these design choices perfectly.

Why do read operations block each other with locks?

At first glance, it might seem like reads shouldn't need mutual exclusion, but the buffer head (struct buffer_head) acts as a critical disk cache intermediary, and locking solves two core problems:

  • Preventing redundant disk I/O: If two processes try to read the same disk block simultaneously, without locking, both will check bh->b_uptodate, see it's 0 (meaning the block isn't cached yet), and submit separate read requests to the disk. This wastes disk bandwidth and system resources. With locking, the first process locks the buffer, submits the request, and the second process waits. Once the first process's I/O completes, it marks bh->b_uptodate = 1 and unlocks the buffer. The second process then wakes up, sees the buffer is already up-to-date, and can return the cached data immediately without hitting the disk.

  • Avoiding partial/invalid data: While a read I/O is in progress, the buffer's data is being filled incrementally by the disk controller. If another process tried to access the buffer without locking, it would read partial or inconsistent data. The lock ensures that only one process can interact with the buffer while I/O is active, guaranteeing data integrity.

Looking at your code snippet, this logic is front and center:

lock_buffer (bh);
if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
    unlock_buffer (bh);
    return;
}

After locking, if the buffer is already up-to-date (for reads), the process unlocks and returns immediately. Without the lock, this check-and-use would be a race condition—two processes could both decide to submit duplicate I/O requests.

Why does Linux 0.11 use an exclusive lock for reads?

Linux 0.11 doesn't implement read-write locks (which allow multiple concurrent readers but block writers) for buffer heads. The lock here is a simple exclusive lock (bh->b_lock is a boolean flag: 1 = locked, 0 = unlocked). This is a deliberate simplification for the early kernel:

  • Minimal implementation overhead: Read-write locks add complexity—tracking reader counts, handling writer starvation, and managing state transitions all require extra code and runtime overhead. For a small kernel like 0.11, which targets limited hardware resources, keeping locking logic simple was a top priority.

  • Low concurrency needs: Early Unix-like systems ran far fewer processes simultaneously compared to modern systems. The occasional cost of reader blocking was negligible compared to the simplicity of using a single exclusive lock for all buffer operations (reads and writes).

Even with an exclusive lock, the performance hit for reads is minimal: once the first process finishes caching the block, all subsequent readers can access it immediately without waiting (since b_uptodate is set, they unlock and return right away).


内容的提问来源于stack exchange,提问作者terry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:45:28