WIP: Fix links creation for windows/winfsp

This commit is contained in:
Filipe Azevedo 2023-06-11 17:27:46 +02:00 committed by Nick Craig-Wood
parent e15f711117
commit 2a00583f5c
4 changed files with 26 additions and 17 deletions

2
.gitignore vendored
View File

@ -16,3 +16,5 @@ Thumbs.db
__pycache__
.DS_Store
*.kate-swp
*debug*bin*
.vscode/

View File

@ -1101,12 +1101,18 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
rnewName += fs.LinkSuffix
}
_, err = destDir.stat(rnewName)
statFile, err := destDir.stat(rnewName)
switch err {
case ENOENT:
// not found, carry on
case nil:
// Special case for windows / winfsp symlinks, it create a file early that is never deleted, leading to clash.
if d.vfs.Opt.Links && isLink && strings.HasPrefix(oldName, ".fuse_hidden") {
statFile.(*File).winfspPendingSymlink = true
break
}
return EEXIST
default:
// a different error - report

View File

@ -41,18 +41,19 @@ type File struct {
muRW sync.Mutex // synchronize RWFileHandle.openPending(), RWFileHandle.close() and File.Remove
mu sync.RWMutex // protects the following
d *Dir // parent directory
dPath string // path of parent directory. NB dir rename means all Files are flushed
o fs.Object // NB o may be nil if file is being written
leaf string // leaf name of the object
writers []Handle // writers for this file
virtualModTime *time.Time // modtime for backends with Precision == fs.ModTimeNotSupported
pendingModTime time.Time // will be applied once o becomes available, i.e. after file was written
pendingRenameFun func(ctx context.Context) error // will be run/renamed after all writers close
sys atomic.Value // user defined info to be attached here
nwriters atomic.Int32 // len(writers)
appendMode bool // file was opened with O_APPEND
mu sync.RWMutex // protects the following
d *Dir // parent directory
dPath string // path of parent directory. NB dir rename means all Files are flushed
o fs.Object // NB o may be nil if file is being written
leaf string // leaf name of the object
writers []Handle // writers for this file
virtualModTime *time.Time // modtime for backends with Precision == fs.ModTimeNotSupported
pendingModTime time.Time // will be applied once o becomes available, i.e. after file was written
pendingRenameFun func(ctx context.Context) error // will be run/renamed after all writers close
sys atomic.Value // user defined info to be attached here
nwriters atomic.Int32 // len(writers)
appendMode bool // file was opened with O_APPEND
winfspPendingSymlink bool // windows/winfsp symlinks support - when true, this file node needs to be deleted
}
// newFile creates a new File
@ -285,6 +286,10 @@ func (f *File) addWriter(h Handle) {
// delWriter removes a write handle from the file
func (f *File) delWriter(h Handle) {
f.mu.Lock()
// Special case for windows / winfsp symlinks
if f.d.vfs.Opt.Links && f.winfspPendingSymlink && len(f.writers) == 1 {
defer f.Remove()
}
defer f.applyPendingRename()
defer f.mu.Unlock()
var found = -1

View File

@ -78,10 +78,6 @@ func TestFileModTimeWithOpenWriters(t *testing.T) {
func TestSymlinks(t *testing.T) {
run.skipIfNoFUSE(t)
if runtime.GOOS == "windows" {
t.Skip("Skipping test on Windows")
}
{
// VFS only implements os.Stat, which return information to target for symlinks, getting symlink information would require os.Lstat implementation.
// We will not bother to add Lstat implemented, but in the test we can just call os.Lstat which return the information needed when !useVFS