Advance seqnum in create and destroy local_slice_mapping

This commit is contained in:
toninov 2025-10-03 23:09:28 +02:00
parent 3e231d0cd7
commit b4686a398e
No known key found for this signature in database
5 changed files with 26 additions and 10 deletions

View file

@ -31,13 +31,13 @@ void sflite_discard_work_fn(struct work_struct *work)
unsigned long flags;
u32 lsi = sio->lsi;
u32 psi;
int err = 0;
/* Mutual exclusion with FLUSHes */
if (down_read_interruptible(&svol->posmap.flush_lock)) {
orig_bio->bi_status = BLK_STS_IOERR;
goto unlock;
}
/* Lock the position map */
spin_lock_irqsave(&svol->posmap.lock, flags);
@ -52,7 +52,7 @@ void sflite_discard_work_fn(struct work_struct *work)
}
/* Unmap the slice */
sflite_destroy_local_slice_mapping(svol, lsi);
err = sflite_destroy_local_slice_mapping(svol, lsi);
unlock:
/* Unlock */
@ -63,7 +63,7 @@ unlock:
/* WARNING: it is crucial that the original bio is terminated here and never
reaches the block device, otherwise the effect of a TRIM on the block device
would be obvious, and likely to break plausible deniability */
orig_bio->bi_status = BLK_STS_OK;
orig_bio->bi_status = errno_to_blk_status(err);
bio_endio(orig_bio);
return;
}

View file

@ -314,7 +314,7 @@ int sflite_flush_posmap(struct sflite_volume *svol, struct bio *orig_bio, gfp_t
* If some CWBs failed, we return an error (then failing the upper-layer
* bio in the caller, if there is one), but that doesn't mean aborting
* entirely, because we can still mark some blocks as clean.
* Here, we need to lock. */
* Here, we need to lock again. */
down_write(&svol->posmap.flush_lock); // Not killable, for simplicity
err = mark_posmap_blocks_clean(svol);
bitmap_clear(svol->posmap.cwb_error, 0, nblocks);

View file

@ -64,6 +64,7 @@ static int __peek_next_free_psi(struct sflite_device *sdev, u32 *psi)
static void __create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 psi, bool set_dirty)
{
struct sflite_device *sdev = svol->sdev;
u32 block = lsi/SFLITE_PSIS_PER_BLOCK;
/* Grab it from the device (NOCHECK whether PSI is taken already, or OOB) */
__set_bit(psi, sdev->occupation_bitmap);
@ -78,7 +79,8 @@ static void __create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u3
svol->posmap.entries[lsi] = psi;
svol->posmap.nr_mapped_slices++;
if (likely(set_dirty)) {
__set_bit(lsi/SFLITE_PSIS_PER_BLOCK, svol->posmap.dirty);
__set_bit(block, svol->posmap.dirty);
svol->posmap.seqnum[block] += 1; // Wrap around, no problem
}
return;
@ -91,6 +93,7 @@ static void __create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u3
int sflite_create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 *psi)
{
struct sflite_device *sdev = svol->sdev;
u32 block = lsi/SFLITE_PSIS_PER_BLOCK;
int err;
/* Bounds check TODO redundant? */
@ -99,6 +102,11 @@ int sflite_create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 *
/* Check LSI is unmapped TODO redundant? */
if (unlikely(svol->posmap.entries[lsi] != SFLITE_PSI_INVALID))
return -EINVAL;
/* Overwhelmingly unlikely: needs 16384 create/destroy on the same
* posmap block while a FLUSH is pending. */
if (unlikely(test_bit(block, svol->posmap.flush_pending) &&
(svol->posmap.seqnum[block] + 1 == svol->posmap.snap_seqnum[block])))
return -EAGAIN;
/* Create mapping */
err = __peek_next_free_psi(sdev, psi);
@ -115,10 +123,17 @@ int sflite_create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 *
*/
int sflite_destroy_local_slice_mapping(struct sflite_volume *svol, u32 lsi)
{
u32 block = lsi/SFLITE_PSIS_PER_BLOCK;
/* Bounds check */
if (unlikely(lsi >= svol->sdev->tot_slices)) {
return -EINVAL;
}
/* Overwhelmingly unlikely: needs 16384 create/destroy on the same
* posmap block while a FLUSH is pending. */
if (unlikely(test_bit(block, svol->posmap.flush_pending) &&
(svol->posmap.seqnum[block] + 1 == svol->posmap.snap_seqnum[block])))
return -EAGAIN;
/* Unassign the PSI */
svol->posmap.entries[lsi] = SFLITE_PSI_INVALID;
@ -131,7 +146,8 @@ int sflite_destroy_local_slice_mapping(struct sflite_volume *svol, u32 lsi)
requiring reload/close-open? */
/* Set the dirty bit in position map */
__set_bit(lsi/SFLITE_PSIS_PER_BLOCK, svol->posmap.dirty);
__set_bit(block, svol->posmap.dirty);
svol->posmap.seqnum[block] += 1; // Wrap around, no problem
return 0;
}

View file

@ -107,7 +107,7 @@ static void sflite_decrypt_work_fn(struct work_struct *work)
struct bio *orig_bio = io->orig_bio;
struct bio *phys_bio = io->phys_bio;
struct bio_vec bvl = bio_iovec(orig_bio);
int err;
int err = 0;
/* If physical bio failed, then fail-fast */
if (unlikely(phys_bio->bi_status != BLK_STS_OK)) {

View file

@ -42,7 +42,7 @@ void sflite_write_work_fn(struct work_struct *work)
u32 block_offset = io->block_offset;
u32 psi;
unsigned long flags;
int err;
int err = 0;
// Catch FUA-tagged request early: unsupported TODO improve and support - BUG: this causes a bug, comment out for now
//if (orig_bio->bi_opf & REQ_FUA) {
@ -68,12 +68,12 @@ void sflite_write_work_fn(struct work_struct *work)
err = sflite_create_local_slice_mapping(svol, lsi, &psi);
spin_unlock(&sdev->slices_lock);
if (unlikely(err)){
DMERR("Could not create slice mapping; error %d", err);
DMWARN("Could not create slice mapping; error %d", err);
/* Unlock */
spin_unlock_irqrestore(&svol->posmap.lock, flags);
up_read(&svol->posmap.flush_lock);
/* End of critical section: fail bio */
orig_bio->bi_status = BLK_STS_IOERR;
orig_bio->bi_status = errno_to_blk_status(err);
goto endio;
}
}