vfs: --vfs-used-is-size uses `rclone size` to give used space (full recursive listing)

The same algorithm as `rclone size` is used, but without filtering.
It is advised to only use this with caching.
vfs-used-is-size
Yves G 2020-03-07 22:38:10 +01:00
parent 8bf6ab2c52
commit 843c1c293f
4 changed files with 35 additions and 2 deletions

View File

@ -260,6 +260,19 @@ This is the same as setting the attr_timeout option in mount.fuse.
Note that all the rclone filters can be used to select a subset of the
files to be visible in the mount.
### Alternate report of used bytes
Some backends, most notably S3, do not report the amount of bytes used.
If you need this information to be available when running ` + "`df`" + ` on the filesystem,
then pass the parameter --vfs-used-is-size=true to rclone.
With this parameter set, instead of relying on the backend to report this information,
rclone will scan the whole remote like ` + "`rclone size `" + ` does, and compute the total used space itself.
Notes:
* Contrary to ` + "`rclone size `" + `, this flag ignores filters so that the result is accurate.
* It is advised to only use this with caching.
### systemd
When running rclone ` + commandName + ` as a systemd service, it is possible

View File

@ -35,6 +35,7 @@ import (
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/log"
"github.com/rclone/rclone/fs/walk"
"github.com/rclone/rclone/vfs/vfscache"
"github.com/rclone/rclone/vfs/vfscommon"
)
@ -478,9 +479,25 @@ func (vfs *VFS) Statfs() (total, used, free int64) {
defer vfs.usageMu.Unlock()
total, used, free = -1, -1, -1
doAbout := vfs.f.Features().About
if doAbout != nil && (vfs.usageTime.IsZero() || time.Since(vfs.usageTime) >= vfs.Opt.DirCacheTime) {
if (doAbout != nil || vfs.Opt.UsedIsSize) && (vfs.usageTime.IsZero() || time.Since(vfs.usageTime) >= vfs.Opt.DirCacheTime) {
var err error
vfs.usage, err = doAbout(context.TODO())
ctx := context.TODO()
if doAbout == nil {
vfs.usage = &fs.Usage{}
} else {
vfs.usage, err = doAbout(ctx)
}
if vfs.Opt.UsedIsSize {
var usedBySizeAlgorithm int64 = 0
// Algorithm from `rclone size`
err = walk.ListR(ctx, vfs.f, "", true, -1, walk.ListObjects, func(entries fs.DirEntries) error {
entries.ForObject(func(o fs.Object) {
usedBySizeAlgorithm += o.Size()
})
return nil
})
vfs.usage.Used = &usedBySizeAlgorithm
}
vfs.usageTime = time.Now()
if err != nil {
fs.Errorf(vfs.f, "Statfs failed: %v", err)

View File

@ -30,6 +30,7 @@ type Options struct {
CaseInsensitive bool
WriteWait time.Duration // time to wait for in-sequence write
ReadWait time.Duration // time to wait for in-sequence read
UsedIsSize bool // if true, use the `rclone size` algorithm for Used size
}
// DefaultOpt is the default values uses for Opt
@ -54,4 +55,5 @@ var DefaultOpt = Options{
CaseInsensitive: runtime.GOOS == "windows" || runtime.GOOS == "darwin", // default to true on Windows and Mac, false otherwise
WriteWait: 1000 * time.Millisecond,
ReadWait: 5 * time.Millisecond,
UsedIsSize: false,
}

View File

@ -35,5 +35,6 @@ func AddFlags(flagSet *pflag.FlagSet) {
flags.BoolVarP(flagSet, &Opt.CaseInsensitive, "vfs-case-insensitive", "", Opt.CaseInsensitive, "If a file name not found, find a case insensitive match.")
flags.DurationVarP(flagSet, &Opt.WriteWait, "vfs-write-wait", "", Opt.WriteWait, "Time to wait for in-sequence write before giving error.")
flags.DurationVarP(flagSet, &Opt.ReadWait, "vfs-read-wait", "", Opt.ReadWait, "Time to wait for in-sequence read before seeking.")
flags.BoolVarP(flagSet, &Opt.UsedIsSize, "vfs-used-is-size", "", Opt.UsedIsSize, "Use the `rclone size` algorithm for Used size.")
platformFlags(flagSet)
}