mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Fix incorrect st_nlink inheritance from directory in Windows stream scanner
This commit is contained in:
parent
c9fbc058ef
commit
b113accaad
3 changed files with 18 additions and 8 deletions
|
|
@ -1577,10 +1577,13 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa
|
|||
|
||||
#if HAVE_LSTAT_SYNC
|
||||
/*
|
||||
* If the st_ino field is missing, takes care to fill it using the extended lstat()
|
||||
* this can happen only in Windows
|
||||
* In Windows fast directory enumeration, st_ino and st_nlink may be
|
||||
* missing (0). If a field is needed, lstat_sync() must be called to
|
||||
* retrieve it. Here only st_ino is required for file identity and
|
||||
* hardlink tracking, while st_nlink is not; we call lstat_sync() only
|
||||
* when st_ino is missing to avoid expensive file opens.
|
||||
*/
|
||||
if (st->st_ino == INODE_INVALID || st->st_nlink == 0) {
|
||||
if (st->st_ino == INODE_INVALID) {
|
||||
if (lstat_sync(path_next, st, 0) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_tag("%s:%u:%s:%s: Stat error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next), strerror(errno));
|
||||
|
|
|
|||
|
|
@ -547,7 +547,12 @@ static int windows_stream2stat(const BY_HANDLE_FILE_INFORMATION* info, const FIL
|
|||
|
||||
st->st_ino = stream->FileId.QuadPart;
|
||||
|
||||
st->st_nlink = info->nNumberOfLinks;
|
||||
/*
|
||||
* FILE_ID_BOTH_DIR_INFO doesn't provide the hardlink count of the entry.
|
||||
* The BY_HANDLE_FILE_INFORMATION refers to the directory itself, so its
|
||||
* nNumberOfLinks cannot be used for the child.
|
||||
*/
|
||||
st->st_nlink = 0;
|
||||
|
||||
st->st_dev = info->dwVolumeSerialNumber;
|
||||
|
||||
|
|
|
|||
10
os/mingw.h
10
os/mingw.h
|
|
@ -409,11 +409,13 @@ int windows_closedir(windows_dir* dirstream);
|
|||
* Specifically this happens if we are using GetFileInformationByHandleEx()
|
||||
* to read the directory stream.
|
||||
*
|
||||
* The st_ino field may be 0 if it's not possible to read it in a fast way.
|
||||
* Specifically this happens if we are using FindFirst/FindNext to enumerate
|
||||
* the directory.
|
||||
* The st_ino and st_nlink fields may be 0 if the fast directory enumeration
|
||||
* API does not provide them. Specifically, st_ino is 0 with FindFirst/FindNext,
|
||||
* while st_nlink is 0 with both directory streams and FindFirst/FindNext.
|
||||
*
|
||||
* In such cases, call lstat_sync() to fill the missing fields.
|
||||
* If a missing field is actually needed by the caller, call lstat_sync()
|
||||
* to retrieve it from the file handle. Otherwise, avoid calling lstat_sync()
|
||||
* to preserve fast directory scanning performance.
|
||||
*/
|
||||
void windows_dirent_lstat(const struct windows_dirent* dd, struct windows_stat* st);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue