From 2d7afe8690ece6285051143ddb9092fedca692d8 Mon Sep 17 00:00:00 2001 From: David Sze Date: Sun, 31 Jan 2021 15:25:24 -0500 Subject: [PATCH] local: Add flag --no-preallocate - #3207 Some virtual filesystems (such as Google Drive File Stream) may incorrectly set the actual file size equal to the preallocated space, causing checksum and file size checks to fail. This flag can be used to disable preallocation for local backends of this type. --- backend/local/local.go | 30 +++++++++++++++++++++++------- docs/content/local.md | 15 +++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/backend/local/local.go b/backend/local/local.go index 3daeb4f0a..95ba16ed1 100644 --- a/backend/local/local.go +++ b/backend/local/local.go @@ -148,6 +148,17 @@ Windows/macOS and case sensitive for everything else. Use this flag to override the default choice.`, Default: false, Advanced: true, + }, { + Name: "no_preallocate", + Help: `Disable preallocation of disk space for transferred files + +Preallocation of disk space helps prevent filesystem fragmentation. +However, some virtual filesystem layers (such as Google Drive File +Stream) may incorrectly set the actual file size equal to the +preallocated space, causing checksum and file size checks to fail. +Use this flag to disable preallocation.`, + Default: false, + Advanced: true, }, { Name: "no_sparse", Help: `Disable sparse files for multi-thread downloads @@ -191,6 +202,7 @@ type Options struct { OneFileSystem bool `config:"one_file_system"` CaseSensitive bool `config:"case_sensitive"` CaseInsensitive bool `config:"case_insensitive"` + NoPreAllocate bool `config:"no_preallocate"` NoSparse bool `config:"no_sparse"` NoSetModTime bool `config:"no_set_modtime"` Enc encoder.MultiEncoder `config:"encoding"` @@ -1127,10 +1139,12 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return err } } - // Pre-allocate the file for performance reasons - err = file.PreAllocate(src.Size(), f) - if err != nil { - fs.Debugf(o, "Failed to pre-allocate: %v", err) + if !o.fs.opt.NoPreAllocate { + // Pre-allocate the file for performance reasons + err = file.PreAllocate(src.Size(), f) + if err != nil { + fs.Debugf(o, "Failed to pre-allocate: %v", err) + } } out = f } else { @@ -1217,9 +1231,11 @@ func (f *Fs) OpenWriterAt(ctx context.Context, remote string, size int64) (fs.Wr return nil, err } // Pre-allocate the file for performance reasons - err = file.PreAllocate(size, out) - if err != nil { - fs.Debugf(o, "Failed to pre-allocate: %v", err) + if !f.opt.NoPreAllocate { + err = file.PreAllocate(size, out) + if err != nil { + fs.Debugf(o, "Failed to pre-allocate: %v", err) + } } if !f.opt.NoSparse && file.SetSparseImplemented { sparseWarning.Do(func() { diff --git a/docs/content/local.md b/docs/content/local.md index e91c46d7f..47b6a66f2 100644 --- a/docs/content/local.md +++ b/docs/content/local.md @@ -447,6 +447,21 @@ to override the default choice. - Type: bool - Default: false +#### --local-no-preallocate + +Disable preallocation of disk space for transferred files + +Preallocation of disk space helps prevent filesystem fragmentation. +However, some virtual filesystem layers (such as Google Drive File +Stream) may incorrectly set the actual file size equal to the +preallocated space, causing checksum and file size checks to fail. +Use this flag to disable preallocation. + +- Config: no_preallocate +- Env Var: RCLONE_LOCAL_NO_PREALLOCATE +- Type: bool +- Default: false + #### --local-no-sparse Disable sparse files for multi-thread downloads