mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Detects the case of physical offsets not reported beucase the file doesn't have one.
This commit is contained in:
parent
cffbba8aee
commit
6deecb26de
6 changed files with 36 additions and 10 deletions
7
HISTORY
7
HISTORY
|
|
@ -1,6 +1,13 @@
|
|||
SnapRAID HISTORY
|
||||
================
|
||||
|
||||
4.2 2013/9
|
||||
==========
|
||||
* Fixed the wrong warning about physical offsets not supported caused
|
||||
by files not having a real offset because too small.
|
||||
For example, in NTFS it's possible to store such files in the MFT.
|
||||
It's just a cosmetic change, and not a functional one.
|
||||
|
||||
4.1 2013/9
|
||||
==========
|
||||
* If the underline filesystem doesn't support the FIEMAP command,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ([2.65])
|
||||
AC_INIT([snapraid], [4.1], [], [], [http://snapraid.sourceforge.net])
|
||||
AC_INIT([snapraid], [4.2], [], [], [http://snapraid.sourceforge.net])
|
||||
AM_INIT_AUTOMAKE([foreign no-dependencies -Wall])
|
||||
AC_CONFIG_SRCDIR([snapraid.c])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
|
|
|||
9
mingw.c
9
mingw.c
|
|
@ -1130,7 +1130,10 @@ int filephy(const char* file, struct stat* st, uint64_t* physical)
|
|||
} else if (error == ERROR_HANDLE_EOF) {
|
||||
/* if the file is small, it can be stored in the Master File Table (MFT) */
|
||||
/* and then it doesn't have a physical address */
|
||||
rpb->ExtentCount = 0;
|
||||
/* In such case we report a specific fake address, to report this special condition */
|
||||
/* that it's different from the 0 offset reported by the underline file system */
|
||||
rpb->ExtentCount = 1;
|
||||
rpb->Extents[0].Lcn.QuadPart = FILEPHY_WITHOUT_OFFSET;
|
||||
} else {
|
||||
windows_errno(error);
|
||||
CloseHandle(h);
|
||||
|
|
@ -1141,9 +1144,9 @@ int filephy(const char* file, struct stat* st, uint64_t* physical)
|
|||
CloseHandle(h);
|
||||
|
||||
if (rpb->ExtentCount < 1)
|
||||
*physical = 0;
|
||||
*physical = FILEPHY_UNREPORTED_OFFSET;
|
||||
else
|
||||
*physical = rpb->Extents[0].Lcn.QuadPart;
|
||||
*physical = rpb->Extents[0].Lcn.QuadPart + FILEPHY_REAL_OFFSET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
16
portable.h
16
portable.h
|
|
@ -187,6 +187,22 @@ static inline int hardlink(const char* a, const char* b)
|
|||
*/
|
||||
int devuuid(uint64_t device, char* uuid, size_t size);
|
||||
|
||||
/**
|
||||
* Special value returned when the file doesn't have a real offset.
|
||||
* For example, because it's stored in the NTFS MFT.
|
||||
*/
|
||||
#define FILEPHY_WITHOUT_OFFSET 0
|
||||
|
||||
/**
|
||||
* Special value returned when the filesystem doesn't report any offset for unknown reason.
|
||||
*/
|
||||
#define FILEPHY_UNREPORTED_OFFSET 1
|
||||
|
||||
/**
|
||||
* Value indicating real offsets. All offsets greater or equal at this one are real.
|
||||
*/
|
||||
#define FILEPHY_REAL_OFFSET 2
|
||||
|
||||
/**
|
||||
* Get the physcal address of the specified file.
|
||||
* This is expected to be just a hint and not necessarely correct or unique.
|
||||
|
|
|
|||
2
scan.c
2
scan.c
|
|
@ -974,7 +974,7 @@ void state_scan(struct snapraid_state* state, int output)
|
|||
|
||||
/* if the file is not empty, count duplicate physical offsets */
|
||||
if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
|
||||
if (phy_count > 0 && file->physical == phy_last)
|
||||
if (phy_count > 0 && file->physical == phy_last && phy_last != FILEPHY_WITHOUT_OFFSET)
|
||||
++phy_dup;
|
||||
phy_last = file->physical;
|
||||
++phy_count;
|
||||
|
|
|
|||
10
unix.c
10
unix.c
|
|
@ -149,7 +149,7 @@ int filephy(const char* path, struct stat* st, 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;
|
||||
*physical = fm.fiemap.fm_extents[0].fe_physical + FILEPHY_REAL_OFFSET;
|
||||
if (close(f) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
|
|
@ -157,7 +157,7 @@ int filephy(const char* path, struct stat* st, uint64_t* physical)
|
|||
|
||||
/* if empty, FIBMAP doesn't work */
|
||||
if (st->st_size == 0) {
|
||||
*physical = 0;
|
||||
*physical = FILEPHY_WITHOUT_OFFSET;
|
||||
if (close(f) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
|
|
@ -168,7 +168,7 @@ int filephy(const char* path, struct stat* st, uint64_t* physical)
|
|||
/* 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;
|
||||
*physical = blknum + FILEPHY_REAL_OFFSET;
|
||||
if (close(f) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
|
|
@ -177,13 +177,13 @@ int filephy(const char* path, struct stat* st, uint64_t* physical)
|
|||
/* otherwise don't use anything, and keep the existing order */
|
||||
/* at now this should happen only for vfat */
|
||||
/* and it's surely better than using fake inodes */
|
||||
*physical = 0;
|
||||
*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 */
|
||||
*physical = 0;
|
||||
*physical = FILEPHY_UNREPORTED_OFFSET;
|
||||
|
||||
(void)path; /* not used here */
|
||||
(void)st;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue