mirror of
https://codeberg.org/shufflecake/shufflecake-c.git
synced 2025-12-27 06:04:57 -05:00
finish docs
This commit is contained in:
parent
10d5d294ee
commit
fc671f3388
1 changed files with 56 additions and 9 deletions
|
|
@ -61,10 +61,10 @@ Let us start with the FLUSH handler, and its helper functions:
|
|||
|
||||
```rust
|
||||
fn flush() {
|
||||
RWSEM.down_write();
|
||||
down_write(RWSEM);
|
||||
// Populate the FLUSH state, while we are holding the locks
|
||||
err = prepare_cwbs();
|
||||
RWSEM.up_write();
|
||||
up_write(RWSEM);
|
||||
// After unlocking, WRITEs and DISCARDs are no longer blocked and
|
||||
// can go through, potentially re-dirtying the PosMap blocks
|
||||
|
||||
|
|
@ -74,13 +74,13 @@ fn flush() {
|
|||
// It is important to first wait for all CWB callbacks to finish.
|
||||
err = DEV.flush();
|
||||
|
||||
RWSEM.down_write();
|
||||
down_write(RWSEM);
|
||||
// Some blocks might be marked clean, some might not; the overall FLUSH
|
||||
// operation is successful only if all CWBs were successful
|
||||
err = mark_blocks_clean();
|
||||
clear(CWB_ERROR);
|
||||
clear(FLUSH_PENDING);
|
||||
RWSEM.up_write();
|
||||
up_write(RWSEM);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -174,10 +174,12 @@ Here, we only describe the critical section, rather than the whole handler.
|
|||
|
||||
```rust
|
||||
fn write(lba) {
|
||||
lsi = lba / 256; // 256 4-KiB blocks in a slice
|
||||
block = lsi / 1024; // PosMap block this falls into
|
||||
lsi = lba / 256; // There are 256 4-KiB blocks in a slice
|
||||
block = lsi / 1024; // The PosMap block this falls into
|
||||
|
||||
RWSEM.down_write();
|
||||
// Take both locks
|
||||
RWSEM.down_read();
|
||||
spin_lock(LOCK);
|
||||
psi = ENTRIES[LSI];
|
||||
// If LSI is unmapped, sample a new one and insert in PosMap
|
||||
if (psi == 0xFFFFFFFF) {
|
||||
|
|
@ -192,10 +194,55 @@ fn write(lba) {
|
|||
DIRTY[lsi] = true;
|
||||
SEQNUM[block]++; // Can wrap around
|
||||
}
|
||||
RWSEM.up_write();
|
||||
spin_unlock(LOCK);
|
||||
up_read(RWSEM);
|
||||
}
|
||||
```
|
||||
|
||||
We make sure not to increment the sequence number too many times (16384 times) while a FLUSH is executing; this way, the check `SNAP_SEQNUM[block] == SEQNUM[block]` is, as mentioned, sufficient for `mark_blocks_clean()` to conclude that the block was not re-dirtied.
|
||||
We make sure not to increment the sequence number too many times (16384 times) while a FLUSH is executing; this way, the check `SNAP_SEQNUM[block] == SEQNUM[block]` is, as mentioned, sufficient for `mark_blocks_clean()` to conclude that the block was not re-dirtied. It is anyway overwhelmingly unlikely that the block gets re-dirtied 16384 times before its FLUSH can complete.
|
||||
|
||||
|
||||
#### DISCARD
|
||||
|
||||
The DISCARD's critical section is similar to the WRITE's, in that it dirties a position map block, and increments the sequence number. Just, it does not also act on the device, so it does not need to take the per-device `spinlock`.
|
||||
|
||||
```rust
|
||||
fn discard(lsi) {
|
||||
block = lsi / 1024;
|
||||
|
||||
RWSEM.down_read();
|
||||
spin_lock(LOCK);
|
||||
psi = ENTRIES[LSI];
|
||||
// Unmap LSI
|
||||
if (psi != 0xFFFFFFFF) {
|
||||
// If there's a FLUSH executing, ensure we don't increment the block's
|
||||
// sequence number too many times
|
||||
if (FLUSH_PENDING[block] && (SNAP_SEQNUM[block] + 1 == SEQNUM[block]))
|
||||
return -EAGAIN; // Just try again later, after the FLUSH finished
|
||||
|
||||
ENTRIES[lsi] = 0xFFFFFFFF;
|
||||
DIRTY[lsi] = true;
|
||||
SEQNUM[block]++; // Can wrap around
|
||||
}
|
||||
spin_unlock(LOCK);
|
||||
up_read(RWSEM);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### READ
|
||||
|
||||
The READ handler only takes the `spinlock`, and not the `rwsem`. This allows for concurrency between the READ's and the FLUSH's critical sections: this is fine because READs only *read* the `entries` without writing anything, and because the FLUSH handler does not *write* to `entries`.
|
||||
|
||||
```rust
|
||||
fn read(lba) {
|
||||
lsi = lba / 256; // There are 256 4-KiB blocks in a slice
|
||||
block = lsi / 1024; // The PosMap block this falls into
|
||||
|
||||
spin_lock(LOCK);
|
||||
psi = ENTRIES[LSI];
|
||||
spin_unlock(LOCK);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue