Merge the CLI and Daemon portable interface

This commit is contained in:
Andrea Mazzoleni 2026-06-24 00:15:15 +02:00
parent 3302518566
commit 3ce5a5b4e5
46 changed files with 4110 additions and 2042 deletions

View file

@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2013 Andrea Mazzoleni
#include "portable.h"
#include "os/portable.h"
#ifndef __MINGW32__ /* Only for Unix */
#include "os.h"
#include "app.h"
#include "support.h"
/****************************************************************************/
@ -23,7 +23,7 @@ int exit_sync_needed = 2;
volatile int global_interrupt = 0;
int app_global_interrupt(void)
int os_signal_interrupt(void)
{
return global_interrupt;
}
@ -1295,7 +1295,6 @@ static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
}
#endif
/**
* Get the LABEL using libblkid.
* It uses a cache to work without root permission, resulting in LABEL
@ -1594,118 +1593,6 @@ int devuuid(uint64_t device_id, const char* device_path, char* uuid, size_t uuid
/****************************************************************************/
/* fs */
int filephy(const char* path, uint64_t size, uint64_t* physical)
{
#if HAVE_LINUX_FIEMAP_H
/*
* In Linux get the real physical address of the file
* Note that FIEMAP doesn't require root permission
*/
int f;
struct fiemap* fiemap;
size_t fiemap_size;
unsigned int blknum;
f = open(path, O_RDONLY);
if (f == -1) {
/* LCOV_EXCL_START */
return -1;
/* LCOV_EXCL_STOP */
}
/*
* First try with FIEMAP
* if works for ext2, ext3, ext4, xfs, btrfs
*/
fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent);
fiemap = malloc_nofail(fiemap_size);
memset(fiemap, 0, fiemap_size);
fiemap->fm_start = 0;
fiemap->fm_length = ~0ULL;
fiemap->fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */
fiemap->fm_extent_count = 1; /* we are interested only at the first block */
if (ioctl(f, FS_IOC_FIEMAP, fiemap) != -1) {
uint32_t flags = fiemap->fm_extents[0].fe_flags;
uint64_t offset = fiemap->fm_extents[0].fe_physical;
/* check some condition for validating the offset */
if (flags & FIEMAP_EXTENT_DATA_INLINE) {
/* if the data is inline, we don't have an offset to report */
*physical = FILEPHY_WITHOUT_OFFSET;
} else if (flags & FIEMAP_EXTENT_UNKNOWN) {
/* if the offset is unknown, we don't have an offset to report */
*physical = FILEPHY_WITHOUT_OFFSET;
} else if (offset == 0) {
/*
* 0 is the general fallback for file-systems when
* they don't have an offset to report
*/
*physical = FILEPHY_WITHOUT_OFFSET;
} else {
/* finally report the real offset */
*physical = offset + FILEPHY_REAL_OFFSET;
}
free(fiemap);
if (close(f) == -1)
return -1;
return 0;
}
free(fiemap);
/* if the file is empty, FIBMAP doesn't work, and we don't even try to use it */
if (size == 0) {
*physical = FILEPHY_WITHOUT_OFFSET;
if (close(f) == -1)
return -1;
return 0;
}
/*
* Then try with FIBMAP
* it works for jfs, reiserfs, ntfs-3g
* in exfat it always returns 0, that it's anyway better than the fake inodes
*/
blknum = 0; /* first block */
if (ioctl(f, FIBMAP, &blknum) != -1) {
*physical = blknum + FILEPHY_REAL_OFFSET;
if (close(f) == -1)
return -1;
return 0;
}
/*
* Otherwise don't use anything, and keep the directory traversal order
* at now this should happen only for vfat
* and it's surely better than using fake inodes
*/
*physical = FILEPHY_UNREPORTED_OFFSET;
if (close(f) == -1)
return -1;
#else
/*
* In a generic Unix use a dummy value for all the files
* We don't want to risk to use the inode without knowing
* if it really improves performance.
* In this way we keep them in the directory traversal order
* that at least keeps files in the same directory together.
* Note also that in newer file-system with snapshot, like ZFS,
* the inode doesn't represent even more the disk position, because files
* are not overwritten in place, but rewritten in another location
* of the disk.
*/
*physical = FILEPHY_UNREPORTED_OFFSET;
(void)path; /* not used here */
(void)size;
#endif
return 0;
}
/* from man statfs */
#define ADFS_SUPER_MAGIC 0xadf5
#define AFFS_SUPER_MAGIC 0xADFF
@ -1800,6 +1687,9 @@ int filephy(const char* path, uint64_t size, uint64_t* physical)
#define UFS_BYTESWAPPED_SUPER_MAGIC 0x54190100
#define VMHGFS_SUPER_MAGIC 0xBACBACBC
#define VZFS_SUPER_MAGIC 0x565A4653
#define BTRFS_SUPER_MAGIC 0x9123683E
#define BCACHEFS_SUPER_MAGIC 0xCA451A4E
#define ZFS_SUPER_MAGIC 0x2FC12FC1
struct filesystem_entry {
unsigned id;
@ -2035,6 +1925,9 @@ int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_har
return 0;
}
/****************************************************************************/
/* snapshot */
#if HAVE_LINUX_DEVICE
static int fssnapshot_inode(const char* path, uint32_t magic, uint64_t root_inode, struct fssnapshot_struct* fss)
{