shufflecake/shufflecake-userland/include/utils/disk.h
2024-09-01 17:16:57 +02:00

103 lines
3.6 KiB
C

/*
* 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
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
*
* 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 <https://www.shufflecake.net>.
*
* 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 <https://www.gnu.org/licenses/>.
*/
/*
* Disk helper functions
*/
#ifndef _UTILS_DISK_H_
#define _UTILS_DISK_H_
/*****************************************************
* INCLUDE SECTION *
*****************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "utils/math.h"
#include "utils/sflc.h"
/*****************************************************
* MACROS *
*****************************************************/
/**
* Max slices for given disk size (in 4096-byte blocks). LITE version
*/
static inline uint32_t sflite_disk_maxSlices(uint64_t size) {
uint64_t nr_slices;
// Start from upper bound
nr_slices = size / SFLC_SLICE_SCALE;
while(true) {
if (nr_slices == 0)
break;
// Stop when this nr_slices can fit in size, including the header
uint64_t posmap_blocks = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK);
uint64_t header_size = 1 + SFLC_DEV_MAX_VOLUMES * (1 + posmap_blocks);
if (header_size + nr_slices*SFLC_SLICE_SCALE <= size)
break;
nr_slices--;
}
return nr_slices > SFLC_MAX_SLICES ? SFLC_MAX_SLICES : (uint32_t) nr_slices;
}
/* LEGACY version */
#define sflegc_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFLEGC_BLOCKS_PER_PHYS_SLICE)
/* We need this inequality to hold, in order for the previous bound to be true */
#if SFLC_DEV_MAX_VOLUMES * 2 > SFLC_SLICE_IDX_PER_BLOCK
#error "Invalid combination of parameters, probably SFLC_DEV_MAX_VOLUMES is too big"
#endif
/*****************************************************
* PUBLIC FUNCTIONS PROTOTYPES *
*****************************************************/
/* Returns a malloc'ed string formatted as <MAJOR>:<MINOR> */
char *sflc_disk_getDeviceName(char *bdev_path);
/* Checks whether the given path points to a block device */
bool sflc_disk_isBlockDevice(char *path);
/* Returns the size in 4096-byte sectors (or < 0 if error) */
int64_t sflc_disk_getSize(char *bdev_path);
/* Reads a single 4096-byte block from the disk */
int sflc_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf);
/* Writes many 4096-byte blocks to the disk */
int sflc_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks);
/* Writes a single 4096-byte block to the disk */
#define sflc_disk_writeBlock(bdev_path, bnum, buf) sflc_disk_writeManyBlocks(bdev_path, bnum, buf, 1)
#endif /* _UTILS_DISK_H_ */