Skip to content

Commit

Permalink
Windows: fixed incorrect permission error returned; fix #5599 (#5629)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjie4255 authored Feb 10, 2025
1 parent ad7ad4f commit 08d5d82
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ pkg/meta/testdata
/juicefs
/juicefs.ceph
/juicefs.exe
/juicefsd.exe
/juicefs.lite
dist/
5 changes: 5 additions & 0 deletions cmd/mount_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func mountFlags() []cli.Flag {
Name: "o",
Usage: "other FUSE options",
},
&cli.StringFlag{
Name: "access-log",
Usage: "Access log file",
},
&cli.BoolFlag{
Name: "as-root",
Usage: "Access files as administrator",
Expand Down Expand Up @@ -61,6 +65,7 @@ func getDaemonStage() int {
}

func mountMain(v *vfs.VFS, c *cli.Context) {
v.Conf.AccessLog = c.String("access-log")
winfsp.Serve(v, c.String("o"), c.Float64("file-cache-to"), c.Bool("as-root"), c.Int("delay-close"))
}

Expand Down
49 changes: 40 additions & 9 deletions pkg/winfsp/winfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,34 @@ func (j *juice) Statfs(path string, stat *fuse.Statfs_t) int {
}

func errorconv(err syscall.Errno) int {
// convert based on the error.i file in winfsp project
switch err {
case syscall.EACCES:
return -fuse.EACCES
case syscall.EEXIST:
return -fuse.EEXIST
case syscall.ENOENT, syscall.ENOTDIR:
return -fuse.ENOENT
case syscall.ECANCELED:
return -fuse.EINTR
case syscall.EIO:
return -fuse.EIO
case syscall.EINVAL:
return -fuse.ENXIO
case syscall.EBADFD:
return -fuse.EBADF
case syscall.EDQUOT:
return -fuse.ENOSPC
case syscall.EBUSY:
return -fuse.EBUSY
case syscall.ENOTEMPTY:
return -fuse.ENOTEMPTY
case syscall.ENAMETOOLONG:
return -fuse.ENAMETOOLONG
case syscall.ERROR_HANDLE_EOF:
return -fuse.ENODATA
}

return -int(err)
}

Expand Down Expand Up @@ -174,7 +202,7 @@ func (j *juice) Readlink(path string) (e int, target string) {
return
}
t, errno := j.vfs.Readlink(ctx, fi.Inode())
e = -int(errno)
e = errorconv(errno)
target = string(t)
return
}
Expand Down Expand Up @@ -253,7 +281,7 @@ func (j *juice) Create(p string, flags int, mode uint32) (e int, fh uint64) {
j.handlers[fh] = entry.Inode
j.Unlock()
}
e = -int(errno)
e = errorconv(errno)
return
}

Expand Down Expand Up @@ -300,7 +328,7 @@ func (j *juice) OpenEx(path string, fi *fuse.FileInfo_t) (e int) {
j.handlers[fh] = ino
j.Unlock()
}
e = -int(errno)
e = errorconv(errno)
return
}

Expand Down Expand Up @@ -407,6 +435,9 @@ func (j *juice) Getattr(p string, stat *fuse.Stat_t, fh uint64) (e int) {

fi, err := j.fs.Stat(ctx, p)
if err != 0 {
// Known issue: If the parent directory is not exists, the Windows api such as
// GetFileAttributeX expects the ERROR_PATH_NOT_FOUND returned.
// However, the fuse api has no such error code defined.
e = -fuse.ENOENT
return
}
Expand Down Expand Up @@ -450,7 +481,7 @@ func (j *juice) Read(path string, buf []byte, off int64, fh uint64) (e int) {
}
n, err := j.vfs.Read(ctx, ino, buf, uint64(off), fh)
if err != 0 {
e = -int(err)
e = errorconv(err)
return
}
return n
Expand All @@ -471,7 +502,7 @@ func (j *juice) Write(path string, buff []byte, off int64, fh uint64) (e int) {
}
errno := j.vfs.Write(ctx, ino, buff, uint64(off), fh)
if errno != 0 {
e = -int(errno)
e = errorconv(errno)
} else {
e = len(buff)
}
Expand All @@ -487,7 +518,7 @@ func (j *juice) Flush(path string, fh uint64) (e int) {
e = -fuse.EBADF
return
}
e = -int(j.vfs.Flush(ctx, ino, fh, 0))
e = errorconv(j.vfs.Flush(ctx, ino, fh, 0))
return
}

Expand Down Expand Up @@ -521,7 +552,7 @@ func (j *juice) Fsync(path string, datasync bool, fh uint64) (e int) {
if ino == 0 {
e = -fuse.EBADF
} else {
e = -int(j.vfs.Fsync(ctx, ino, 1, fh))
e = errorconv(j.vfs.Fsync(ctx, ino, 1, fh))
}
return
}
Expand All @@ -541,7 +572,7 @@ func (j *juice) Opendir(path string) (e int, fh uint64) {
j.handlers[fh] = f.Inode()
j.Unlock()
}
e = -int(errno)
e = errorconv(errno)
return
}

Expand All @@ -558,7 +589,7 @@ func (j *juice) Readdir(path string,
ctx := j.newContext()
entries, readAt, err := j.vfs.Readdir(ctx, ino, 100000, int(ofst), fh, true)
if err != 0 {
e = -int(err)
e = errorconv(err)
return
}
var st fuse.Stat_t
Expand Down

0 comments on commit 08d5d82

Please sign in to comment.