mount,cmount: clip the number of blocks to 2^32-1 on macOS
OSX FUSE only supports 32 bit number of blocks which means that block counts have been wrapping. This causes f_bavail to be 0 which in turn causes problems with programs like borg backup. Fixes #2356
This commit is contained in:
parent
4eefd05dcf
commit
174ca22936
3 changed files with 28 additions and 5 deletions
|
@ -8,11 +8,11 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/billziss-gh/cgofuse/fuse"
|
||||
"github.com/ncw/rclone/cmd/mountlib"
|
||||
"github.com/ncw/rclone/fs"
|
||||
"github.com/ncw/rclone/fs/log"
|
||||
"github.com/ncw/rclone/vfs"
|
||||
|
@ -263,10 +263,7 @@ func (fsys *FS) Releasedir(path string, fh uint64) (errc int) {
|
|||
func (fsys *FS) Statfs(path string, stat *fuse.Statfs_t) (errc int) {
|
||||
defer log.Trace(path, "")("stat=%+v, errc=%d", stat, &errc)
|
||||
const blockSize = 4096
|
||||
fsBlocks := uint64(1 << 50)
|
||||
if runtime.GOOS == "windows" {
|
||||
fsBlocks = (1 << 43) - 1
|
||||
}
|
||||
const fsBlocks = (1 << 50) / blockSize
|
||||
stat.Blocks = fsBlocks // Total data blocks in file system.
|
||||
stat.Bfree = fsBlocks // Free blocks in file system.
|
||||
stat.Bavail = fsBlocks // Free blocks in file system if you're not root.
|
||||
|
@ -285,6 +282,9 @@ func (fsys *FS) Statfs(path string, stat *fuse.Statfs_t) (errc int) {
|
|||
if free >= 0 {
|
||||
stat.Bavail = uint64(free) / blockSize
|
||||
}
|
||||
mountlib.ClipBlocks(&stat.Blocks)
|
||||
mountlib.ClipBlocks(&stat.Bfree)
|
||||
mountlib.ClipBlocks(&stat.Bavail)
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"bazil.org/fuse"
|
||||
fusefs "bazil.org/fuse/fs"
|
||||
"github.com/ncw/rclone/cmd/mountlib"
|
||||
"github.com/ncw/rclone/fs"
|
||||
"github.com/ncw/rclone/fs/log"
|
||||
"github.com/ncw/rclone/vfs"
|
||||
|
@ -72,6 +73,9 @@ func (f *FS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.Sta
|
|||
if free >= 0 {
|
||||
resp.Bavail = uint64(free) / blockSize
|
||||
}
|
||||
mountlib.ClipBlocks(&resp.Blocks)
|
||||
mountlib.ClipBlocks(&resp.Bfree)
|
||||
mountlib.ClipBlocks(&resp.Bavail)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -293,3 +293,22 @@ be copied to the vfs cache before opening with --vfs-cache-mode full.
|
|||
|
||||
return commandDefintion
|
||||
}
|
||||
|
||||
// ClipBlocks clips the blocks pointed to to the OS max
|
||||
func ClipBlocks(b *uint64) {
|
||||
var max uint64
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
max = (1 << 43) - 1
|
||||
case "darwin":
|
||||
// OSX FUSE only supports 32 bit number of blocks
|
||||
// https://github.com/osxfuse/osxfuse/issues/396
|
||||
max = (1 << 32) - 1
|
||||
default:
|
||||
// no clipping
|
||||
return
|
||||
}
|
||||
if *b > max {
|
||||
*b = max
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue