1
0
mirror of https://github.com/winfsp/hubfs.git synced 2022-03-13 05:11:16 +03:00

fs: hubfs: Getattr: remove /. handling

This commit is contained in:
Bill Zissimopoulos
2022-02-27 14:54:15 +00:00
parent e38ebc6338
commit e3ca6b43da

View File

@@ -180,58 +180,19 @@ func (fs *hubfs) Readpath(path string) (errc int, target string) {
func (fs *hubfs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
defer trace(path, fh)(&errc, stat)
// The resolve logic below is specific to Windows and WinFsp. An
// explanation follows.
//
// On Windows symbolic links (symlinks) are marked as directory symlinks
// or file symlinks. This is important for some apps on Windows; for
// example CMD.EXE is unable to properly CD into a symlink that points to
// a directory if the symlink is not marked as a directory symlink.
//
// When WinFsp-FUSE (the FUSE layer of WinFsp) issues Getattr and sees a
// symlink it must also inform Windows if it is a directory (see above).
// At the time I was writing the WinFsp-FUSE layer I got a bit lazy: I
// should have written the code to issue all the necessary Readlink calls
// to properly resolve the symlink and then issue Getattr on the result.
// Instead I punted on this and wrote simple logic to issue a Getattr on
// the original path+"/." and expected the file system to deal with it.
//
// WinFsp-FUSE will only ever send path+"/." in this particular case. The
// file system is supposed to fill the Stat_t struct with the appropriate
// file mode that shows whether the (pointed) file is a directory. WinFsp-
// FUSE will then mark the symlink appropriately.
//
// Our resolve logic below works well for the case where the last path
// component is a symlink. This covers the important use case of
// submodules. However the logic does not currently handle cases where
// a symlink is at the middle of the path:
//
// path = /name/.../name/LINK1/. --resolves-to->
// path = /name/.../name/LINK2/name/.../name --resolves-to-> ?
if strings.HasSuffix(path, "/.") {
return -fuse.ENOENT
}
resolve := strings.HasSuffix(path, "/.")
retries := 0
retry:
errc, obs := fs.open(path)
if 0 != errc {
return
}
target := fs.getattr(obs, obs.entry, path, stat)
fs.getattr(obs, obs.entry, path, stat)
fs.release(obs)
if resolve && "" != target && 16 > retries {
if '/' == target[0] {
path = target
} else {
path = pathutil.Join(path, "..", target)
}
retries++
goto retry
}
return
}