mirror of
https://codeberg.org/shufflecake/shufflecake-c.git
synced 2026-01-10 13:01:16 -05:00
feat:Use pre-shuffled PSI array
This commit is contained in:
parent
46fde04ff5
commit
d7bb03dfb6
5 changed files with 83 additions and 51 deletions
|
|
@ -30,7 +30,7 @@ OBJ_LIST += sysfs/sysfs.o sysfs/devices.o sysfs/volumes.o
|
|||
OBJ_LIST += target/target.o
|
||||
OBJ_LIST += device/device.o device/volumes.o device/rawio.o device/rmap.o device/iv.o
|
||||
OBJ_LIST += volume/volume.o volume/io.o volume/read.o volume/write.o volume/fmap.o
|
||||
OBJ_LIST += utils/string.o utils/bio.o utils/pools.o utils/workqueues.o
|
||||
OBJ_LIST += utils/string.o utils/bio.o utils/pools.o utils/workqueues.o utils/vector.o
|
||||
OBJ_LIST += crypto/rand/rand.o crypto/rand/selftest.o
|
||||
OBJ_LIST += crypto/symkey/symkey.o crypto/symkey/skreq_pool.o crypto/symkey/selftest.o
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "sysfs/sysfs.h"
|
||||
#include "utils/vector.h"
|
||||
#include "log/log.h"
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
|
@ -68,6 +69,9 @@ static bool sflc_dev_acquireId(size_t id);
|
|||
/* Release device ID */
|
||||
static void sflc_dev_releaseId(size_t id);
|
||||
|
||||
/* Initialises and pre-shuffles the PSI array */
|
||||
static int sflc_dev_initAndShufflePsiArray(u32 *psi_array, u32 len);
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
|
|
@ -153,8 +157,8 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t
|
|||
dev->vol_header_size = 1 + nr_pmbs_per_vol + dev->vol_header_nr_iv_blocks;
|
||||
dev->dev_header_size = 1 + (SFLC_DEV_MAX_VOLUMES * dev->vol_header_size);
|
||||
|
||||
/* Init rmap lock */
|
||||
mutex_init(&dev->rmap_lock);
|
||||
/* Init slices lock */
|
||||
mutex_init(&dev->slices_lock);
|
||||
/* Allocate reverse slice map */
|
||||
dev->rmap = vmalloc(dev->tot_slices * sizeof(u8));
|
||||
if (!dev->rmap) {
|
||||
|
|
@ -164,6 +168,21 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t
|
|||
}
|
||||
/* Initialise it */
|
||||
memset(dev->rmap, SFLC_DEV_RMAP_INVALID_VOL, dev->tot_slices * sizeof(u8));
|
||||
/* Allocate PSI array */
|
||||
dev->shuffled_psi_array = vmalloc(dev->tot_slices * sizeof(u32));
|
||||
if (!dev->shuffled_psi_array) {
|
||||
pr_err("Could not allocate PSI array\n");
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_psi_array;
|
||||
}
|
||||
/* Initialise it and pre-shuffle it */
|
||||
err = sflc_dev_initAndShufflePsiArray(dev->shuffled_psi_array, dev->tot_slices);
|
||||
if (err) {
|
||||
pr_err("Could not init-and-shuffle PSI array: error %d", err);
|
||||
goto err_initshuffle_psi_array;
|
||||
}
|
||||
/* Init related counter */
|
||||
dev->shuffled_psi_ctr = 0;
|
||||
|
||||
/* Init IV cache lock */
|
||||
mutex_init(&dev->iv_cache_lock);
|
||||
|
|
@ -198,6 +217,9 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t
|
|||
err_sysfs:
|
||||
kfree(dev->iv_cache);
|
||||
err_alloc_iv_cache:
|
||||
err_initshuffle_psi_array:
|
||||
vfree(dev->shuffled_psi_array);
|
||||
err_alloc_psi_array:
|
||||
vfree(dev->rmap);
|
||||
err_alloc_rmap:
|
||||
kfree(dev->bdev_path);
|
||||
|
|
@ -250,6 +272,9 @@ bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev)
|
|||
/* IV cache */
|
||||
kfree(dev->iv_cache);
|
||||
|
||||
/* PSI array */
|
||||
vfree(dev->shuffled_psi_array);
|
||||
|
||||
/* Reverse slice map */
|
||||
vfree(dev->rmap);
|
||||
|
||||
|
|
@ -271,7 +296,7 @@ bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev)
|
|||
* PRIVATE FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Acquire devoce ID, returns false if not possible */
|
||||
/* Acquire device ID, returns false if not possible */
|
||||
static bool sflc_dev_acquireId(size_t id)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
|
@ -315,3 +340,18 @@ static void sflc_dev_releaseId(size_t id)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Initialises and pre-shuffles the PSI array */
|
||||
static int sflc_dev_initAndShufflePsiArray(u32 *psi_array, u32 len)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
/* Init to the identity map */
|
||||
for (i = 0; i < len; i++) {
|
||||
psi_array[i] = i;
|
||||
}
|
||||
|
||||
/* Permute */
|
||||
return sflc_vec_u32shuffle(psi_array, len);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,8 +112,12 @@ struct sflc_device_s
|
|||
int vol_cnt;
|
||||
|
||||
/* Reverse slice map, associating PSIs to volume indices */
|
||||
struct mutex rmap_lock;
|
||||
u8 * rmap;
|
||||
/* Shuffled array of PSIs, with advancement counter */
|
||||
u32 *shuffled_psi_array;
|
||||
u32 shuffled_psi_ctr;
|
||||
/* Lock for all three of these objects */
|
||||
struct mutex slices_lock;
|
||||
|
||||
/* Slices info */
|
||||
u32 tot_slices;
|
||||
|
|
@ -192,16 +196,14 @@ bool sflc_dev_removeVolume(sflc_Device * dev, int vol_idx);
|
|||
int sflc_dev_rwSector(sflc_Device * dev, struct page * page, sector_t sector, int rw);
|
||||
|
||||
|
||||
/* The caller needs to hold rmap_lock to call these functions */
|
||||
/* The caller needs to hold slices_lock to call these functions */
|
||||
|
||||
/* Sets the PSI as owned by the given volume. Returns < 0 if already taken. */
|
||||
int sflc_dev_setRmap(sflc_Device * dev, u32 psi, u8 vol_idx);
|
||||
|
||||
/* Sets the PSI as free. */
|
||||
void sflc_dev_unsetRmap(sflc_Device * dev, u32 psi);
|
||||
/* Sets the PSI as owned by the given volume (also decreases free_slices).
|
||||
* Returns < 0 if already taken. */
|
||||
int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx);
|
||||
|
||||
/* Returns a random free physical slice, or < 0 if error */
|
||||
s32 sflc_dev_getRandomFreePsi(sflc_Device * dev);
|
||||
s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev);
|
||||
|
||||
|
||||
/* These functions provide concurrent-safe access to the entries of the IV cache.
|
||||
|
|
|
|||
|
|
@ -41,8 +41,9 @@
|
|||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Sets the PSI as owned by the given volume. Returns < 0 if already taken. */
|
||||
int sflc_dev_setRmap(sflc_Device * dev, u32 psi, u8 vol_idx)
|
||||
/* Sets the PSI as owned by the given volume (also decreases free_slices).
|
||||
* Returns < 0 if already taken. */
|
||||
int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx)
|
||||
{
|
||||
u8 prev_vol_idx;
|
||||
|
||||
|
|
@ -66,38 +67,27 @@ int sflc_dev_setRmap(sflc_Device * dev, u32 psi, u8 vol_idx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Sets the PSI as free. */
|
||||
void sflc_dev_unsetRmap(sflc_Device * dev, u32 psi)
|
||||
{
|
||||
/* Bounds check */
|
||||
if (psi >= dev->tot_slices) {
|
||||
pr_err("Requested to unset ownership for invalid PSI\n");
|
||||
}
|
||||
|
||||
/* Just unset it */
|
||||
dev->rmap[psi] = SFLC_DEV_RMAP_INVALID_VOL;
|
||||
dev->free_slices += 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Returns a random free physical slice, or < 0 if error */
|
||||
s32 sflc_dev_getRandomFreePsi(sflc_Device * dev)
|
||||
s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev)
|
||||
{
|
||||
s32 psi;
|
||||
u32 psi;
|
||||
|
||||
/* Check that there are free slices */
|
||||
if (!dev->free_slices) {
|
||||
pr_crit("Whoah! No free PSIs on the device! Catastrophe!");
|
||||
pr_crit("Whoah! No free PSIs on the device! Catastrophe!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* Repeatedly sample until you find a free one */
|
||||
/* Repeatedly advance the counter in the shuffled array
|
||||
* until you find a free one */
|
||||
do {
|
||||
psi = sflc_rand_uniform(dev->tot_slices);
|
||||
if (psi < 0) {
|
||||
pr_err("Could not sample random PSI\n");
|
||||
return -EINVAL;
|
||||
psi = dev->shuffled_psi_array[dev->shuffled_psi_ctr];
|
||||
dev->shuffled_psi_ctr += 1;
|
||||
|
||||
if (dev->shuffled_psi_ctr >= dev->tot_slices) {
|
||||
pr_err("Double catastrophe! No free PSIs on the device, and didn't catch it before!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
} while (dev->rmap[psi] != SFLC_DEV_RMAP_INVALID_VOL);
|
||||
|
||||
|
|
|
|||
|
|
@ -125,12 +125,12 @@ int sflc_vol_loadFmap(sflc_Volume * vol)
|
|||
iv_ptr = kmap(iv_page);
|
||||
data_ptr = kmap(data_page);
|
||||
|
||||
/* Lock both the forward and the reverse position maps */
|
||||
/* Lock both the forward map and the slices structs */
|
||||
if (mutex_lock_interruptible(&vol->fmap_lock)) {
|
||||
pr_err("Interrupted while waiting to lock fmap\n");
|
||||
return -EINTR;
|
||||
}
|
||||
if (mutex_lock_interruptible(&dev->rmap_lock)) {
|
||||
if (mutex_lock_interruptible(&dev->slices_lock)) {
|
||||
pr_err("Interrupted while waiting to lock rmap\n");
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
return -EINTR;
|
||||
|
|
@ -182,7 +182,7 @@ int sflc_vol_loadFmap(sflc_Volume * vol)
|
|||
vol->fmap[lsi] = psi;
|
||||
/* Also add it to the device's rmap and to the count, if LSI is actually mapped */
|
||||
if (psi != SFLC_VOL_FMAP_INVALID_PSI) {
|
||||
sflc_dev_setRmap(dev, psi, vol->vol_idx);
|
||||
sflc_dev_markPsiTaken(dev, psi, vol->vol_idx);
|
||||
vol->mapped_slices += 1;
|
||||
}
|
||||
|
||||
|
|
@ -195,8 +195,8 @@ int sflc_vol_loadFmap(sflc_Volume * vol)
|
|||
err = 0;
|
||||
|
||||
out:
|
||||
/* Unlock both maps */
|
||||
mutex_unlock(&dev->rmap_lock);
|
||||
/* Release both locks */
|
||||
mutex_unlock(&dev->slices_lock);
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
/* Kunmap pages */
|
||||
kunmap(iv_page);
|
||||
|
|
@ -235,12 +235,12 @@ int sflc_vol_storeFmap(sflc_Volume * vol)
|
|||
iv_ptr = kmap(iv_page);
|
||||
data_ptr = kmap(data_page);
|
||||
|
||||
/* Lock both the forward and the reverse position maps */
|
||||
/* Lock both the forward map and the slices objects */
|
||||
if (mutex_lock_interruptible(&vol->fmap_lock)) {
|
||||
pr_err("Interrupted while waiting to lock fmap\n");
|
||||
return -EINTR;
|
||||
}
|
||||
if (mutex_lock_interruptible(&dev->rmap_lock)) {
|
||||
if (mutex_lock_interruptible(&dev->slices_lock)) {
|
||||
pr_err("Interrupted while waiting to lock rmap\n");
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
return -EINTR;
|
||||
|
|
@ -304,8 +304,8 @@ int sflc_vol_storeFmap(sflc_Volume * vol)
|
|||
err = 0;
|
||||
|
||||
out:
|
||||
/* Unlock both maps */
|
||||
mutex_unlock(&dev->rmap_lock);
|
||||
/* Release both locks */
|
||||
mutex_unlock(&dev->slices_lock);
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
/* Kunmap pages */
|
||||
kunmap(iv_page);
|
||||
|
|
@ -346,18 +346,18 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op)
|
|||
|
||||
/* Otherwise, create a new slice mapping */
|
||||
|
||||
/* Also lock the device's reverse map */
|
||||
if (mutex_lock_interruptible(&dev->rmap_lock)) {
|
||||
/* Also lock the device's slices objects */
|
||||
if (mutex_lock_interruptible(&dev->slices_lock)) {
|
||||
pr_err("Interrupted while waiting to lock the reverse position map\n");
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
/* Get a free physical slice */
|
||||
psi = sflc_dev_getRandomFreePsi(dev);
|
||||
psi = sflc_dev_getNextRandomFreePsi(dev);
|
||||
if (psi < 0) {
|
||||
pr_err("Could not get a random free physical slice; error %d\n", psi);
|
||||
mutex_unlock(&dev->rmap_lock);
|
||||
mutex_unlock(&dev->slices_lock);
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
return psi;
|
||||
}
|
||||
|
|
@ -366,10 +366,10 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op)
|
|||
vol->fmap[lsi] = psi;
|
||||
vol->mapped_slices += 1;
|
||||
/* And in the device's rmap */
|
||||
sflc_dev_setRmap(dev, psi, vol->vol_idx);
|
||||
sflc_dev_markPsiTaken(dev, psi, vol->vol_idx);
|
||||
|
||||
/* Unlock both maps */
|
||||
mutex_unlock(&dev->rmap_lock);
|
||||
mutex_unlock(&dev->slices_lock);
|
||||
mutex_unlock(&vol->fmap_lock);
|
||||
|
||||
return psi;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue