2011-04-28 23:37:44 +02:00
|
|
|
/*
|
2011-03-04 20:59:21 +01:00
|
|
|
* Copyright (C) 2011 Andrea Mazzoleni
|
|
|
|
|
*
|
|
|
|
|
* 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 3 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef __ELEM_H
|
|
|
|
|
#define __ELEM_H
|
|
|
|
|
|
2011-03-25 21:04:46 +01:00
|
|
|
#include "util.h"
|
2011-03-04 20:59:21 +01:00
|
|
|
#include "tommylist.h"
|
|
|
|
|
#include "tommyhash.h"
|
|
|
|
|
#include "tommyhashdyn.h"
|
|
|
|
|
#include "tommyarray.h"
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* snapraid */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Invalid position.
|
|
|
|
|
*/
|
2011-03-30 17:13:42 +02:00
|
|
|
#define POS_INVALID ((block_off_t)-1)
|
2011-03-04 20:59:21 +01:00
|
|
|
|
|
|
|
|
/**
|
2011-03-12 10:09:59 +01:00
|
|
|
* Basic block position type.
|
2011-03-06 22:52:50 +01:00
|
|
|
* With 32 bits and 128k blocks you can address 256 TB.
|
2011-03-04 20:59:21 +01:00
|
|
|
*/
|
2011-03-12 10:09:59 +01:00
|
|
|
typedef uint32_t block_off_t;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Basic data position type.
|
2011-03-30 17:13:42 +02:00
|
|
|
* It's signed as file size and offset are usually signed.
|
2011-03-12 10:09:59 +01:00
|
|
|
*/
|
2011-03-30 17:13:42 +02:00
|
|
|
typedef int64_t data_off_t;
|
2011-03-04 20:59:21 +01:00
|
|
|
|
2011-04-25 13:43:51 +02:00
|
|
|
/**
|
|
|
|
|
* Content file specification.
|
|
|
|
|
*/
|
|
|
|
|
struct snapraid_content {
|
|
|
|
|
char content[PATH_MAX]; /**< Path of the content file. */
|
|
|
|
|
tommy_node node; /**< Next node in the list. */
|
|
|
|
|
};
|
|
|
|
|
|
2011-03-16 23:52:10 +01:00
|
|
|
/**
|
|
|
|
|
* Filter for paths.
|
|
|
|
|
*/
|
|
|
|
|
struct snapraid_filter {
|
|
|
|
|
char pattern[PATH_MAX]; /**< Filter pattern. */
|
|
|
|
|
int is_path; /**< If the pattern is only for the complete path. */
|
|
|
|
|
int is_dir; /**< If the pattern is only for dir. */
|
2011-04-26 18:51:42 +02:00
|
|
|
int direction; /**< If it's an inclusion (=1) or an exclusion (=-1). */
|
2011-03-16 23:52:10 +01:00
|
|
|
tommy_node node; /**< Next node in the list. */
|
|
|
|
|
};
|
|
|
|
|
|
2011-03-04 20:59:21 +01:00
|
|
|
struct snapraid_file;
|
|
|
|
|
|
2011-03-22 23:23:45 +01:00
|
|
|
#define BLOCK_HAS_HASH 1 /**< If the hash value is valid. */
|
|
|
|
|
#define BLOCK_HAS_PARITY 2 /**< If the parity block is valid. */
|
|
|
|
|
|
2011-03-04 20:59:21 +01:00
|
|
|
/**
|
|
|
|
|
* Block of a file.
|
|
|
|
|
*/
|
|
|
|
|
struct snapraid_block {
|
2011-03-12 10:09:59 +01:00
|
|
|
block_off_t parity_pos; /**< Position of the block in the parity. */
|
2011-04-28 23:09:19 +02:00
|
|
|
uintptr_t file_mixed; /**< Back pointer to the file owning this block, mixed with some flags. */
|
2011-04-12 22:16:35 +02:00
|
|
|
unsigned char hash[HASH_SIZE]; /**< Hash of the block. */
|
2011-03-04 20:59:21 +01:00
|
|
|
};
|
|
|
|
|
|
2011-04-28 23:09:19 +02:00
|
|
|
#define FILE_IS_PRESENT 1 /**< If it's seen as present. */
|
|
|
|
|
#define FILE_IS_EXCLUDED 2 /**< If it's an excluded file from the processing. */
|
|
|
|
|
#define FILE_IS_LARGER 4 /**< If a larger file was already detected. */
|
|
|
|
|
|
2011-03-04 20:59:21 +01:00
|
|
|
/**
|
|
|
|
|
* File.
|
|
|
|
|
*/
|
|
|
|
|
struct snapraid_file {
|
2011-04-28 23:09:19 +02:00
|
|
|
int64_t mtime; /**< Modification time. */
|
|
|
|
|
uint64_t inode; /**< Inode. */
|
2011-03-12 10:09:59 +01:00
|
|
|
data_off_t size; /**< Size of the file. */
|
2011-03-04 20:59:21 +01:00
|
|
|
struct snapraid_block* blockvec; /**< All the blocks of the file. */
|
2011-03-12 10:09:59 +01:00
|
|
|
block_off_t blockmax; /**< Number of blocks. */
|
2011-04-28 23:09:19 +02:00
|
|
|
unsigned flag; /**< FILE_IS_* flags. */
|
|
|
|
|
char sub[PATH_MAX]; /**< Sub path of the file. Without the disk dir. The disk is implicit. */
|
|
|
|
|
|
2011-03-04 20:59:21 +01:00
|
|
|
/* nodes for data structures */
|
|
|
|
|
tommy_node nodelist;
|
|
|
|
|
tommy_hashdyn_node nodeset;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Disk.
|
|
|
|
|
*/
|
|
|
|
|
struct snapraid_disk {
|
|
|
|
|
char name[PATH_MAX]; /**< Name of the disk. */
|
2011-03-12 23:36:37 +01:00
|
|
|
char dir[PATH_MAX]; /**< Mount point of the disk. It always terminates with /. */
|
2011-03-12 10:09:59 +01:00
|
|
|
block_off_t first_free_block; /**< First free searching block. */
|
2011-03-04 20:59:21 +01:00
|
|
|
tommy_list filelist; /**< List of all the files. */
|
2011-03-20 22:36:49 +01:00
|
|
|
tommy_hashdyn inodeset; /**< Hashtable by inode of all the files. */
|
2011-03-04 20:59:21 +01:00
|
|
|
tommy_array blockarr; /**< Block array of the disk. */
|
|
|
|
|
};
|
|
|
|
|
|
2011-04-25 13:43:51 +02:00
|
|
|
/**
|
|
|
|
|
* Allocates a content.
|
|
|
|
|
*/
|
|
|
|
|
struct snapraid_content* content_alloc(const char* path);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Deallocates a content.
|
|
|
|
|
*/
|
|
|
|
|
void content_free(struct snapraid_content* content);
|
|
|
|
|
|
2011-03-16 23:52:10 +01:00
|
|
|
/**
|
|
|
|
|
* Allocates an exclusion.
|
|
|
|
|
*/
|
2011-04-26 18:51:42 +02:00
|
|
|
struct snapraid_filter* filter_alloc(int is_include, const char* pattern);
|
2011-03-16 23:52:10 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Deallocates an exclusion.
|
|
|
|
|
*/
|
|
|
|
|
void filter_free(struct snapraid_filter* filter);
|
|
|
|
|
|
2011-03-30 00:14:43 +02:00
|
|
|
/**
|
2011-04-26 18:51:42 +02:00
|
|
|
* Filters a path.
|
|
|
|
|
* For each element of the path all the filters are applied, until the first one that matches.
|
|
|
|
|
* Returns 0 if the files has to be processed.
|
2011-03-30 00:14:43 +02:00
|
|
|
*/
|
2011-04-26 18:51:42 +02:00
|
|
|
int filter_path(tommy_list* filterlist, const char* path, int is_dir);
|
2011-03-16 23:52:10 +01:00
|
|
|
|
2011-04-28 23:09:19 +02:00
|
|
|
static inline struct snapraid_file* block_file_get(struct snapraid_block* block)
|
|
|
|
|
{
|
|
|
|
|
return (struct snapraid_file*)(block->file_mixed & ~(uintptr_t)3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void block_file_set(struct snapraid_block* block, struct snapraid_file* file)
|
|
|
|
|
{
|
|
|
|
|
block->file_mixed = (block->file_mixed & ~(uintptr_t)3) | (uintptr_t)file;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int block_flag_has(struct snapraid_block* block, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
return (block->file_mixed & mask) == mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void block_flag_set(struct snapraid_block* block, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
block->file_mixed |= mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void block_flag_clear(struct snapraid_block* block, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
block->file_mixed &= ~(uintptr_t)mask;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-04 20:59:21 +01:00
|
|
|
/**
|
2011-03-12 23:36:37 +01:00
|
|
|
* Gets the relative position of a block inside the file.
|
2011-03-04 20:59:21 +01:00
|
|
|
*/
|
2011-03-12 10:09:59 +01:00
|
|
|
block_off_t block_file_pos(struct snapraid_block* block);
|
2011-03-04 20:59:21 +01:00
|
|
|
|
|
|
|
|
/**
|
2011-03-12 23:36:37 +01:00
|
|
|
* Gets the size in bytes of the block.
|
|
|
|
|
* If it's the last block of a file it could be less than block_size.
|
2011-03-04 20:59:21 +01:00
|
|
|
*/
|
|
|
|
|
unsigned block_file_size(struct snapraid_block* block, unsigned block_size);
|
|
|
|
|
|
2011-04-28 23:09:19 +02:00
|
|
|
static inline int file_flag_has(struct snapraid_file* file, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
return (file->flag & mask) == mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
file->flag |= mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
file->flag &= ~mask;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
|
|
|
|
* Allocates a file.
|
|
|
|
|
*/
|
2011-03-20 22:36:49 +01:00
|
|
|
struct snapraid_file* file_alloc(unsigned block_size, const char* sub, uint64_t size, uint64_t mtime, uint64_t inode);
|
2011-03-04 20:59:21 +01:00
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
2011-03-16 23:52:10 +01:00
|
|
|
* Deallocates a file.
|
2011-03-12 23:36:37 +01:00
|
|
|
*/
|
2011-03-04 20:59:21 +01:00
|
|
|
void file_free(struct snapraid_file* file);
|
|
|
|
|
|
2011-03-30 00:14:43 +02:00
|
|
|
/**
|
|
|
|
|
* Returns the name of the file, without the dir.
|
|
|
|
|
*/
|
|
|
|
|
const char* file_name(struct snapraid_file* file);
|
|
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
2011-03-20 22:36:49 +01:00
|
|
|
* Compares two files by inode.
|
2011-03-12 23:36:37 +01:00
|
|
|
*/
|
2011-03-20 22:36:49 +01:00
|
|
|
int file_inode_compare(const void* void_arg, const void* void_data);
|
2011-03-04 20:59:21 +01:00
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
2011-03-20 22:36:49 +01:00
|
|
|
* Computes the hash of a file inode.
|
2011-03-12 23:36:37 +01:00
|
|
|
*/
|
2011-03-20 22:36:49 +01:00
|
|
|
static inline tommy_uint32_t file_inode_hash(uint64_t inode)
|
2011-03-04 20:59:21 +01:00
|
|
|
{
|
2011-03-20 22:36:49 +01:00
|
|
|
return (tommy_uint32_t)tommy_inthash_u64(inode);
|
2011-03-04 20:59:21 +01:00
|
|
|
}
|
|
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
|
|
|
|
* Allocates a disk.
|
|
|
|
|
*/
|
2011-03-04 20:59:21 +01:00
|
|
|
struct snapraid_disk* disk_alloc(const char* name, const char* dir);
|
|
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
|
|
|
|
* Deallocates a disk.
|
|
|
|
|
*/
|
2011-03-04 20:59:21 +01:00
|
|
|
void disk_free(struct snapraid_disk* disk);
|
|
|
|
|
|
2011-03-12 23:36:37 +01:00
|
|
|
/**
|
|
|
|
|
* Gets a specific block of a disk.
|
|
|
|
|
* Returns 0 if the block is over the end of the disk or not used.
|
|
|
|
|
*/
|
2011-03-12 10:09:59 +01:00
|
|
|
static inline struct snapraid_block* disk_block_get(struct snapraid_disk* disk, block_off_t pos)
|
2011-03-04 20:59:21 +01:00
|
|
|
{
|
|
|
|
|
if (pos < tommy_array_size(&disk->blockarr))
|
|
|
|
|
return tommy_array_get(&disk->blockarr, pos);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|