From 32592331fef49962a1e476ad9666b1a9a7b5a6c3 Mon Sep 17 00:00:00 2001 From: Anagh Kumar Baranwal <6824881+darthShadow@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:59:20 +0530 Subject: [PATCH] Set appropriate file & directory metadata from VFS mount Signed-off-by: Anagh Kumar Baranwal <6824881+darthShadow@users.noreply.github.com> --- vfs/dir.go | 24 +++++++++++++++++++----- vfs/file.go | 10 ++++++++++ vfs/vfscommon/options.go | 6 ++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/vfs/dir.go b/vfs/dir.go index 26b706b62..4fd3a0b58 100644 --- a/vfs/dir.go +++ b/vfs/dir.go @@ -999,12 +999,26 @@ func (d *Dir) Mkdir(name string) (*Dir, error) { return nil, err } // fs.Debugf(path, "Dir.Mkdir") - err = d.f.Mkdir(context.TODO(), path) - if err != nil { - fs.Errorf(d, "Dir.Mkdir failed to create directory: %v", err) - return nil, err + var fsDir *fs.Dir + if do := d.Fs().Features().MkdirMetadata; do != nil && !d.vfs.Opt.SkipMetadata { + fsDirectory, err := do(context.TODO(), path, fs.Metadata{ + "uid": fmt.Sprintf("%d", d.vfs.Opt.UID), + "gid": fmt.Sprintf("%d", d.vfs.Opt.GID), + "mode": fmt.Sprintf("%#o", d.vfs.Opt.DirPerms), + }) + if err != nil { + fs.Errorf(d, "Dir.Mkdir failed to create directory with metadata: %v", err) + return nil, err + } + fsDir = fs.NewDirCopy(context.TODO(), fsDirectory) + } else { + err = d.Fs().Mkdir(context.TODO(), path) + if err != nil { + fs.Errorf(d, "Dir.Mkdir failed to create directory: %v", err) + return nil, err + } + fsDir = fs.NewDir(path, time.Now()) } - fsDir := fs.NewDir(path, time.Now()) dir := newDir(d.vfs, d.f, d, fsDir) d.addObject(dir) if err = d.SetModTime(time.Now()); err != nil { diff --git a/vfs/file.go b/vfs/file.go index 1c599ef01..900ca9b52 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -480,6 +480,16 @@ func (f *File) setSize(n int64) { func (f *File) setObject(o fs.Object) { f.mu.Lock() f.o = o + if do, ok := f.o.(fs.SetMetadataer); ok && !f.d.vfs.Opt.SkipMetadata { + err := do.SetMetadata(context.TODO(), fs.Metadata{ + "uid": fmt.Sprintf("%d", f.d.vfs.Opt.UID), + "gid": fmt.Sprintf("%d", f.d.vfs.Opt.GID), + "mode": fmt.Sprintf("%#o", f.d.vfs.Opt.FilePerms), + }) + if err != nil { + fs.Debugf(f._path(), "Failed to set file metadata: %v", err) + } + } _ = f._applyPendingModTime() d := f.d f.mu.Unlock() diff --git a/vfs/vfscommon/options.go b/vfs/vfscommon/options.go index 591ce5044..ae682c864 100644 --- a/vfs/vfscommon/options.go +++ b/vfs/vfscommon/options.go @@ -139,6 +139,11 @@ var OptionsInfo = fs.Options{{ Default: fs.SizeSuffix(-1), Help: "Specify the total space of disk", Groups: "VFS", +}, { + Name: "vfs_skip_metadata", + Default: true, + Help: "Skip setting the metadata on the underlying files & directories", + Groups: "VFS", }, { Name: "umask", Default: FileMode(getUmask()), @@ -191,6 +196,7 @@ type Options struct { UsedIsSize bool `config:"vfs_used_is_size"` // if true, use the `rclone size` algorithm for Used size FastFingerprint bool `config:"vfs_fast_fingerprint"` // if set use fast fingerprints DiskSpaceTotalSize fs.SizeSuffix `config:"vfs_disk_space_total_size"` + SkipMetadata bool `config:"vfs_skip_metadata"` // VFS will skip setting the metadata on the underlying files & directories } // Opt is the default options modified by the environment variables and command line flags