From 584c362ba46cf711c9ef19b27c89ea216f7eb804 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 20 Dec 2015 17:19:57 +0100 Subject: [PATCH] Handle correctly files without offset This avoid the warnings about duplicate offsets. --- HISTORY | 3 +++ cmdline/unix.c | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/HISTORY b/HISTORY index 2308f603..b9edf694 100644 --- a/HISTORY +++ b/HISTORY @@ -6,6 +6,9 @@ SnapRAID HISTORY * Fixes support for symlinks pointing to an empty target. Before they were only partially supported, and their presence could result in a content file not readable. + * Improves the physical offset ordering for the Btrfs filesystem, + correctly detecting files that have not a physical offset, for + whatever reason. * Adds UUID support to Btrfs filesystems. It's present only if the libblkid library is available on the system. diff --git a/cmdline/unix.c b/cmdline/unix.c index 29c23ecf..743a5170 100644 --- a/cmdline/unix.c +++ b/cmdline/unix.c @@ -210,7 +210,25 @@ int filephy(const char* path, uint64_t size, uint64_t* physical) fm.fiemap.fm_extent_count = 1; /* we are interested only at the first block */ if (ioctl(f, FS_IOC_FIEMAP, &fm) != -1) { - *physical = fm.fiemap.fm_extents[0].fe_physical + FILEPHY_REAL_OFFSET; + uint32_t flags = fm.fiemap.fm_extents[0].fe_flags; + uint64_t offset = fm.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 filesystems when */ + /* they don't have an offset to report */ + *physical = FILEPHY_WITHOUT_OFFSET; + } else { + /* finally report the real offset */ + *physical = offset + FILEPHY_REAL_OFFSET; + } + if (close(f) == -1) return -1; return 0;