From 31bc3478673032779b4031a664444820f71e9fa1 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 25 Sep 2024 22:38:41 +0200 Subject: [PATCH 01/12] Define device and volume classes OOP-style --- dm-sflc/src/sflc_types.h | 154 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 dm-sflc/src/sflc_types.h diff --git a/dm-sflc/src/sflc_types.h b/dm-sflc/src/sflc_types.h new file mode 100644 index 0000000..4ae0ab6 --- /dev/null +++ b/dm-sflc/src/sflc_types.h @@ -0,0 +1,154 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the + * GNU General Public License along with this program. + * If not, see . + */ + +/** + * This kernel module implements Shufflecake as an in-kernel device driver, + * built on top of the device-mapper framework. + * Shufflecake supports several "modes" (currently Legacy and Lite). Each mode + * is a distinct set of algorithms which implements a specific flavour of the + * Shufflecake scheme; they are very different and largely incompatible with + * each other. For this reason, each mode has its own independent, complete + * implementation - located in a subdirectory of the root - and exposes a + * standardised interface to the top-level "dispatcher", which only takes care + * of the few bookkeeping tasks which are common to all modes, and displays a + * unified view to user space through the sysfs. + * + * In order to achieve an intuitive and maintainable separation between the + * dispatcher and the modes, a "lightweight" OOP-style coding convention is + * followed: not fully general, but just enough to allow for one-level class + * inheritance and type-checked method polymorphism. + * Base "classes" exist to represent devices and volumes (see Shufflecake docs + * to learn what these terms mean): they are structs containing the fields + * needed by the dispatcher for its bookkeeping. Derived "classes" exist to + * represent mode-specific devices and volumes: they are structs embedding a + * base-class struct "by-value", plus their own specific fields. + * Type-checked polymorphism is achieved by having device and volume methods + * take as argument a pointer to a base-class struct, instead of an opaque void + * pointer. The pointer is then "down-cast" in the mode-specific method. + */ + +#ifndef _SFLC_TYPES_H +#define _SFLC_TYPES_H + + +#include + +#include "sflc_constants.h" +#include "legacy/sflc_legacy.h" +#include "lite/sflc_lite.h" + + +/* + *---------------------------- + * Structs + *---------------------------- + */ + +/** + * The virtual table. + * Contains all the concrete method pointers provided by a Shufflecake mode + * (devices + volumes + devmapper). + * It is a field in the base class, but will be set by the constructor of the + * derived class. + */ +struct sflc_mode_ops; + +/** + * Base class for devices. + * It is inherited by derived classes for mode-specific devices. + */ +struct sflc_device_base +{ + /* Shufflecake-unique device ID */ + u32 dev_id; + /* : */ + char name[16]; + /* Shufflecake mode: legacy/lite */ + int mode; + /* Number of (open) volumes */ + u32 nr_volumes; + + /* Sysfs */ + struct kobject kobj; + struct completion kobj_released; + + /* Virtual table */ + struct sflc_mode_ops *ops; +}; + +/** + * Base class for volumes. + * It is inherited by derived classes for mode-specific volumes. + */ +struct sflc_volume_base +{ + /* Backing device */ + struct sflc_device *sdev; + /* Volume name: sflc__ */ + char name[32]; + + /* Sysfs */ + struct kobject kobj; + struct completion kobj_released; + + /* Virtual table */ + struct sflc_mode_ops *ops; +}; + + +/* + *---------------------------- + * Methods + *---------------------------- + */ + +/* Device constructor */ +typedef struct sflc_device_base* (*sflc_mode_dev_ctr_fn) ( + struct dm_target *ti, int argc, char **argv); +/* Device destructor */ +typedef void (*sflc_mode_dev_dtr_fn) (struct sflc_device_base* sd_base); + +/* Volume constructor */ +typedef struct sflc_volume_base* (*sflc_mode_vol_ctr_fn) ( + struct sflc_device_base *sd_base, struct dm_target *ti, + int argc, char **argv); +/* Volume destructor */ +typedef void (*sflc_mode_vol_dtr_fn) (struct sflc_volume_base* sv_base); + +/** + * A Shufflecake mode must provide ctr() and dtr() for devices and volumes, + * as well as devmapper-related methods. + */ +struct sflc_mode_ops +{ + sflc_mode_dev_ctr_fn dev_ctr; + sflc_mode_dev_dtr_fn dev_dtr; + sflc_mode_vol_ctr_fn vol_ctr; + sflc_mode_vol_dtr_fn vol_dtr; + dm_map_fn map; + dm_io_hints_fn io_hints; + dm_iterate_devices_fn iterate_devices; +}; + + +#endif /* _SFLC_TYPES_H */ From e27f738260fbd70347fc391c9ef325e6400b602f Mon Sep 17 00:00:00 2001 From: = Date: Fri, 27 Sep 2024 00:05:54 +0200 Subject: [PATCH 02/12] Minor adjustments --- dm-sflc/src/sflc.h | 82 ++++++++++------------------------------ dm-sflc/src/sflc_types.h | 2 +- 2 files changed, 20 insertions(+), 64 deletions(-) diff --git a/dm-sflc/src/sflc.h b/dm-sflc/src/sflc.h index 1ff8499..896c43e 100644 --- a/dm-sflc/src/sflc.h +++ b/dm-sflc/src/sflc.h @@ -27,58 +27,8 @@ #include +#include "sflc_types.h" #include "sflc_constants.h" -#include "legacy/sflc_legacy.h" -#include "lite/sflc_lite.h" - - -/* - *---------------------------- - * Structs - *---------------------------- - */ - -struct sflc_device -{ - /* Shufflecake-unique device ID */ - u32 dev_id; - /* : */ - char name[16]; - /* Number of volumes */ - u32 nr_volumes; - - /* Mode-specific device struct */ - int mode; - union { - sflegc_Device *sflegc_dev; - struct sflite_device *sflite_dev; - }; - - /* Sysfs */ - struct kobject kobj; - struct completion kobj_released; -}; - -struct sflc_volume -{ - /* Backing device */ - struct sflc_device *sdev; - /* Volume name: sflc__ */ - char name[32]; - - /* Mode-specific volume struct */ - int mode; - union { - sflegc_Volume *sflegc_vol; - struct sflite_volume *sflite_vol; - }; - /* Pointers to concrete, mode-specific callbacks */ - struct target_type *tt; - - /* Sysfs */ - struct kobject kobj; - struct completion kobj_released; -}; /* @@ -87,8 +37,12 @@ struct sflc_volume *---------------------------- */ +/* Every mode provides a full set of algorithms */ +struct sflc_mode_ops **sflc_mode_ops; + +/* Array of all open devices */ extern struct mutex sflc_alldevs_lock; -extern struct sflc_device **sflc_alldevs; +extern struct sflc_device_base **sflc_alldevs; /* Next free device id */ extern u32 sflc_free_devid; /* The lowest free devID */ @@ -99,22 +53,24 @@ extern u32 sflc_free_devid; /* The lowest free devID */ *---------------------------- */ -/* Device */ -struct sflc_device *sflc_dev_create(struct dm_target *ti, int argc, char **argv); -void sflc_dev_destroy(struct sflc_device *sdev); +/* Device base */ +int sflc_dev_base_init(struct sflc_device_base *sd_base, struct dm_target *ti, + int argc, char **argv); +void sflc_dev_base_exit(struct sflc_device_base *sd_base); -/* Volume */ -struct sflc_volume *sflc_vol_create(struct sflc_device *sdev, struct dm_target *ti, - int argc, char **argv); -void sflc_vol_destroy(struct sflc_volume *svol); +/* Volume base */ +int sflc_vol_base_init(struct sflc_volume *sv_base, + struct sflc_device_base *sd_base, struct dm_target *ti, + int argc, char **argv); +void sflc_vol_base_exit(struct sflc_volume_base *sv_base); /* Sysfs */ int sflc_sysfs_init(void); void sflc_sysfs_exit(void); -int sflc_sysfs_register_device(struct sflc_device *sdev); -void sflc_sysfs_unregister_device(struct sflc_device *sdev); -int sflc_sysfs_register_volume(struct sflc_volume *svol); -void sflc_sysfs_unregister_volume(struct sflc_volume *svol); +int sflc_sysfs_register_device_base(struct sflc_device_base *sd_base); +void sflc_sysfs_unregister_device_base(struct sflc_device_base *sd_base); +int sflc_sysfs_register_volume_base(struct sflc_volume_base *sv_base); +void sflc_sysfs_unregister_volume_base(struct sflc_volume_base *sv_base); #endif /* _SFLC_H */ diff --git a/dm-sflc/src/sflc_types.h b/dm-sflc/src/sflc_types.h index 4ae0ab6..5d7347e 100644 --- a/dm-sflc/src/sflc_types.h +++ b/dm-sflc/src/sflc_types.h @@ -84,7 +84,7 @@ struct sflc_device_base /* : */ char name[16]; /* Shufflecake mode: legacy/lite */ - int mode; + u32 mode; /* Number of (open) volumes */ u32 nr_volumes; From c0824a6a2d950653d3c1af11fe49fb95e9b0337d Mon Sep 17 00:00:00 2001 From: = Date: Fri, 27 Sep 2024 21:29:29 +0200 Subject: [PATCH 03/12] Adapt dev_vol.c --- dm-sflc/src/dev_vol.c | 173 +++++++-------------------------------- dm-sflc/src/sflc.h | 8 +- dm-sflc/src/sflc_types.h | 2 +- 3 files changed, 34 insertions(+), 149 deletions(-) diff --git a/dm-sflc/src/dev_vol.c b/dm-sflc/src/dev_vol.c index 6c454b9..2fc94b3 100644 --- a/dm-sflc/src/dev_vol.c +++ b/dm-sflc/src/dev_vol.c @@ -27,183 +27,68 @@ #include "legacy/sflc_legacy.h" -/* Create a sflc_device containing the appropriate mode-specific struct */ -struct sflc_device *sflc_dev_create(struct dm_target *ti, int argc, char **argv) +/* Init a sflc_device_base */ +int sflc_dev_base_init(struct sflc_device_base *sd_base, struct dm_target *ti, + int argc, char **argv) { - struct sflc_device *sdev; u32 dev_id; dev_t devt; - int mode; int err; - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); - if (!sdev) { - DMERR("Could not allocate device"); - return ERR_PTR(-ENOMEM); - } - /* Parse arguments */ - if (sscanf(argv[0], "%d", &mode) != 1) { - err = -EINVAL; - goto bad_parse; - } + if (sscanf(argv[0], "%d", &mode) != 1) + return -EINVAL; sscanf(argv[1], "%u", &dev_id); err = lookup_bdev(argv[2], &devt); - if (err) { - DMERR("Could not look up block device"); - goto bad_parse; - } + if (err) + return err; /* Assign fields */ - sdev->dev_id = dev_id; - sdev->nr_volumes = 0; - sdev->mode = mode; - format_dev_t(sdev->name, devt); + sd_base->dev_id = dev_id; + sd_base->nr_volumes = 0; + format_dev_t(sd_base->name, devt); + /* Fields `mode` and `ops` will be set by the derived constructor */ /* Register with sysfs */ - err = sflc_sysfs_register_device(sdev); + err = sflc_sysfs_register_device_base(sd_base); if (err) - goto bad_sysfs; + return err; - /* Instantiate inner device. Sysfs has to be inited by now */ - switch (mode) - { - case SFLC_MODE_LEGACY: - sdev->sflegc_dev = sflegc_dev_create(ti, argc, argv, &sdev->kobj); - if (IS_ERR(sdev->sflegc_dev)) { - err = PTR_ERR(sdev->sflegc_dev); - goto bad_inner; - } - break; - case SFLC_MODE_LITE: - sdev->sflite_dev = sflite_dev_create(ti, argc, argv, &sdev->kobj); - if (IS_ERR(sdev->sflite_dev)) { - err = PTR_ERR(sdev->sflite_dev); - goto bad_inner; - } - break; - default: - DMERR("Invalid Shufflecake mode %d", mode); - err = -EINVAL; - goto bad_mode; - } - - return sdev; - - -bad_mode: -bad_inner: - sflc_sysfs_unregister_device(sdev); -bad_sysfs: -bad_parse: - kfree(sdev); - return ERR_PTR(err); + return 0; } -void sflc_dev_destroy(struct sflc_device *sdev) +void sflc_dev_base_exit(struct sflc_device_base *sd_base) { - switch (sdev->mode) - { - case SFLC_MODE_LEGACY: - sflegc_dev_destroy(sdev->sflegc_dev); - break; - case SFLC_MODE_LITE: - sflite_dev_destroy(sdev->sflite_dev); - break; - default: - DMCRIT("Destroying device with invalid Shufflecake mode %d", sdev->mode); - return; - } - - sflc_sysfs_unregister_device(sdev); - kfree(sdev); + sflc_sysfs_unregister_device_base(sd_base); } -/* Create a sflc_volume containing the appropriate mode-specific struct */ -struct sflc_volume *sflc_vol_create(struct sflc_device *sdev, struct dm_target *ti, - int argc, char **argv) +/* Init a sflc_volume_base */ +int sflc_vol_base_init(struct sflc_volume_base *sv_base, + struct sflc_device_base *sd_base, struct dm_target *ti, + int argc, char **argv) { - struct sflc_volume *svol; u32 vol_idx; - int mode; int err; - svol = kzalloc(sizeof(*svol), GFP_KERNEL); - if (!svol) { - DMERR("Could not allocate volume"); - return ERR_PTR(-ENOMEM); - } - /* Parse arguments */ - if (sscanf(argv[0], "%d", &mode) != 1) { - err = -EINVAL; - goto bad_parse; - } sscanf(argv[3], "%u", &vol_idx); /* Assign fields */ - svol->mode = mode; - sprintf(svol->name, "sflc_%u_%u", sdev->dev_id, vol_idx); - svol->sdev = sdev; + sprintf(sv_base->name, "sflc_%u_%u", sd_base->dev_id, vol_idx); + sv_base->sd_base = sd_base; + /* Field `ops` will be set by the derived constructor */ /* Register with sysfs */ - err = sflc_sysfs_register_volume(svol); + err = sflc_sysfs_register_volume_base(sv_base); if (err) - goto bad_sysfs; + return err; - /* Instantiate inner volume. Sysfs has to be inited by now */ - switch (mode) - { - case SFLC_MODE_LEGACY: - svol->sflegc_vol = sflegc_vol_create(ti, sdev->sflegc_dev, argc, argv, &svol->kobj); - if (IS_ERR(svol->sflegc_vol)) { - err = PTR_ERR(svol->sflegc_vol); - goto bad_inner; - } - svol->tt = &sflegc_target_type; - break; - case SFLC_MODE_LITE: - svol->sflite_vol = sflite_vol_create(ti, sdev->sflite_dev, argc, argv, &svol->kobj); - if (IS_ERR(svol->sflite_vol)) { - err = PTR_ERR(svol->sflite_vol); - goto bad_inner; - } - svol->tt = &sflite_target_type; - break; - default: - DMERR("Invalid Shufflecake mode %d", mode); - err = -EINVAL; - goto bad_mode; - } - - return svol; - - -bad_mode: -bad_inner: - sflc_sysfs_unregister_volume(svol); -bad_sysfs: -bad_parse: - kfree(svol); - return ERR_PTR(err); + return 0; } -void sflc_vol_destroy(struct sflc_volume *svol) +void sflc_vol_base_exit(struct sflc_volume_base *sv_base) { - switch (svol->mode) - { - case SFLC_MODE_LEGACY: - sflegc_vol_destroy(svol->sflegc_vol); - break; - case SFLC_MODE_LITE: - sflite_vol_destroy(svol->sflite_vol); - break; - default: - DMCRIT("Destroying volume with invalid Shufflecake mode %d", svol->mode); - return; - } - - sflc_sysfs_unregister_volume(svol); - kfree(svol); + sflc_sysfs_unregister_volume_base(sv_base); } + diff --git a/dm-sflc/src/sflc.h b/dm-sflc/src/sflc.h index 896c43e..ed206c1 100644 --- a/dm-sflc/src/sflc.h +++ b/dm-sflc/src/sflc.h @@ -55,13 +55,13 @@ extern u32 sflc_free_devid; /* The lowest free devID */ /* Device base */ int sflc_dev_base_init(struct sflc_device_base *sd_base, struct dm_target *ti, - int argc, char **argv); + int argc, char **argv); void sflc_dev_base_exit(struct sflc_device_base *sd_base); /* Volume base */ -int sflc_vol_base_init(struct sflc_volume *sv_base, - struct sflc_device_base *sd_base, struct dm_target *ti, - int argc, char **argv); +int sflc_vol_base_init(struct sflc_volume_base *sv_base, + struct sflc_device_base *sd_base, struct dm_target *ti, + int argc, char **argv); void sflc_vol_base_exit(struct sflc_volume_base *sv_base); /* Sysfs */ diff --git a/dm-sflc/src/sflc_types.h b/dm-sflc/src/sflc_types.h index 5d7347e..e866013 100644 --- a/dm-sflc/src/sflc_types.h +++ b/dm-sflc/src/sflc_types.h @@ -103,7 +103,7 @@ struct sflc_device_base struct sflc_volume_base { /* Backing device */ - struct sflc_device *sdev; + struct sflc_device *sd_base; /* Volume name: sflc__ */ char name[32]; From 4db71b05a55968420bfcb700f92242325e4b3eb3 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 27 Sep 2024 21:36:52 +0200 Subject: [PATCH 04/12] Adapt sysfs --- dm-sflc/src/sflc_types.h | 2 +- dm-sflc/src/sysfs.c | 72 +++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/dm-sflc/src/sflc_types.h b/dm-sflc/src/sflc_types.h index e866013..2397418 100644 --- a/dm-sflc/src/sflc_types.h +++ b/dm-sflc/src/sflc_types.h @@ -103,7 +103,7 @@ struct sflc_device_base struct sflc_volume_base { /* Backing device */ - struct sflc_device *sd_base; + struct sflc_device_base *sd_base; /* Volume name: sflc__ */ char name[32]; diff --git a/dm-sflc/src/sysfs.c b/dm-sflc/src/sysfs.c index 2ef402d..9782ca8 100644 --- a/dm-sflc/src/sysfs.c +++ b/dm-sflc/src/sysfs.c @@ -87,16 +87,16 @@ void sflc_sysfs_exit() static ssize_t dev_id_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_device *sdev = container_of(kobj, struct sflc_device, kobj); + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); - return sysfs_emit(buf, "%u\n", sdev->dev_id); + return sysfs_emit(buf, "%u\n", sd_base->dev_id); } static ssize_t volumes_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_device *sdev = container_of(kobj, struct sflc_device, kobj); + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); - return sysfs_emit(buf, "%u\n", sdev->nr_volumes); + return sysfs_emit(buf, "%u\n", sd_base->nr_volumes); } @@ -109,47 +109,47 @@ static struct attribute *sflc_device_default_attrs[] = { }; ATTRIBUTE_GROUPS(sflc_device_default); -static void sflc_device_kobj_release(struct kobject *kobj) +static void sflc_device_base_kobj_release(struct kobject *kobj) { - struct sflc_device *sdev = container_of(kobj, struct sflc_device, kobj); - complete(&sdev->kobj_released); + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); + complete(&sd_base->kobj_released); } -static struct kobj_type sflc_device_ktype = { - .release = sflc_device_kobj_release, +static struct kobj_type sflc_device_base_ktype = { + .release = sflc_device_base_kobj_release, .sysfs_ops = &kobj_sysfs_ops, .default_groups = sflc_device_default_groups }; -int sflc_sysfs_register_device(struct sflc_device *sdev) +int sflc_sysfs_register_device_base(struct sflc_device_base *sd_base) { int err; /* Completion */ - init_completion(&sdev->kobj_released); + init_completion(&sd_base->kobj_released); /* Register directory :/ under bdevs/ */ - sdev->kobj.kset = bdevs_kset; - err = kobject_init_and_add(&sdev->kobj, &sflc_device_ktype, NULL, - "%s", sdev->name); + sd_base->kobj.kset = bdevs_kset; + err = kobject_init_and_add(&sd_base->kobj, &sflc_device_base_ktype, NULL, + "%s", sd_base->name); if (err) goto bad; /* Emit uevent */ - kobject_uevent(&sdev->kobj, KOBJ_ADD); + kobject_uevent(&sd_base->kobj, KOBJ_ADD); return 0; bad: - kobject_put(&sdev->kobj); - wait_for_completion(&sdev->kobj_released); + kobject_put(&sd_base->kobj); + wait_for_completion(&sd_base->kobj_released); return err; } -void sflc_sysfs_unregister_device(struct sflc_device *sdev) +void sflc_sysfs_unregister_device_base(struct sflc_device_base *sd_base) { - kobject_put(&sdev->kobj); - wait_for_completion(&sdev->kobj_released); + kobject_put(&sd_base->kobj); + wait_for_completion(&sd_base->kobj_released); } @@ -159,45 +159,47 @@ void sflc_sysfs_unregister_device(struct sflc_device *sdev) *---------------------------- */ -static void sflc_volume_kobj_release(struct kobject *kobj) +static void sflc_volume_base_kobj_release(struct kobject *kobj) { - struct sflc_volume *svol = container_of(kobj, struct sflc_volume, kobj); + struct sflc_volume_base *sv_base = container_of(kobj, struct sflc_volume_base, kobj); - complete(&svol->kobj_released); + complete(&sv_base->kobj_released); } -static struct kobj_type sflc_volume_ktype = { - .release = sflc_volume_kobj_release, +static struct kobj_type sflc_volume_base_ktype = { + .release = sflc_volume_base_kobj_release, .sysfs_ops = &kobj_sysfs_ops, }; -int sflc_sysfs_register_volume(struct sflc_volume *svol) +int sflc_sysfs_register_volume_base(struct sflc_volume_base *sv_base) { int err; /* Completion */ - init_completion(&svol->kobj_released); + init_completion(&sv_base->kobj_released); /* Register directory name>/ under device directory */ - err = kobject_init_and_add(&svol->kobj, &sflc_volume_ktype, &svol->sdev->kobj, - "%s", svol->name); + err = kobject_init_and_add(&sv_base->kobj, &sflc_volume_base_ktype, + &sv_base->sd_base->kobj, + "%s", sv_base->name); if (err) goto bad; /* Emit uevent */ - kobject_uevent(&svol->kobj, KOBJ_ADD); + kobject_uevent(&sv_base->kobj, KOBJ_ADD); return 0; bad: - kobject_put(&svol->kobj); - wait_for_completion(&svol->kobj_released); + kobject_put(&sv_base->kobj); + wait_for_completion(&sv_base->kobj_released); return err; } -void sflc_sysfs_unregister_volume(struct sflc_volume *svol) +void sflc_sysfs_unregister_volume_base(struct sflc_volume_base *sv_base) { - kobject_put(&svol->kobj); - wait_for_completion(&svol->kobj_released); + kobject_put(&sv_base->kobj); + wait_for_completion(&sv_base->kobj_released); } + From b2483c12d54e3aa6f9257d5478a31ed07b513892 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 27 Sep 2024 21:49:17 +0200 Subject: [PATCH 05/12] Add vol_idx to volume base --- dm-sflc/src/dev_vol.c | 3 +-- dm-sflc/src/sflc_types.h | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dm-sflc/src/dev_vol.c b/dm-sflc/src/dev_vol.c index 2fc94b3..5bc3473 100644 --- a/dm-sflc/src/dev_vol.c +++ b/dm-sflc/src/dev_vol.c @@ -36,8 +36,6 @@ int sflc_dev_base_init(struct sflc_device_base *sd_base, struct dm_target *ti, int err; /* Parse arguments */ - if (sscanf(argv[0], "%d", &mode) != 1) - return -EINVAL; sscanf(argv[1], "%u", &dev_id); err = lookup_bdev(argv[2], &devt); if (err) @@ -75,6 +73,7 @@ int sflc_vol_base_init(struct sflc_volume_base *sv_base, sscanf(argv[3], "%u", &vol_idx); /* Assign fields */ + sv_base->vol_idx = vol_idx; sprintf(sv_base->name, "sflc_%u_%u", sd_base->dev_id, vol_idx); sv_base->sd_base = sd_base; /* Field `ops` will be set by the derived constructor */ diff --git a/dm-sflc/src/sflc_types.h b/dm-sflc/src/sflc_types.h index 2397418..2415229 100644 --- a/dm-sflc/src/sflc_types.h +++ b/dm-sflc/src/sflc_types.h @@ -104,6 +104,9 @@ struct sflc_volume_base { /* Backing device */ struct sflc_device_base *sd_base; + + /* Volume index within the device */ + u32 vol_idx; /* Volume name: sflc__ */ char name[32]; From 7cc60dbb5a20e1514d2eaacb570147372536a0f3 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 30 Sep 2024 00:04:51 +0200 Subject: [PATCH 06/12] Adapt half of sflc_lite --- dm-sflc/src/lite/device.c | 36 +++++++++++++++++------------------- dm-sflc/src/lite/sflc_lite.h | 35 ++++++++++++++--------------------- dm-sflc/src/lite/sysfs.c | 8 ++++---- dm-sflc/src/lite/volume.c | 31 +++++++++++++++++-------------- 4 files changed, 52 insertions(+), 58 deletions(-) diff --git a/dm-sflc/src/lite/device.c b/dm-sflc/src/lite/device.c index e62aa54..02c6e76 100644 --- a/dm-sflc/src/lite/device.c +++ b/dm-sflc/src/lite/device.c @@ -55,11 +55,9 @@ static void fisheryates_u32(u32 *v, u32 len) * argv[4]: number of 1 MB slices in the underlying device * argv[5]: 64-byte encryption key (hex-encoded) */ -struct sflite_device *sflite_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj) +struct sflc_device_base *sflite_dev_ctr(struct dm_target *ti, int argc, char **argv) { struct sflite_device *sdev; - dev_t devt; - u32 dev_id; u32 tot_slices; int i; int err; @@ -70,29 +68,25 @@ struct sflite_device *sflite_dev_create(struct dm_target *ti, int argc, char **a return ERR_PTR(-ENOMEM); } + /* Init base part */ + err = sflc_dev_base_init(&sdev->sd_base, ti, argc, argv); + if (err) + goto bad_base; + sdev->sd_base.mode = SFLC_MODE_LITE; + sdev->sd_base.ops = &sflc_lite_ops; + /* Parse args */ if (argc != 6) { - pr_err("Wrong argument count"); + DMERR("Wrong argument count"); err = -EINVAL; goto bad_parse; } - sscanf(argv[1], "%u", &dev_id); if (sscanf(argv[4], "%u", &tot_slices) != 1) { - pr_err("Could not decode tot_slices\n"); + DMERR("Could not decode tot_slices"); err = -EINVAL; goto bad_parse; } - sdev->dev_id = dev_id; - - /* Look up block device and set name */ - err = lookup_bdev(argv[2], &devt); - if (err) { - DMERR("Could not look up block device"); - goto bad_lookup; - } - format_dev_t(sdev->name, devt); - /* Compute sizes */ sdev->tot_slices = tot_slices; sdev->nr_free_slices = tot_slices; @@ -160,12 +154,11 @@ struct sflite_device *sflite_dev_create(struct dm_target *ti, int argc, char **a } /* Add to sysfs, once initialised */ - sdev->kobj_parent = kobj; err = sflite_sysfs_add_device(sdev); if (err) goto bad_sysfs; - return sdev; + return &sdev->sd_base; bad_sysfs: @@ -183,13 +176,17 @@ bad_prmslices: bad_ofld: bad_lookup: bad_parse: + sflc_dev_base_exit(&sdev->sd_base); +bad_base: kfree(sdev); return ERR_PTR(err); } -void sflite_dev_destroy(struct sflite_device *sdev) +void sflite_dev_dtr(struct sflc_device_base *sd_base) { + struct sflite_device *sdev = container_of(sd_base, struct sflite_device, sd_base); + sflite_sysfs_remove_device(sdev); destroy_workqueue(sdev->crypt_queue); destroy_workqueue(sdev->io_queue); @@ -197,6 +194,7 @@ void sflite_dev_destroy(struct sflite_device *sdev) bioset_exit(&sdev->bioset); vfree(sdev->prmslices); vfree(sdev->slices_ofld); + sflc_dev_base_exit(&sdev->sd_base); kfree(sdev); return; diff --git a/dm-sflc/src/lite/sflc_lite.h b/dm-sflc/src/lite/sflc_lite.h index 1c2e5a7..f07c315 100644 --- a/dm-sflc/src/lite/sflc_lite.h +++ b/dm-sflc/src/lite/sflc_lite.h @@ -29,6 +29,7 @@ #include #include #include "sflite_constants.h" +#include "sflc_types.h" #include "sflc_constants.h" @@ -40,10 +41,8 @@ struct sflite_device { - /* Shufflecake-unique device ID */ - u32 dev_id; - /* : */ - char name[16]; + /* Base device object */ + struct sflc_device_base sd_base; /* Logical size of each volume */ u32 tot_slices; @@ -58,9 +57,6 @@ struct sflite_device bool *slices_ofld; u32 nr_free_slices; - /* Parent sysfs directory */ - struct kobject *kobj_parent; - /* Resource sharing */ struct bio_set bioset; struct dm_io_client *io_client; @@ -70,6 +66,9 @@ struct sflite_device struct sflite_volume { + /* Base volume object */ + struct sflc_volume_base sv_base; + /* Backing device */ struct sflite_device *sdev; @@ -78,24 +77,17 @@ struct sflite_volume struct dm_dev *dm_dev; struct dm_target *ti; - /* Volume index within the device */ - u32 vol_idx; - /* Volume name: sflite__ */ - char name[32]; - /* Position map */ struct mutex posmap_lock; u32 *posmap; u32 nr_mapped_slices; - /* Parent sysfs directory */ - struct kobject *kobj_parent; - /* Crypto */ u8 enckey[SFLITE_XTS_KEYLEN]; struct crypto_skcipher *tfm; }; +/* Per-bio data */ struct sflite_io { struct sflite_volume *svol; @@ -136,7 +128,7 @@ struct sflite_io *---------------------------- */ -extern struct target_type sflite_target_type; +extern struct sflc_mode_ops sflc_lite_ops; /* @@ -150,13 +142,14 @@ int sflite_init(void); void sflite_exit(void); /* Device */ -struct sflite_device *sflite_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj); -void sflite_dev_destroy(struct sflite_device *sdev); +struct sflc_device_base *sflite_dev_ctr(struct dm_target *ti, int argc, char **argv); +void sflite_dev_dtr(struct sflc_device_base *sd_base); /* Volume */ -struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_device *sdev, - int argc, char **argv, struct kobject *kobj); -void sflite_vol_destroy(struct sflite_volume *svol); +struct sflc_volume_base *sflite_vol_ctr(struct sflc_device_base *sd_base, + struct dm_target *ti, + int argc, char **argv); +void sflite_vol_dtr(struct sflc_volume_base *sv_base); /* Sysfs */ int sflite_sysfs_add_device(struct sflite_device *sdev); diff --git a/dm-sflc/src/lite/sysfs.c b/dm-sflc/src/lite/sysfs.c index 88e2d06..3c6d72f 100644 --- a/dm-sflc/src/lite/sysfs.c +++ b/dm-sflc/src/lite/sysfs.c @@ -67,12 +67,12 @@ static const struct attribute_group sflite_device_attr_group = { int sflite_sysfs_add_device(struct sflite_device *sdev) { - return sysfs_create_group(sdev->kobj_parent, &sflite_device_attr_group); + return sysfs_create_group(&sdev->sd_base.kobj, &sflite_device_attr_group); } void sflite_sysfs_remove_device(struct sflite_device *sdev) { - sysfs_remove_group(sdev->kobj_parent, &sflite_device_attr_group); + sysfs_remove_group(&sdev->sd_base.kobj, &sflite_device_attr_group); } @@ -107,10 +107,10 @@ static const struct attribute_group sflite_volume_attr_group = { int sflite_sysfs_add_volume(struct sflite_volume *svol) { - return sysfs_create_group(svol->kobj_parent, &sflite_volume_attr_group); + return sysfs_create_group(&svol->sv_base.kobj, &sflite_volume_attr_group); } void sflite_sysfs_remove_volume(struct sflite_volume *svol) { - sysfs_remove_group(svol->kobj_parent, &sflite_volume_attr_group); + sysfs_remove_group(&svol->sv_base.kobj, &sflite_volume_attr_group); } diff --git a/dm-sflc/src/lite/volume.c b/dm-sflc/src/lite/volume.c index e37d9c1..a8f5933 100644 --- a/dm-sflc/src/lite/volume.c +++ b/dm-sflc/src/lite/volume.c @@ -34,11 +34,12 @@ * argv[4]: number of 1 MB slices in the underlying device * argv[5]: 64-byte encryption key (hex-encoded) */ -struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_device* sdev, - int argc, char **argv, struct kobject *kobj) +struct sflc_volume_base *sflite_vol_ctr(struct sflc_device_base *sd_base, + struct dm_target *ti, + int argc, char **argv) { struct sflite_volume *svol; - u32 vol_idx; + struct sflite_device *sdev = container_of(sd_base, struct sflite_device, sd_base); int err; svol = kzalloc(sizeof(*svol), GFP_KERNEL); @@ -47,17 +48,17 @@ struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_devi return ERR_PTR(-ENOMEM); } + /* Init base part */ + err = sflc_vol_base_init(&svol->sv_base, sd_base, ti, argc, argv); + if (err) + goto bad_base; + /* Parse arguments */ if (argc != 6) { DMERR("Wrong argument count"); err = -EINVAL; goto bad_parse; } - if (sscanf(argv[3], "%u", &vol_idx) != 1) { - DMERR("Could not decode tot_slices\n"); - err = -EINVAL; - goto bad_parse; - } /* Decode the encryption key */ if (strlen(argv[5]) != 2 * SFLITE_XTS_KEYLEN) { DMERR("Invalid key length"); @@ -72,11 +73,9 @@ struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_devi } svol->sdev = sdev; - svol->vol_idx = vol_idx; - sprintf(svol->name, "sflc_%u_%u", sdev->dev_id, vol_idx); svol->ti = ti; - err = dm_get_device(ti, sdev->name, + err = dm_get_device(ti, sdev->sd_base.name, dm_table_get_mode(ti->table), &svol->dm_dev); if (err) { ti->error = "Device lookup failed"; @@ -114,7 +113,6 @@ struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_devi } /* Add to sysfs, once initialised */ - svol->kobj_parent = kobj; err = sflite_sysfs_add_volume(svol); if (err) { DMERR("Could not register volume with sysfs; error %d", err); @@ -133,7 +131,7 @@ struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_devi ti->per_io_data_size = sizeof(struct sflite_io); ti->private = svol; - return svol; + return &svol->sv_base; bad_sysfs: @@ -146,17 +144,22 @@ bad_tfm_alloc: dm_put_device(ti, svol->dm_dev); bad_dm_dev: bad_parse: + sflc_vol_base_exit(&svol->sv_base); +bad_base: kfree(svol); return ERR_PTR(err); } -void sflite_vol_destroy(struct sflite_volume *svol) +void sflite_vol_dtr(struct sflc_volume_base *sv_base) { + struct sflite_volume *svol = container_of(sv_base, struct sflite_volume, sv_base); + sflite_sysfs_remove_volume(svol); vfree(svol->posmap); crypto_free_skcipher(svol->tfm); dm_put_device(svol->ti, svol->dm_dev); + sflc_vol_base_exit(&svol->sv_base); kfree(svol); return; From d920eedb13210d91f56efb503115ab3dc7be4eca Mon Sep 17 00:00:00 2001 From: = Date: Mon, 30 Sep 2024 22:20:28 +0200 Subject: [PATCH 07/12] Adapt sflc_lite --- dm-sflc/src/lite/device.c | 4 ++-- dm-sflc/src/lite/posmap.c | 2 +- dm-sflc/src/lite/sflc_lite.c | 14 +++++++++----- dm-sflc/src/lite/sflc_lite.h | 2 +- dm-sflc/src/lite/volume.c | 1 + 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/dm-sflc/src/lite/device.c b/dm-sflc/src/lite/device.c index 02c6e76..55ff28e 100644 --- a/dm-sflc/src/lite/device.c +++ b/dm-sflc/src/lite/device.c @@ -137,7 +137,7 @@ struct sflc_device_base *sflite_dev_ctr(struct dm_target *ti, int argc, char **a /* I/O workqueue */ sdev->io_queue = alloc_workqueue("sflite_%s_io", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, - 0, sdev->name); + 0, sdev->sd_base.name); if (!sdev->io_queue) { err = -ENOMEM; DMERR("Could not allocate I/O workqueue"); @@ -146,7 +146,7 @@ struct sflc_device_base *sflite_dev_ctr(struct dm_target *ti, int argc, char **a /* Decryption workqueue */ sdev->crypt_queue = alloc_workqueue("sflite_%s_crypt", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, - 0, sdev->name); + 0, sdev->sd_base.name); if (!sdev->crypt_queue) { err = -ENOMEM; DMERR("Could not allocate decryption workqueue"); diff --git a/dm-sflc/src/lite/posmap.c b/dm-sflc/src/lite/posmap.c index 3ee2551..8a2e412 100644 --- a/dm-sflc/src/lite/posmap.c +++ b/dm-sflc/src/lite/posmap.c @@ -311,7 +311,7 @@ static int _deserialise_and_sanitise_posmap(struct sflite_volume *svol) /* If PSI already taken, sample a new one */ if (sdev->slices_ofld[psi]) { DMWARN("Corruption of volume %u: LSI %u was evicted from PSI %u", - svol->vol_idx, lsi, psi); + svol->sv_base.vol_idx, lsi, psi); err = peek_next_free_psi(sdev, &psi); if (err) return err; diff --git a/dm-sflc/src/lite/sflc_lite.c b/dm-sflc/src/lite/sflc_lite.c index edc245f..f17adf7 100644 --- a/dm-sflc/src/lite/sflc_lite.c +++ b/dm-sflc/src/lite/sflc_lite.c @@ -41,9 +41,9 @@ static int sflite_map(struct dm_target *ti, struct bio *bio) { + struct sflc_volume_base *sv_base = ti->private; + struct sflite_volume *svol = container_of(sv_base, struct sflite_volume, sv_base); struct sflite_io *sio = dm_per_bio_data(bio, sizeof(struct sflite_io)); - struct sflc_volume *top_vol = ti->private; - struct sflite_volume *svol = top_vol->sflite_vol; sector_t lblk_num = bio->bi_iter.bi_sector >> SFLITE_BLOCK_SHIFT; if (unlikely(!bio_has_data(bio))) { @@ -116,8 +116,8 @@ static void sflite_io_hints(struct dm_target *ti, struct queue_limits *limits) static int sflite_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { - struct sflc_volume *top_vol = ti->private; - struct sflite_volume *svol = top_vol->sflite_vol; + struct sflc_volume_base *sv_base = ti->private; + struct sflite_volume *svol = container_of(sv_base, struct sflite_volume, sv_base); struct sflite_device *sdev = svol->sdev; if (!fn) { @@ -129,7 +129,11 @@ static int sflite_iterate_devices(struct dm_target *ti, iterate_devices_callout_ } -struct target_type sflite_target_type = { +struct sflc_mode_ops sflc_lite_ops = { + .dev_ctr = sflite_dev_ctr, + .dev_dtr = sflite_dev_dtr, + .vol_ctr = sflite_vol_ctr, + .vol_dtr = sflite_vol_dtr, .map = sflite_map, .io_hints = sflite_io_hints, .iterate_devices = sflite_iterate_devices, diff --git a/dm-sflc/src/lite/sflc_lite.h b/dm-sflc/src/lite/sflc_lite.h index f07c315..59becb7 100644 --- a/dm-sflc/src/lite/sflc_lite.h +++ b/dm-sflc/src/lite/sflc_lite.h @@ -111,7 +111,7 @@ struct sflite_io /* Starting sector of position map */ #define SFLITE_POSMAP_START_SECTOR(svol) \ (SFLITE_BLOCK_SCALE * (1 + SFLITE_DEV_MAX_VOLUMES) + \ - (svol)->vol_idx * (svol)->sdev->posmap_size_sectors) + (svol)->sv_base.vol_idx * (svol)->sdev->posmap_size_sectors) /* Physical sector of a remapped bio */ diff --git a/dm-sflc/src/lite/volume.c b/dm-sflc/src/lite/volume.c index a8f5933..3df5edd 100644 --- a/dm-sflc/src/lite/volume.c +++ b/dm-sflc/src/lite/volume.c @@ -52,6 +52,7 @@ struct sflc_volume_base *sflite_vol_ctr(struct sflc_device_base *sd_base, err = sflc_vol_base_init(&svol->sv_base, sd_base, ti, argc, argv); if (err) goto bad_base; + svol->sv_base.ops = &sflc_lite_ops; /* Parse arguments */ if (argc != 6) { From bb92f256e778199b177b1127f08d1b0ae205feab Mon Sep 17 00:00:00 2001 From: = Date: Mon, 30 Sep 2024 23:54:07 +0200 Subject: [PATCH 08/12] Adapt sflc_legacy --- dm-sflc/src/legacy/device/device.c | 50 ++++++++++++------------------ dm-sflc/src/legacy/device/device.h | 25 ++++----------- dm-sflc/src/legacy/sflc_legacy.h | 2 +- dm-sflc/src/legacy/sysfs.c | 29 ++++++----------- dm-sflc/src/legacy/target.c | 26 +++++++--------- dm-sflc/src/legacy/volume/volume.c | 37 +++++++++++----------- dm-sflc/src/legacy/volume/volume.h | 18 +++++------ 7 files changed, 75 insertions(+), 112 deletions(-) diff --git a/dm-sflc/src/legacy/device/device.c b/dm-sflc/src/legacy/device/device.c index 1725d65..e510c40 100644 --- a/dm-sflc/src/legacy/device/device.c +++ b/dm-sflc/src/legacy/device/device.c @@ -63,11 +63,10 @@ static int sflegc_dev_initAndShufflePsiArray(u32 *psi_array, u32 len); * argv[4]: number of 1 MB slices in the underlying device * argv[5]: 32-byte encryption key (hex-encoded) */ -sflegc_Device *sflegc_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj) +struct sflc_device_base *sflegc_dev_ctr(struct dm_target *ti, int argc, char **argv) { sflegc_Device * dev; u32 tot_slices; - u32 dev_id; int err; int i; @@ -79,25 +78,25 @@ sflegc_Device *sflegc_dev_create(struct dm_target *ti, int argc, char **argv, st goto err_alloc_dev; } + /* Init base part */ + err = sflc_dev_base_init(&dev->sd_base, ti, argc, argv); + if (err) + goto bad_base; + dev->sd_base.mode = SFLC_MODE_LEGACY; + dev->sd_base.ops = &sflc_legacy_ops; + /* Parse args */ if (argc != 6) { pr_err("Wrong argument count"); err = -EINVAL; goto err_parse; } - sscanf(argv[1], "%u", &dev_id); if (sscanf(argv[4], "%u", &tot_slices) != 1) { pr_err("Could not decode tot_slices\n"); err = -EINVAL; goto err_parse; } - /* Init list node here, so it's always safe to list_del() */ - INIT_LIST_HEAD(&dev->list_node); - - /* Set device ID */ - dev->dev_id = dev_id; - /* Set backing real device */ err = dm_get_device(ti, argv[2], dm_table_get_mode(ti->table), &dev->bdev); if (err) { @@ -105,14 +104,6 @@ sflegc_Device *sflegc_dev_create(struct dm_target *ti, int argc, char **argv, st goto err_dm_get_dev; } dev->ti = ti; - /* And its path */ - dev->bdev_path = kmalloc(strlen(argv[2]) + 1, GFP_KERNEL); - if (!dev->bdev_path) { - pr_err("Could not allocate %lu bytes for dev->real_dev_path\n", strlen(argv[2]) + 1); - err = -ENOMEM; - goto err_alloc_real_dev_path; - } - strcpy(dev->bdev_path, argv[2]); /* Init volumes */ for (i = 0; i < SFLEGC_DEV_MAX_VOLUMES; ++i) { @@ -173,14 +164,13 @@ sflegc_Device *sflegc_dev_create(struct dm_target *ti, int argc, char **argv, st INIT_LIST_HEAD(&dev->iv_lru_list); /* Add to sysfs */ - dev->kobj_parent = kobj; err = sflegc_sysfs_add_device(dev); if (err) { pr_err("Could not add device to sysfs; error %d\n", err); goto err_sysfs; } - return dev; + return &dev->sd_base; err_sysfs: @@ -191,35 +181,33 @@ err_initshuffle_psi_array: err_alloc_psi_array: vfree(dev->rmap); err_alloc_rmap: - kfree(dev->bdev_path); -err_alloc_real_dev_path: dm_put_device(ti, dev->bdev); err_dm_get_dev: err_parse: + sflc_dev_base_exit(&dev->sd_base); +bad_base: kfree(dev); err_alloc_dev: return ERR_PTR(err); } -/* Returns false if still busy (not all volumes have been removed). Frees the Device. */ -bool sflegc_dev_destroy(sflegc_Device * dev) +void sflite_dev_dtr(struct sflc_device_base *sd_base) { + struct sflegc_device *dev = container_of(sd_base, sflegc_Device, sd_base); + /* Check if we actually have to put this device */ if (!dev) { - return false; + return; } if (dev->vol_cnt > 0) { pr_warn("Called while still holding %d volumes\n", dev->vol_cnt); - return false; + return; } /* Flush all IVs */ sflegc_dev_flushIvs(dev); - /* List */ - list_del(&dev->list_node); - /* Sysfs */ sflegc_sysfs_remove_device(dev); @@ -234,12 +222,14 @@ bool sflegc_dev_destroy(sflegc_Device * dev) /* Backing device */ dm_put_device(dev->ti, dev->bdev); - kfree(dev->bdev_path); + + /* Base part */ + sflc_dev_base_exit(&dev->sd_base); /* Free the device itself */ kfree(dev); - return true; + return; } diff --git a/dm-sflc/src/legacy/device/device.h b/dm-sflc/src/legacy/device/device.h index a6109e7..63430d6 100644 --- a/dm-sflc/src/legacy/device/device.h +++ b/dm-sflc/src/legacy/device/device.h @@ -50,6 +50,7 @@ typedef struct sflegc_dev_iv_cache_entry_s sflegc_dev_IvCacheEntry; #include +#include "sflc_types.h" #include "legacy/sflc_legacy.h" #include "legacy/volume/volume.h" #include "legacy/crypto/symkey/symkey.h" @@ -101,13 +102,13 @@ struct sflegc_dev_iv_cache_entry_s struct sflegc_device_s { + /* Base device object */ + struct sflc_device_base sd_base; + /* Underlying block device */ struct dm_dev * bdev; - char * bdev_path; /* Target instance that owns the bdev reference */ struct dm_target *ti; - /* Shufflecake-unique numeric ID of this device */ - u32 dev_id; /* All volumes linked to this device */ sflegc_Volume * vol[SFLEGC_DEV_MAX_VOLUMES]; @@ -130,18 +131,12 @@ struct sflegc_device_s u32 vol_header_size; u32 dev_header_size; - /* Parent sysfs directory */ - struct kobject *kobj_parent; - /* LRU cache of IV blocks */ struct mutex iv_cache_lock; wait_queue_head_t iv_cache_waitqueue; sflegc_dev_IvCacheEntry ** iv_cache; u32 iv_cache_nr_entries; struct list_head iv_lru_list; - - /* We keep all devices in a list */ - struct list_head list_node; }; @@ -149,17 +144,9 @@ struct sflegc_device_s * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* - * None of these functions acquire the big device lock: it must be held - * by the caller. - */ - -/* Creates Device and adds it to the list. Returns an ERR_PTR() if unsuccessful. */ -sflegc_Device * sflegc_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj); - -/* Returns false if still busy (not all volumes have been removed) Frees the Device. */ -bool sflegc_dev_destroy(sflegc_Device * dev); +struct sflc_device_base *sflegc_dev_ctr(struct dm_target *ti, int argc, char **argv); +void sflegc_dev_dtr(struct sflc_device_base *sd_base); /* Returns false if volume index was already occupied. */ bool sflegc_dev_addVolume(sflegc_Device * dev, sflegc_Volume * vol, int vol_idx); diff --git a/dm-sflc/src/legacy/sflc_legacy.h b/dm-sflc/src/legacy/sflc_legacy.h index 70f0a95..2a3824f 100644 --- a/dm-sflc/src/legacy/sflc_legacy.h +++ b/dm-sflc/src/legacy/sflc_legacy.h @@ -31,7 +31,7 @@ #include "legacy/volume/volume.h" -extern struct target_type sflegc_target_type; +extern struct sflc_mode_ops sflc_legacy_ops; int sflegc_init(void); diff --git a/dm-sflc/src/legacy/sysfs.c b/dm-sflc/src/legacy/sysfs.c index df6615e..626f93d 100644 --- a/dm-sflc/src/legacy/sysfs.c +++ b/dm-sflc/src/legacy/sysfs.c @@ -43,13 +43,10 @@ /* Show the total number of slices in a device */ static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_device *top_dev; - sflegc_Device * dev; + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); + sflegc_Device * dev = container_of(sd_base, sflegc_Device, sd_base); ssize_t ret; - top_dev = container_of(kobj, struct sflc_device, kobj); - dev = top_dev->sflegc_dev; - /* Write the tot_slices */ ret = sysfs_emit(buf, "%u\n", dev->tot_slices); @@ -59,13 +56,10 @@ static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *katt /* Show the number of free slices in a device */ static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_device *top_dev; - sflegc_Device * dev; + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); + sflegc_Device * dev = container_of(sd_base, sflegc_Device, sd_base); ssize_t ret; - top_dev = container_of(kobj, struct sflc_device, kobj); - dev = top_dev->sflegc_dev; - /* Write the free_slices */ if (mutex_lock_interruptible(&dev->slices_lock)) return -ERESTARTSYS; @@ -88,12 +82,12 @@ static const struct attribute_group sflegc_device_attr_group = { int sflegc_sysfs_add_device(sflegc_Device *dev) { - return sysfs_create_group(dev->kobj_parent, &sflegc_device_attr_group); + return sysfs_create_group(dev->sd_base.kobj, &sflegc_device_attr_group); } void sflegc_sysfs_remove_device(sflegc_Device *dev) { - sysfs_remove_group(dev->kobj_parent, &sflegc_device_attr_group); + sysfs_remove_group(dev->sd_base.kobj, &sflegc_device_attr_group); } @@ -106,13 +100,10 @@ void sflegc_sysfs_remove_device(sflegc_Device *dev) /* Show the number of mapped slices in a volume */ static ssize_t mapped_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_volume *top_vol; - sflegc_Volume * vol; + struct sflc_volume_base *sv_base = container_of(kobj, struct sflc_volume_base, kobj); + sflegc_Volume * vol = container_of(sv_base, sflegc_Volume, sv_base); ssize_t ret; - top_vol = container_of(kobj, struct sflc_volume, kobj); - vol = top_vol->sflegc_vol; - /* Write the free_slices */ if (mutex_lock_interruptible(&vol->fmap_lock)) return -ERESTARTSYS; @@ -133,10 +124,10 @@ static const struct attribute_group sflegc_volume_attr_group = { int sflegc_sysfs_add_volume(sflegc_Volume *vol) { - return sysfs_create_group(vol->kobj_parent, &sflegc_volume_attr_group); + return sysfs_create_group(vol->sv_base.kobj, &sflegc_volume_attr_group); } void sflegc_sysfs_remove_volume(sflegc_Volume *vol) { - sysfs_remove_group(vol->kobj_parent, &sflegc_volume_attr_group); + sysfs_remove_group(vol->sv_base.kobj, &sflegc_volume_attr_group); } diff --git a/dm-sflc/src/legacy/target.c b/dm-sflc/src/legacy/target.c index 08a0d40..a95d60d 100644 --- a/dm-sflc/src/legacy/target.c +++ b/dm-sflc/src/legacy/target.c @@ -55,10 +55,14 @@ static int sflegc_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callo * PUBLIC VARIABLES DEFINITIONS * *****************************************************/ -struct target_type sflegc_target_type = { - .map = sflegc_tgt_map, - .io_hints = sflegc_tgt_ioHints, - .iterate_devices = sflegc_tgt_iterateDevices, +struct sflc_mode_ops sflc_legacy_ops = { + .dev_ctr = sflegc_dev_ctr, + .dev_dtr = sflegc_dev_dtr, + .vol_ctr = sflegc_vol_ctr, + .vol_dtr = sflegc_vol_dtr, + .map = sflegc_tgt_map, + .io_hints = sflegc_tgt_ioHints, + .iterate_devices = sflegc_tgt_iterateDevices, }; /***************************************************** @@ -70,8 +74,8 @@ struct target_type sflegc_target_type = { static int sflegc_tgt_map(struct dm_target *ti, struct bio *bio) { int err; - struct sflc_volume *top_vol = ti->private; - sflegc_Volume *vol = top_vol->sflegc_vol; + struct sflc_volume_base *sv_base = ti->private; + sflegc_Volume *vol = container_of(sv_base, sflegc_Volume, sv_base); /* If no data, just quickly remap the sector and the block device (no crypto) */ /* TODO: this is dangerous for deniability, will need more filtering */ @@ -117,11 +121,6 @@ static int sflegc_tgt_map(struct dm_target *ti, struct bio *bio) /* Callback executed to inform the DM about our 4096-byte sector size */ static void sflegc_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits) { - struct sflc_volume *top_vol = ti->private; - sflegc_Volume *vol = top_vol->sflegc_vol; - - pr_info("Called io_hints on volume \"%s\"\n", vol->vol_name); - limits->logical_block_size = SFLEGC_DEV_SECTOR_SIZE; limits->physical_block_size = SFLEGC_DEV_SECTOR_SIZE; @@ -135,11 +134,10 @@ static void sflegc_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits static int sflegc_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { - struct sflc_volume *top_vol = ti->private; - sflegc_Volume *vol = top_vol->sflegc_vol; + struct sflc_volume_base *sv_base = ti->private; + sflegc_Volume *vol = container_of(sv_base, sflegc_Volume, sv_base); sflegc_Device * dev = vol->dev; - pr_debug("Called iterate_devices on volume \"%s\"\n", vol->vol_name); if (!fn) { return -EINVAL; diff --git a/dm-sflc/src/legacy/volume/volume.c b/dm-sflc/src/legacy/volume/volume.c index e229312..8c62e1f 100644 --- a/dm-sflc/src/legacy/volume/volume.c +++ b/dm-sflc/src/legacy/volume/volume.c @@ -50,11 +50,12 @@ * argv[4]: number of 1 MB slices in the underlying device * argv[5]: 32-byte encryption key (hex-encoded) */ -sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev, - int argc, char **argv, struct kobject *kobj) +struct sflc_volume_base *sflegc_vol_ctr(struct sflc_device_base *sd_base, + struct dm_target *ti, + int argc, char **argv) { sflegc_Volume * vol; - int vol_idx; + sflegc_Device *dev = container_of(sd_base, sflegc_Device, sd_base); u8 enckey[SFLEGC_SK_KEY_LEN]; int err; @@ -66,17 +67,18 @@ sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev, goto err_alloc_vol; } + /* Init base part */ + err = sflc_vol_base_init(&vol->sv_base, sd_base, ti, argc, argv); + if (err) + goto bad_base; + vol->sv_base.ops = &sflc_legacy_ops; + /* Parse args */ if (argc != 6) { pr_err("Wrong argument count"); err = -EINVAL; goto err_parse; } - if (sscanf(argv[3], "%u", &vol_idx) != 1) { - pr_err("Could not decode tot_slices\n"); - err = -EINVAL; - goto err_parse; - } /* Decode the encryption key */ if (strlen(argv[5]) != 2 * SFLEGC_SK_KEY_LEN) { pr_err("Hexadecimal key (length %lu): %s\n", strlen(argv[5]), argv[5]); @@ -90,11 +92,7 @@ sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev, goto err_parse; } - /* Set volume name */ - sprintf(vol->vol_name, "sflc_%u_%d", dev->dev_id, vol_idx); - /* Sysfs stuff */ - vol->kobj_parent = kobj; err = sflegc_sysfs_add_volume(vol); if (err) { pr_err("Could not add volume to sysfs; error %d\n", err); @@ -102,13 +100,12 @@ sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev, } /* Backing device */ - if (!sflegc_dev_addVolume(dev, vol, vol_idx)) { + if (!sflegc_dev_addVolume(dev, vol, vol->sv_base.vol_idx)) { pr_err("Could not add volume to device\n"); err = -EINVAL; goto err_add_to_dev; } vol->dev = dev; - vol->vol_idx = vol_idx; /* Crypto */ vol->skctx = sflegc_sk_createContext(enckey); @@ -152,7 +149,7 @@ sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev, TODO: will need to support them to release slice mappings */ ti->num_discard_bios = 0; - return vol; + return &vol->sv_base; err_load_fmap: @@ -165,23 +162,24 @@ err_add_to_dev: sflegc_sysfs_remove_volume(vol); err_sysfs: err_parse: + sflc_vol_base_exit(&vol->sv_base); +bad_base: kfree(vol); err_alloc_vol: return ERR_PTR(err); } /* Removes the volume from the device and frees it. */ -void sflegc_vol_destroy(sflegc_Volume * vol) +void sflite_vol_dtr(struct sflc_volume_base *sv_base) { + sflegc_Volume *vol = container_of(sv_base, sflegc_Volume, sv_base); int err; /* Store fmap */ - pr_notice("Going to store position map of volume %s\n", vol->vol_name); err = sflegc_vol_storeFmap(vol); if (err) { pr_err("Could not store position map; error %d\n", err); } - pr_debug("Successfully stored position map of volume %s\n", vol->vol_name); /* Free it */ vfree(vol->fmap); @@ -194,6 +192,9 @@ void sflegc_vol_destroy(sflegc_Volume * vol) /* Destroy sysfs entries */ sflegc_sysfs_remove_volume(vol); + /* Base part */ + sflc_vol_base_exit(&vol->sv_base); + /* Free volume structure */ kfree(vol); diff --git a/dm-sflc/src/legacy/volume/volume.h b/dm-sflc/src/legacy/volume/volume.h index 3222433..c61de66 100644 --- a/dm-sflc/src/legacy/volume/volume.h +++ b/dm-sflc/src/legacy/volume/volume.h @@ -47,6 +47,7 @@ typedef struct sflegc_volume_s sflegc_Volume; #include +#include "sflc_types.h" #include "legacy/sflc_legacy.h" #include "legacy/device/device.h" #include "legacy/crypto/symkey/symkey.h" @@ -103,13 +104,11 @@ struct sflegc_vol_decrypt_work_s struct sflegc_volume_s { - /* Name of the volume, sflc__*/ - char vol_name[SFLEGC_VOL_NAME_MAX_LEN + 1]; + /* Base volume object */ + struct sflc_volume_base sv_base; /* Backing device */ sflegc_Device * dev; - /* Index of this volume within the device's volume array */ - u32 vol_idx; /* Forward position map */ struct mutex fmap_lock; @@ -117,8 +116,6 @@ struct sflegc_volume_s /* Stats on the fmap */ u32 mapped_slices; - /* Parent sysfs directory */ - struct kobject *kobj_parent; /* Crypto */ sflegc_sk_Context * skctx; @@ -129,11 +126,10 @@ struct sflegc_volume_s * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful */ -sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev, - int argc, char **argv, struct kobject *kobj); -/* Removes the volume from the device and frees it. */ -void sflegc_vol_destroy(sflegc_Volume * vol); +struct sflc_volume_base *sflegc_vol_ctr(struct sflc_device_base *sd_base, + struct dm_target *ti, + int argc, char **argv); +void sflegc_vol_dtr(struct sflc_volume_base *sv_base); /* Remaps the underlying block device and the sector number */ int sflegc_vol_remapBioFast(sflegc_Volume * vol, struct bio * bio); From 1df6b0774c6c5d5d92498b415a5ae05e6d1cfd08 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 1 Oct 2024 00:33:13 +0200 Subject: [PATCH 09/12] Adapt everything: now it compiles, still to be tested --- dm-sflc/src/legacy/device/device.c | 5 +- dm-sflc/src/legacy/sysfs.c | 8 +-- dm-sflc/src/legacy/volume/fmap.c | 8 +-- dm-sflc/src/legacy/volume/volume.c | 9 ++-- dm-sflc/src/lite/device.c | 2 +- dm-sflc/src/lite/sysfs.c | 12 ++--- dm-sflc/src/lite/volume.c | 1 + dm-sflc/src/sflc.c | 82 +++++++++++++++++++----------- dm-sflc/src/sflc.h | 2 +- dm-sflc/src/sflc_constants.h | 1 + dm-sflc/src/sflc_types.h | 2 - 11 files changed, 76 insertions(+), 56 deletions(-) diff --git a/dm-sflc/src/legacy/device/device.c b/dm-sflc/src/legacy/device/device.c index e510c40..e64b613 100644 --- a/dm-sflc/src/legacy/device/device.c +++ b/dm-sflc/src/legacy/device/device.c @@ -33,6 +33,7 @@ #include "legacy/device/device.h" #include "legacy/utils/vector.h" #include "legacy/log/log.h" +#include "sflc.h" #include @@ -192,9 +193,9 @@ err_alloc_dev: } -void sflite_dev_dtr(struct sflc_device_base *sd_base) +void sflegc_dev_dtr(struct sflc_device_base *sd_base) { - struct sflegc_device *dev = container_of(sd_base, sflegc_Device, sd_base); + sflegc_Device *dev = container_of(sd_base, sflegc_Device, sd_base); /* Check if we actually have to put this device */ if (!dev) { diff --git a/dm-sflc/src/legacy/sysfs.c b/dm-sflc/src/legacy/sysfs.c index 626f93d..7d567ec 100644 --- a/dm-sflc/src/legacy/sysfs.c +++ b/dm-sflc/src/legacy/sysfs.c @@ -82,12 +82,12 @@ static const struct attribute_group sflegc_device_attr_group = { int sflegc_sysfs_add_device(sflegc_Device *dev) { - return sysfs_create_group(dev->sd_base.kobj, &sflegc_device_attr_group); + return sysfs_create_group(&dev->sd_base.kobj, &sflegc_device_attr_group); } void sflegc_sysfs_remove_device(sflegc_Device *dev) { - sysfs_remove_group(dev->sd_base.kobj, &sflegc_device_attr_group); + sysfs_remove_group(&dev->sd_base.kobj, &sflegc_device_attr_group); } @@ -124,10 +124,10 @@ static const struct attribute_group sflegc_volume_attr_group = { int sflegc_sysfs_add_volume(sflegc_Volume *vol) { - return sysfs_create_group(vol->sv_base.kobj, &sflegc_volume_attr_group); + return sysfs_create_group(&vol->sv_base.kobj, &sflegc_volume_attr_group); } void sflegc_sysfs_remove_volume(sflegc_Volume *vol) { - sysfs_remove_group(vol->sv_base.kobj, &sflegc_volume_attr_group); + sysfs_remove_group(&vol->sv_base.kobj, &sflegc_volume_attr_group); } diff --git a/dm-sflc/src/legacy/volume/fmap.c b/dm-sflc/src/legacy/volume/fmap.c index c0ca78c..7f924ae 100644 --- a/dm-sflc/src/legacy/volume/fmap.c +++ b/dm-sflc/src/legacy/volume/fmap.c @@ -137,7 +137,7 @@ int sflegc_vol_loadFmap(sflegc_Volume * vol) } /* Starting block of the position map (skip the DMB, the previous volume headers, and the VMB) */ - sector = 1 + (vol->vol_idx * dev->vol_header_size) + 1; + sector = 1 + (vol->sv_base.vol_idx * dev->vol_header_size) + 1; /* Starting LSI in the fmap */ lsi = 0; @@ -182,7 +182,7 @@ int sflegc_vol_loadFmap(sflegc_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 != SFLEGC_VOL_FMAP_INVALID_PSI) { - sflegc_dev_markPsiTaken(dev, psi, vol->vol_idx); + sflegc_dev_markPsiTaken(dev, psi, vol->sv_base.vol_idx); vol->mapped_slices += 1; } @@ -247,7 +247,7 @@ int sflegc_vol_storeFmap(sflegc_Volume * vol) } /* Starting block of the position map (skip the DMB, the previous volume headers, and the VMB) */ - sector = 1 + (vol->vol_idx * dev->vol_header_size) + 1; + sector = 1 + (vol->sv_base.vol_idx * dev->vol_header_size) + 1; /* Starting LSI in the fmap */ lsi = 0; @@ -366,7 +366,7 @@ static s32 sflegc_vol_mapSlice(sflegc_Volume * vol, u32 lsi, int op) vol->fmap[lsi] = psi; vol->mapped_slices += 1; /* And in the device's rmap */ - sflegc_dev_markPsiTaken(dev, psi, vol->vol_idx); + sflegc_dev_markPsiTaken(dev, psi, vol->sv_base.vol_idx); /* Unlock both maps */ mutex_unlock(&dev->slices_lock); diff --git a/dm-sflc/src/legacy/volume/volume.c b/dm-sflc/src/legacy/volume/volume.c index 8c62e1f..f37623d 100644 --- a/dm-sflc/src/legacy/volume/volume.c +++ b/dm-sflc/src/legacy/volume/volume.c @@ -32,6 +32,7 @@ #include "legacy/volume/volume.h" #include "legacy/utils/string.h" #include "legacy/log/log.h" +#include "sflc.h" #include @@ -128,13 +129,11 @@ struct sflc_volume_base *sflegc_vol_ctr(struct sflc_device_base *sd_base, vol->mapped_slices = 0; /* Initialise fmap */ - pr_notice("Volume opening for volume %s: loading fmap from header\n", vol->vol_name); err = sflegc_vol_loadFmap(vol); if (err) { pr_err("Could not load position map; error %d\n", err); goto err_load_fmap; } - pr_debug("Successfully loaded position map for volume %s\n", vol->vol_name); /* Tell DM we want one SFLC sector at a time */ @@ -157,7 +156,7 @@ err_load_fmap: err_alloc_fmap: sflegc_sk_destroyContext(vol->skctx); err_create_skctx: - sflegc_dev_removeVolume(vol->dev, vol->vol_idx); + sflegc_dev_removeVolume(vol->dev, vol->sv_base.vol_idx); err_add_to_dev: sflegc_sysfs_remove_volume(vol); err_sysfs: @@ -170,7 +169,7 @@ err_alloc_vol: } /* Removes the volume from the device and frees it. */ -void sflite_vol_dtr(struct sflc_volume_base *sv_base) +void sflegc_vol_dtr(struct sflc_volume_base *sv_base) { sflegc_Volume *vol = container_of(sv_base, sflegc_Volume, sv_base); int err; @@ -187,7 +186,7 @@ void sflite_vol_dtr(struct sflc_volume_base *sv_base) sflegc_sk_destroyContext(vol->skctx); /* Remove from device */ - sflegc_dev_removeVolume(vol->dev, vol->vol_idx); + sflegc_dev_removeVolume(vol->dev, vol->sv_base.vol_idx); /* Destroy sysfs entries */ sflegc_sysfs_remove_volume(vol); diff --git a/dm-sflc/src/lite/device.c b/dm-sflc/src/lite/device.c index 55ff28e..cd10ef0 100644 --- a/dm-sflc/src/lite/device.c +++ b/dm-sflc/src/lite/device.c @@ -26,6 +26,7 @@ #include #include #include "sflc_lite.h" +#include "sflc.h" @@ -174,7 +175,6 @@ bad_bioset: bad_prmslices: vfree(sdev->slices_ofld); bad_ofld: -bad_lookup: bad_parse: sflc_dev_base_exit(&sdev->sd_base); bad_base: diff --git a/dm-sflc/src/lite/sysfs.c b/dm-sflc/src/lite/sysfs.c index 3c6d72f..6c15b66 100644 --- a/dm-sflc/src/lite/sysfs.c +++ b/dm-sflc/src/lite/sysfs.c @@ -34,16 +34,16 @@ static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_device *top_dev = container_of(kobj, struct sflc_device, kobj); - struct sflite_device *sdev = top_dev->sflite_dev; + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); + struct sflite_device *sdev = container_of(sd_base, struct sflite_device, sd_base); return sysfs_emit(buf, "%u\n", sdev->tot_slices); } static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_device *top_dev = container_of(kobj, struct sflc_device, kobj); - struct sflite_device *sdev = top_dev->sflite_dev; + struct sflc_device_base *sd_base = container_of(kobj, struct sflc_device_base, kobj); + struct sflite_device *sdev = container_of(sd_base, struct sflite_device, sd_base); int ret; if (mutex_lock_interruptible(&sdev->slices_lock)) @@ -84,8 +84,8 @@ void sflite_sysfs_remove_device(struct sflite_device *sdev) static ssize_t mapped_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { - struct sflc_volume *top_vol = container_of(kobj, struct sflc_volume, kobj); - struct sflite_volume *svol = top_vol->sflite_vol; + struct sflc_volume_base *sv_base = container_of(kobj, struct sflc_volume_base, kobj); + struct sflite_volume *svol = container_of(sv_base, struct sflite_volume, sv_base); int ret; if (mutex_lock_interruptible(&svol->posmap_lock)) diff --git a/dm-sflc/src/lite/volume.c b/dm-sflc/src/lite/volume.c index 3df5edd..26717b9 100644 --- a/dm-sflc/src/lite/volume.c +++ b/dm-sflc/src/lite/volume.c @@ -23,6 +23,7 @@ #include #include "sflc_lite.h" +#include "sflc.h" /** diff --git a/dm-sflc/src/sflc.c b/dm-sflc/src/sflc.c index 1a7e802..76b0f0e 100644 --- a/dm-sflc/src/sflc.c +++ b/dm-sflc/src/sflc.c @@ -32,14 +32,22 @@ #include -// Global variables +/* Global variables */ + +// A set of algorithms for each Shufflecake mode, in the same order as the modes. +struct sflc_mode_ops *sflc_all_mode_ops[SFLC_NR_MODES] = { + &sflc_legacy_ops, + &sflc_lite_ops +}; + +// Global array of base device objects DEFINE_MUTEX(sflc_alldevs_lock); -struct sflc_device **sflc_alldevs = NULL; +struct sflc_device_base **sflc_alldevs = NULL; u32 sflc_free_devid = 0; /* The lowest free devID */ /* Add a device to the global array, and advance next_dev_id */ -static int sflc_add_device_global(u32 dev_id, struct sflc_device *sdev) +static int sflc_add_device_global(u32 dev_id, struct sflc_device_base *sd_base) { int i; @@ -54,7 +62,7 @@ static int sflc_add_device_global(u32 dev_id, struct sflc_device *sdev) return -EINVAL; } // Add to the global array, and advance free_devid - sflc_alldevs[dev_id] = sdev; + sflc_alldevs[dev_id] = sd_base; for (i = sflc_free_devid; i < SFLC_MAX_DEVS && sflc_alldevs[i]; i++); sflc_free_devid = i; @@ -86,10 +94,12 @@ static void sflc_remove_device_global(u32 dev_id) */ static int sflc_ctr(struct dm_target *ti, unsigned int argc, char **argv) { + u32 mode; + struct sflc_mode_ops *mode_ops; u32 dev_id; u32 vol_idx; - struct sflc_device *sdev; - struct sflc_volume *svol; + struct sflc_device_base *sd_base; + struct sflc_volume_base *sv_base; int err; /* Parse arguments */ @@ -97,6 +107,10 @@ static int sflc_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->error = "Invalid argument count"; return -EINVAL; } + if (sscanf(argv[0], "%u", &mode) != 1) { + ti->error = "Could not decode mode"; + return -EINVAL; + } if (sscanf(argv[1], "%u", &dev_id) != 1) { ti->error = "Could not decode device ID"; return -EINVAL; @@ -106,6 +120,10 @@ static int sflc_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } /* Sanity checks */ + if (mode >= SFLC_NR_MODES) { + ti->error = "Mode out of bounds"; + return -EINVAL; + } if (dev_id >= SFLC_MAX_DEVS) { ti->error = "Device ID out of bounds"; return -EINVAL; @@ -114,16 +132,18 @@ static int sflc_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->error = "Volume index out of bounds"; return -EINVAL; } + /* Grab the correct mode */ + mode_ops = sflc_all_mode_ops[mode]; /* Create device, if this is the first volume, otherwise retrieve it */ if (vol_idx == 0) { - sdev = sflc_dev_create(ti, argc, argv); - if (IS_ERR(sdev)) { + sd_base = mode_ops->dev_ctr(ti, argc, argv); + if (IS_ERR(sd_base)) { ti->error = "Could not instantiate device"; - return PTR_ERR(sdev); + return PTR_ERR(sd_base); } /* Insert in global array */ - err = sflc_add_device_global(dev_id, sdev); + err = sflc_add_device_global(dev_id, sd_base); if (err) { ti->error = "Could not add device to global array"; goto bad_dev_global; @@ -131,26 +151,26 @@ static int sflc_ctr(struct dm_target *ti, unsigned int argc, char **argv) } else { if (mutex_lock_interruptible(&sflc_alldevs_lock)) return -ERESTARTSYS; - sdev = sflc_alldevs[dev_id]; + sd_base = sflc_alldevs[dev_id]; mutex_unlock(&sflc_alldevs_lock); - if (!sdev) { + if (!sd_base) { ti->error = "Could not find device with specified ID"; return -EINVAL; } } /* Create volume */ - svol = sflc_vol_create(sdev, ti, argc, argv); - if (IS_ERR(svol)) { + sv_base = mode_ops->vol_ctr(sd_base, ti, argc, argv); + if (IS_ERR(sv_base)) { ti->error = "Could not instantiate volume"; - err = PTR_ERR(svol); + err = PTR_ERR(sv_base); goto bad_vol_create; } /* We expect ->ctr() calls to be strictly sequential, so we don't need locking */ - sdev->nr_volumes++; + sd_base->nr_volumes++; - ti->private = svol; + ti->private = sv_base; return 0; @@ -159,7 +179,7 @@ bad_vol_create: if (vol_idx == 0) { sflc_remove_device_global(dev_id); bad_dev_global: - sflc_dev_destroy(sdev); + mode_ops->dev_dtr(sd_base); } return err; } @@ -168,16 +188,16 @@ bad_dev_global: /* Destroy volume and, if needed, the underlying device */ static void sflc_dtr(struct dm_target *ti) { - struct sflc_volume *svol = ti->private; - struct sflc_device *sdev = svol->sdev; + struct sflc_volume_base *sv_base = ti->private; + struct sflc_device_base *sd_base = sv_base->sd_base; - sflc_vol_destroy(svol); + sv_base->ops->vol_dtr(sv_base); /* We expect ->dtr() calls to be strictly sequential, so we don't need locking */ - sdev->nr_volumes--; + sd_base->nr_volumes--; - if (sdev->nr_volumes == 0) { - sflc_remove_device_global(sdev->dev_id); - sflc_dev_destroy(sdev); + if (sd_base->nr_volumes == 0) { + sflc_remove_device_global(sd_base->dev_id); + sd_base->ops->dev_dtr(sd_base); } return; @@ -186,21 +206,21 @@ static void sflc_dtr(struct dm_target *ti) static int sflc_map(struct dm_target *ti, struct bio *bio) { - struct sflc_volume *svol = ti->private; - return svol->tt->map(ti, bio); + struct sflc_volume_base *sv_base = ti->private; + return sv_base->ops->map(ti, bio); } static void sflc_io_hints(struct dm_target *ti, struct queue_limits *limits) { - struct sflc_volume *svol = ti->private; - svol->tt->io_hints(ti, limits); + struct sflc_volume_base *sv_base = ti->private; + return sv_base->ops->io_hints(ti, limits); return; } static int sflc_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { - struct sflc_volume *svol = ti->private; - return svol->tt->iterate_devices(ti, fn, data); + struct sflc_volume_base *sv_base = ti->private; + return sv_base->ops->iterate_devices(ti, fn, data); } diff --git a/dm-sflc/src/sflc.h b/dm-sflc/src/sflc.h index ed206c1..a3459ca 100644 --- a/dm-sflc/src/sflc.h +++ b/dm-sflc/src/sflc.h @@ -38,7 +38,7 @@ */ /* Every mode provides a full set of algorithms */ -struct sflc_mode_ops **sflc_mode_ops; +extern struct sflc_mode_ops *sflc_all_mode_ops[SFLC_NR_MODES]; /* Array of all open devices */ extern struct mutex sflc_alldevs_lock; diff --git a/dm-sflc/src/sflc_constants.h b/dm-sflc/src/sflc_constants.h index c978796..c608581 100644 --- a/dm-sflc/src/sflc_constants.h +++ b/dm-sflc/src/sflc_constants.h @@ -45,6 +45,7 @@ /* Each device can be formatted and used with a mode of choice, irrespective of the other devices */ #define SFLC_MODE_LEGACY 0 #define SFLC_MODE_LITE 1 +#define SFLC_NR_MODES 2 /* Max number of volumes per device */ diff --git a/dm-sflc/src/sflc_types.h b/dm-sflc/src/sflc_types.h index 2415229..d2927cd 100644 --- a/dm-sflc/src/sflc_types.h +++ b/dm-sflc/src/sflc_types.h @@ -54,8 +54,6 @@ #include #include "sflc_constants.h" -#include "legacy/sflc_legacy.h" -#include "lite/sflc_lite.h" /* From 1a775e9a44e978f9611e52fef25903239f6413de Mon Sep 17 00:00:00 2001 From: = Date: Wed, 2 Oct 2024 22:21:57 +0200 Subject: [PATCH 10/12] Add symlink to sflc_types.h --- dm-sflc/bin/sflc_types.h | 1 + 1 file changed, 1 insertion(+) create mode 120000 dm-sflc/bin/sflc_types.h diff --git a/dm-sflc/bin/sflc_types.h b/dm-sflc/bin/sflc_types.h new file mode 120000 index 0000000..d320fe2 --- /dev/null +++ b/dm-sflc/bin/sflc_types.h @@ -0,0 +1 @@ +../src/sflc_types.h \ No newline at end of file From ad958dd62bc2432323081468b8b7c6bae7d5ed95 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 2 Oct 2024 22:46:33 +0200 Subject: [PATCH 11/12] Adapt FLUSH behaviour of legacy --- dm-sflc/src/legacy/target.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/dm-sflc/src/legacy/target.c b/dm-sflc/src/legacy/target.c index a95d60d..52970b4 100644 --- a/dm-sflc/src/legacy/target.c +++ b/dm-sflc/src/legacy/target.c @@ -77,17 +77,19 @@ static int sflegc_tgt_map(struct dm_target *ti, struct bio *bio) struct sflc_volume_base *sv_base = ti->private; sflegc_Volume *vol = container_of(sv_base, sflegc_Volume, sv_base); - /* If no data, just quickly remap the sector and the block device (no crypto) */ - /* TODO: this is dangerous for deniability, will need more filtering */ - if (unlikely(!bio_has_data(bio))) { - pr_debug("No-data bio: bio_op = %d", bio_op(bio)); - err = sflegc_vol_remapBioFast(vol, bio); - if (err) { - pr_err("Could not remap bio; error %d\n", err); + /* Copied from sflc_lite */ + if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { + /* Has to be empty though */ + if (bio_sectors(bio)) { + DMWARN("Non-empty flush request!"); + //msleep(3000); return DM_MAPIO_KILL; } - return DM_MAPIO_REMAPPED; - } +// DMWARN("REQ_PREFLUSH empty (phew), sector: %llu", bio->bi_iter.bi_sector); +// msleep(100); + bio_set_dev(bio, vol->dev->bdev->bdev); + return DM_MAPIO_REMAPPED; + } /* At this point, the bio has data. Do a few sanity checks */ /* TODO: I think we can get rid of all of them */ From 2d5cb4c74a78ab2cb9b8b63c16a341cf74738ebb Mon Sep 17 00:00:00 2001 From: Tommaso Gagliardoni Date: Sun, 13 Oct 2024 12:08:26 +0200 Subject: [PATCH 12/12] chore:Prepare release v0.5.1 --- CHANGELOG.md | 12 ++++++ README.md | 37 ++++-------------- dm-sflc/src/sflc_constants.h | 4 +- .../images/badges/badge_version_0.5.0.png | Bin 2410 -> 0 bytes .../images/badges/badge_version_0.5.1.png | Bin 0 -> 2241 bytes resources/images/badges/badges.svg | 8 ++-- 6 files changed, 25 insertions(+), 36 deletions(-) delete mode 100644 resources/images/badges/badge_version_0.5.0.png create mode 100644 resources/images/badges/badge_version_0.5.1.png diff --git a/CHANGELOG.md b/CHANGELOG.md index c4434fc..75a3a64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Global constants fully shared among components through `sflc_constants.h`. +## [0.5.1] - 2024-10-13 + +### Refactored + + - Reorganized interface between dispatcher and dm-legacy through pointers to functions. + +### Fixed + + - Fixed debug error message when reading unallocated slices on dm-legacy. + + ## [0.5.0] - 2024-09-01 ### Added @@ -37,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed all occurrences of "Shufflecake Old" to "Shufflecake Legacy", including code paths and variables. - Reordered entries in CHANGELOG.md with sections following the order Added -> Changed -> Fixed -> Refactored -> Removed. + ## [0.4.5] - 2024-06-03 ### Changed diff --git a/README.md b/README.md index beee2f9..863150c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Status](resources/images/badges/badge_status_active.png)](https://codeberg.org/shufflecake/shufflecake-c)  -[![Version](resources/images/badges/badge_version_0.5.0.png)](https://codeberg.org/shufflecake/shufflecake-c/releases/tag/v0.5.0)  +[![Version](resources/images/badges/badge_version_0.5.1.png)](https://codeberg.org/shufflecake/shufflecake-c/releases/tag/v0.5.1)  [![License](resources/images/badges/badge_license_gplv2plus.png)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)  [![Docs researchpaper](resources/images/badges/badge_docs_researchpaper.png)](https://eprint.iacr.org/2023/1529)  [![Website](resources/images/badges/badge_web_shufflecakedotnet.png)](https://shufflecake.net/)  @@ -12,7 +12,7 @@ -# Shufflecake - Full C Implementation - v0.5.0 +# Shufflecake - Full C Implementation - v0.5.1 _Shufflecake_ is a plausible deniability (hidden storage) layer for Linux. You can consider Shufflecake a spiritual successor of tools like TrueCrypt and VeraCrypt, but vastly improved, both in terms of security and functionality. Official website: . @@ -265,6 +265,11 @@ Both methods works with the `init` action, and we do not have current plans to c Please see the file `CHANGELOG.md` for a detailed history of changes. +### [0.5.1] - 2024-10-13 + + - Reorganized interface between dispatcher and dm-legacy through pointers to functions. + - Fixed debug error message when reading unallocated slices on dm-legacy. + ### [0.5.0] - 2024-09-01 - BREAKING CHANGE: major rewrite, bugfixes, introduced Shufflecake "Lite" as a default mode of operation. @@ -273,34 +278,6 @@ Please see the file `CHANGELOG.md` for a detailed history of changes. - Fixed a compile error on some versions of LTS kernels. - Fixed segmentation fault when opening an already opened device. - -### [0.4.4] - 2023-12-31 - - - Fixed a memory allocation error on large devices. - -### [0.4.3] - 2023-11-29 - - - Fixed compile error on recent kernel versions. - -### [0.4.2] - 2023-11-28 - - - Fixed persistent slice allocation ambiguity after a volume corruption by allocating fresh slices for the corrupted volume. This is done in order to help external recovery tools (e.g. RAID). - - Various bugfixes. - -### [0.4.1] - 2023-07-30 - - - Fixed and improved benchmark scripts. - - Fixed mistake in drawing of header layout in `doc`. - -### [0.4.0] - 2023-07-24 - -- BREAKING CHANGE: slightly modified header field format, removing redundant data and making it adherent to documentation. -- Implemented reference slice allocation algorithm with much faster performance. -- Added actions `checkpwd` and `changepwd`. -- Password is now read in a secure shell during `open`. -- Added benchmark suite. -- Fixed bugs in action `close` and option `--skip-randfill`. -- Added `doc` (currently includes figure of Shufflecake headers structure). diff --git a/dm-sflc/src/sflc_constants.h b/dm-sflc/src/sflc_constants.h index c608581..e02d71d 100644 --- a/dm-sflc/src/sflc_constants.h +++ b/dm-sflc/src/sflc_constants.h @@ -33,8 +33,8 @@ #define SFLC_VER_MAJOR 0 #define SFLC_VER_MINOR 5 -#define SFLC_VER_REVISION 0 -#define SFLC_VER_SPECIAL "rc1" +#define SFLC_VER_REVISION 1 +#define SFLC_VER_SPECIAL "" #define STRINGIFY0(s) # s #define STRINGIFY(s) STRINGIFY0(s) diff --git a/resources/images/badges/badge_version_0.5.0.png b/resources/images/badges/badge_version_0.5.0.png deleted file mode 100644 index 869a324ac8dc6c0933d676d9b8cabb44ae3860e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2410 zcmV-w36=JVP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H12=_@u zK~!jg?U{Q_(`OgQKfO}QN-Y;JsH=adKSZ>G5Tl7R&I=mi1ro2sXk3DeF=||vU`&i5 zE^))iA6rb+cwJ(cV^Ond6cxMzbqo;7td-7+R1xQoiBO>z`u;)siwkz(>42-pi<4xNsphn+>bg`cC!G z>-FU3=3+D&X>V`m^y$+$oz93nnVFgB_4)yHhr>a0b8}d}(W6I`ot=%rVBpT3JDfUo ziWe_lM3nVjIxiz5gYNF`cj`Pr5GXG%Cn+gOqJ8`Ax8&sHaPi{BuzV*@oM6&WF=Rs>jh77^y^YQoJe*>V?=@0|~ zjYdOTTN`$}9lzf%t!cGd9zTAJAPA_{Y8o3G0T?`ZFh-*hg+hVT>EywK2a*hpMuXSu z4U#)@I|CSeQL~Ha44$#>PhG%$Y-0 zRu)}dUG(+!q1WrVcI_IcPMrcEKR=)A*RONw(j{av87o$-VDjY2ba!{7R4P%c)s&T$ zQC3z4z^YZNuv)F8q@9W>S_R5TU)W& zYzTrtT3T92=Org617Nq?$;ruK#E20zH8oLDQ6UBNt1y{N0GQ2Y+-^4j<>lp)y#+y_ zp`jrpZ%F6){eJ4|>X<%#I%>6A+H}H%2`Cf_e*gV<3QeIw8XJ==S zE>ovYW%A_7l$MrKRaJ#tE+;!Xo2;xX>~=eLyB&bfKKqQ4k`iibYmv!hEL*mW>C>lk z_Uu`FK3~YgheLdPJOG`YozmF>+S=L>1VLJV730Q@17PRQoy5k*O7wH*&ar6GqM*HA zl@-Wj0XYFABqW5@Gi=SPtE)q;RwD?4L`zFcf#2vpjqDjLghT>AMFH9#C6b3-kw{#bQCBP!Js*9rp0yU@#Z}=pe^CWsyt z6$KD7$N;|k?mPDH-_M;pcY(?`8%$V283LqdSk}P(;S&@#3(1rlzK{bLUQm z4I2jZr`21xZsB&jgKkm)_wV1wWHO=C=_K07ks}#3YSjO1h__fQlJN@*3mHFtJcWgY zXti40ZnxBFHa0dQiXwaV?7`)7k)54Qettf?cI{%^xN$64us|9a0$uO+?b{JWQA(@7 z{q`FGMx&9hzWR#P)Ks=@+XnP^pf8U^ui~{YEOm8tSIZR7{&TjrR6-sfqcw(bv~UK|ui}B_-tM=8~J6E3Fk36-loidc7Wl!6226 zufP79x-E?p||{Povg?AWmb=+8_BgFy<^rluy2967?8HEYSfTCK##$1`Tk7={lYF7XAL4wXuU!{MN#ql2EF9vT`Nh>wpaIXRic#6&C> z3ne8bQhih^m9)0D21Th{F30V5)7;z~wt1uW5%{E&u=k diff --git a/resources/images/badges/badge_version_0.5.1.png b/resources/images/badges/badge_version_0.5.1.png new file mode 100644 index 0000000000000000000000000000000000000000..63b03468e46b9c11addc30358fd650daa0fc2cc5 GIT binary patch literal 2241 zcmV;y2tN0TP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H12u?{v zK~!jg?U`9fl2j$2J;CJ7a7T11v!SQ$|iXn0`}1a=c42DXqF zEf+yS1z}~BL{e62rMM(oIi^icjmwl-y|$?7=s3R%@ukV7lKxcu`(B>socA2gd7ke% z&-2Q5@80d;{}e}$9_<4ZzdMexLipVQ{KMGsNA9}V*jP*^6ZQ4=zcmhbcX#6B zfC&>OpwsD)%jHjl*iSVzF3$I1yiC%9JTAUAh#29Xob#|Neb)b8~5GYQopomnBP8sA$EGb z9zhT|ckUd!cJ2BhU!IC>m_?d>HjER4v=NQ_1!%a~H~DT(6ZV(#9(i%ceCuj?b}(hWQmkm zPft$*0|PmB>=;(76|GiFOiT>7Zr$Sc?b`sv#KaIC9Zf+&0iQm7a*Acaf(3+!hm(_& zLuqL#f*`PZ^=e{bVlbP{n9XJY7A;ytc6K&ZRaMAjGS;tO&%%WZ$;-?8ZsY$JUS3|n zKw`h9$JW+X^m@It{w;!nf&j?K$iU6bO_JZdd6Ttk*A7dyU%q_d)TvVdL`O&eRPjc< zDpXfjqf)8R>-CZ>EG&%Y&!5xY-cCeB1a`Zft5>f|6lXG-C@(K3EG$g2QK?kqfR~@bK^eptG~nNj}&@2G_sE;K}>&;R9)DX`DQH61&~b%9Sfg zO-=pjIKGDw2bR~bU(?#!iosx@rltn1R*RpX9~UlM0KnJR7n{w-iWMuI?0kHD@bvUV zCX)dJ$$s_fm9+lm%^RAUnn+AcBr-CRr%#_^GMQ*;X&E*SZ*OlZDk_|0cDtRXrY0s$ znk30uTU&?dj1^s7UBE!^{TePVE&wAAQ-=;6;?${AJbU)csfVYeq_AnzCXO6AGUk|u z!>H3{RaF(smMue}P+%|^=;`T^1`a_Ga5x-jG#V!xQ4|qH5v5WI4D^k!6KS{GIez>& z^XAPXG&Gdx=xAbNV=e$)tWY ze*Aa&4UQT&=If5WCXU-fpY}i0lR1^gT1y1^+C=T0WyuH1L z^v7R?!9J>1s|gMcrna^g7Z(>oLP7wBy=-eV8nUvofPp*R%a<>KfhifFy}kXH$2scr z*!%bIX>4p{@#4kkbUG*cvREukm@vU{uRx8P-O`FDy88iN8mw2PmC?!8VJ)Mw{5Yp4r(P%W-Y&L1q ztf{F%6h)36JxW(s7pqsVCMhY2%*;%Jf`VAHW{q@Z7@T_d?c0YaicYjTR($u8UR_;H zTwENlU%z(hOHZCW!E83OZQC}=%E}N$5re_N#EBEh$;lbA_$yAeYN|^ytwL{oA*16B-&yYHBJK6%{CzN}{5oXlrYehL~TC{{DW_($dJz&L%!S zp7{89Y3=ag!?d-v0Rzux9v&W2>)5kr4;L<6AR!@vgoFgi=EaK_?BBm17+@w3507Ct z>d!*HV8Md@qbZ1@h{NHatgOt5>m3dUj~_oqCX=Dp>(S|SynXwYix)3SuL*)6(9zK$ z(GY;mW~08o9xpF1{QdozGG&TnH#l@Cl}aoY3+?Ugba!|2(e)YjHgSy_pJ)lgSxsp4jee( zG<2xdYAP!$xp(g#_4V}_jYbL!3#Hy@wOToM?i^dUZj~N2lu9L5tCf 0.5.0 + y="83.4077">0.5.1