snapraid/cmdline/parity.h

148 lines
4.7 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-3.0-or-later
2026-04-02 16:25:49 +02:00
// Copyright (C) 2011 Andrea Mazzoleni
#ifndef __PARITY_H
#define __PARITY_H
#include "support.h"
2025-03-27 12:57:41 -07:00
#include "bw.h"
#include "state.h"
#include "io.h"
/****************************************************************************/
/* parity */
struct snapraid_split_handle {
char path[PATH_MAX]; /**< Path of the file. */
int f; /**< Handle of the files. */
struct stat st; /**< Stat info of the opened file. */
2016-05-15 14:18:44 +02:00
struct advise_struct advise; /**< Advise information. */
/**
* Size of the parity split.
* Only the latest not zero size is allowed to grow.
* Note that this value CANNOT be PARITY_SIZE_INVALID.
*/
data_off_t size;
2016-05-16 22:55:19 +02:00
2019-05-19 08:33:08 +02:00
/**
* Valid size of the parity split.
* This is the size effectively written, and not the result of a chsize operation.
2019-05-19 08:33:08 +02:00
* It's used to make read operations failing if read over that size.
*
* Parity is also truncated to that size when fixing it, in case of a Break (Ctrl+C)
* of the program.
2019-05-19 08:33:08 +02:00
*/
data_off_t valid_size;
2016-05-16 22:55:19 +02:00
/**
* Artificial size limit for testing.
* 0 means unlimited.
*/
data_off_t limit_size;
};
struct snapraid_parity_handle {
struct snapraid_split_handle split_map[SPLIT_MAX];
unsigned split_mac; /**< Number of parity splits. */
unsigned level; /**< Level of the parity. */
2025-03-27 12:57:41 -07:00
struct snapraid_bw* bw; /**< Context for bandwidth limiting. */
};
/**
2015-10-07 22:07:20 +02:00
* Compute the size of the allocated parity data in number of blocks.
*
* This includes parity blocks not yet written and still invalid.
*/
block_off_t parity_allocated_size(struct snapraid_state* state);
/**
2015-10-07 22:07:20 +02:00
* Compute the size of the used parity data in number of blocks.
*
* This includes only parity blocks used for files, not counting
* potential invalid parity at the end.
*
2016-01-02 16:52:20 +01:00
* If the array is fully synced there is no difference between
* parity_allocate_size() and parity_used_size().
* But if the sync is interrupted, the parity_used_size() returns
* the position of the latest BLK block, ignoring CHG, REL and DELETED ones,
* because their parity may be still not even written in the parity file.
*/
block_off_t parity_used_size(struct snapraid_state* state);
/**
2015-10-07 22:07:20 +02:00
* Report all the files outside the specified parity size.
*/
void parity_overflow(struct snapraid_state* state, data_off_t size);
2011-03-12 23:36:37 +01:00
/**
2015-10-07 22:07:20 +02:00
* Create the parity file.
2012-10-09 23:02:46 +02:00
* \param out_size Return the size of the parity file.
2011-03-12 23:36:37 +01:00
*/
int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size);
2012-10-09 23:02:46 +02:00
/**
2015-10-07 22:07:20 +02:00
* Change the parity size.
2012-10-09 23:02:46 +02:00
* \param out_size Return the size of the parity file. The out_size is set also on error to reflect a partial resize.
*/
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder);
/**
* Get the size of the parity.
*
* This returns the cached/expected version of the split sizes, and not the real file size.
*/
void parity_size(struct snapraid_parity_handle* handle, data_off_t* out_size);
/**
* Get the size of the contiguous valid prefix of the parity.
*
* This returns the logical prefix covered by valid data in all consecutive splits.
* For example, with two 100 GiB splits, if the first is truncated to 90 GiB
* and the second is fully valid, the valid prefix is 90 GiB, not 190 GiB.
*/
void parity_valid_size(struct snapraid_parity_handle* handle, data_off_t* out_size);
2011-03-12 23:36:37 +01:00
/**
2015-10-07 22:07:20 +02:00
* Open an already existing parity file.
2011-03-12 23:36:37 +01:00
*/
int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size);
2011-03-12 23:36:37 +01:00
/**
2015-10-07 22:07:20 +02:00
* Flush the parity file in the disk.
2011-03-12 23:36:37 +01:00
*/
int parity_sync(struct snapraid_parity_handle* handle);
2011-03-12 10:09:59 +01:00
/**
* Truncate the parity file to the valid size.
*/
int parity_truncate(struct snapraid_parity_handle* handle);
2011-03-12 23:36:37 +01:00
/**
2015-10-07 22:07:20 +02:00
* Close the parity file.
2011-03-12 23:36:37 +01:00
*/
int parity_close(struct snapraid_parity_handle* handle);
2011-03-12 23:36:37 +01:00
/**
* Read a block from the parity file.
*/
2026-06-03 20:49:36 +02:00
int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size);
2011-03-12 23:36:37 +01:00
/**
2015-10-07 22:07:20 +02:00
* Write a block in the parity file.
2011-03-12 23:36:37 +01:00
*/
int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size);
2011-03-12 23:36:37 +01:00
/**
* Complete all pending I/O and sync the parity files.
*
* This waits for all parity writes, reports their errors, and flushes the
* parity data to disk. It also waits for all scheduled read-ahead to complete
* without consuming the results, which remain available to the caller.
*/
int state_barrier(struct snapraid_state* state, struct snapraid_io* io, struct snapraid_parity_handle* parity_handle, block_off_t blockcur);
#endif