Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FUSE API] Hardlink count from st_nlink is not propagated #511

Open
mhx opened this issue Jun 27, 2023 · 1 comment
Open

[FUSE API] Hardlink count from st_nlink is not propagated #511

mhx opened this issue Jun 27, 2023 · 1 comment

Comments

@mhx
Copy link

mhx commented Jun 27, 2023

Bug Report

I believe this is a bug (or missing feature) in the WinFsp FUSE API. It seems that the hardlink count returned from a getattr call isn't propagated to the Windows filesystem layer (i.e. nNumberOfLinks in BY_HANDLE_FILE_INFORMATION always reads 1).

How to Reproduce

Use a filesystem that returns st_nlink > 1 in getattr. Checking with the stat tool I can see that two files share the same inode, but each of them has their link count reported as 1 (even though st_nlink is actually 3):

C:\Users\mhx\git\dwarfs\build-vcpkg\tmp>stat format.sh
  File: format.sh
  Size: 94              Blocks: 4          IO Block: 65536  regular file
Device: 13b1fae8h/330431208d    Inode: 31          Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (197608/     mhx)   Gid: (197121/    None)
Access: 2020-11-24 23:14:05.000000000 +0100
Modify: 2020-11-24 23:14:05.000000000 +0100
Change: 2020-11-24 23:14:05.000000000 +0100
 Birth: -

C:\Users\mhx\git\dwarfs\build-vcpkg\tmp>stat foo\1\fmt.sh
  File: foo\1\fmt.sh
  Size: 94              Blocks: 4          IO Block: 65536  regular file
Device: 13b1fae8h/330431208d    Inode: 31          Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (197608/     mhx)   Gid: (197121/    None)
Access: 2020-11-24 23:14:05.000000000 +0100
Modify: 2020-11-24 23:14:05.000000000 +0100
Change: 2020-11-24 23:14:05.000000000 +0100
 Birth: -

At the same time, logging from the getattr operation shows that st_nlink is returned as 3:

The service dwarfs has been started.
I 19:18:53.286122 op_getattr(/) -> st_nlink = 1
I 19:18:53.295476 op_getattr(/) -> st_nlink = 1
I 19:18:57.275441 op_getattr(/) -> st_nlink = 1
I 19:18:57.284256 op_getattr(/) -> st_nlink = 1
I 19:18:57.292798 op_getattr(/) -> st_nlink = 1
I 19:18:57.305563 op_getattr(/test.py) -> st_nlink = 1
I 19:18:57.316398 op_getattr(/perl-exec.sh) -> st_nlink = 1
I 19:18:57.321562 op_getattr(/format.sh) -> st_nlink = 3
I 19:18:57.327337 op_getattr(/foobar) -> st_nlink = 1
I 19:18:57.330381 op_getattr(/foo) -> st_nlink = 1
I 19:18:57.332785 op_getattr(/foo/bar) -> st_nlink = 1
I 19:18:57.334925 op_getattr(/foo) -> st_nlink = 1
I 19:18:57.337009 op_getattr(/empty) -> st_nlink = 1
I 19:18:57.338977 op_getattr(/dev) -> st_nlink = 1
I 19:18:57.340728 op_getattr(/bench.sh) -> st_nlink = 3
I 19:18:57.349516 op_getattr(/) -> st_nlink = 1
I 19:18:57.351154 op_getattr(/) -> st_nlink = 1
I 19:18:57.362641 op_getattr(/) -> st_nlink = 1
I 19:18:57.364635 op_getattr(/) -> st_nlink = 1
I 19:18:57.371488 op_getattr(/format.sh) -> st_nlink = 3
I 19:18:57.373200 op_getattr(/format.sh) -> st_nlink = 3
I 19:18:57.376306 op_getattr(/format.sh) -> st_nlink = 3
I 19:18:57.377897 op_getattr(/format.sh) -> st_nlink = 3
I 19:18:57.379452 op_getattr(/format.sh) -> st_nlink = 3
I 19:19:00.475283 op_getattr(/) -> st_nlink = 1
I 19:19:00.483435 op_getattr(/) -> st_nlink = 1
I 19:19:00.494293 op_getattr(/) -> st_nlink = 1
I 19:19:00.506619 op_getattr(/test.py) -> st_nlink = 1
I 19:19:00.513854 op_getattr(/perl-exec.sh) -> st_nlink = 1
I 19:19:00.520416 op_getattr(/format.sh) -> st_nlink = 3
I 19:19:00.523694 op_getattr(/foobar) -> st_nlink = 1
I 19:19:00.526209 op_getattr(/foo) -> st_nlink = 1
I 19:19:00.528573 op_getattr(/foo/bar) -> st_nlink = 1
I 19:19:00.530738 op_getattr(/foo) -> st_nlink = 1
I 19:19:00.532787 op_getattr(/empty) -> st_nlink = 1
I 19:19:00.535353 op_getattr(/dev) -> st_nlink = 1
I 19:19:00.537032 op_getattr(/bench.sh) -> st_nlink = 3
I 19:19:00.544552 op_getattr(/) -> st_nlink = 1
I 19:19:00.546592 op_getattr(/) -> st_nlink = 1
I 19:19:00.557711 op_getattr(/) -> st_nlink = 1
I 19:19:00.559188 op_getattr(/) -> st_nlink = 1
I 19:19:00.567073 op_getattr(/foo/1/fmt.sh) -> st_nlink = 3
I 19:19:00.568609 op_getattr(/foo) -> st_nlink = 1
I 19:19:00.570069 op_getattr(/foo/1) -> st_nlink = 1
I 19:19:00.571452 op_getattr(/foo/1/fmt.sh) -> st_nlink = 3
I 19:19:00.573116 op_getattr(/foo/1/fmt.sh) -> st_nlink = 3
I 19:19:00.574943 op_getattr(/foo) -> st_nlink = 1
I 19:19:00.576228 op_getattr(/foo/1) -> st_nlink = 1
I 19:19:00.578614 op_getattr(/foo/1/fmt.sh) -> st_nlink = 3
I 19:19:00.580114 op_getattr(/foo/1/fmt.sh) -> st_nlink = 3

Behaviors

I'd expect stat to report the correct hardlink count.

Environment

  • OS version and build: 10.0.22621
  • WinFsp version and build: 2.0.23075
@billziss-gh
Copy link
Collaborator

billziss-gh commented Aug 7, 2023

WinFsp does not support hard links. Please see NTFS Compatibility / Unsupported features.

Related #28

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants