Repository: rclone/rclone
File: vfs/vfscache/item.go (Go)

Code before:
			item.c.put(item.name, oldItem) // LOCKING in Cache method
			err = fmt.Errorf("internal error: item %q already open in the cache", item.name)
		}
		oldItem.mu.Unlock()
	}

	// Relock the Item.mu for the return
	item.mu.Lock()

	// Create the downloaders
	if item.o != nil {
		item.downloaders = downloaders.New(item, item.c.opt, item.name, item.o)
	}

	return err
}

// Store stores the local cache file to the remote object, returning
// the new remote object. objOld is the old object if known.
//
// Call with lock held
func (item *Item) _store(ctx context.Context, storeFn StoreFn) (err error) {
	// defer log.Trace(item.name, "item=%p", item)("err=%v", &err)

	// Transfer the temp file to the remote
	cacheObj, err := item.c.fcache.NewObject(ctx, item.c.fcache.(*local.Fs).LocalToStandardPath(toOSPath(item.name)))
	if err != nil && err != fs.ErrorObjectNotFound {
		return fmt.Errorf("vfs cache: failed to find cache file: %w", err)
	}

	// Object has disappeared if cacheObj == nil
	if cacheObj != nil {
		o, name := item.o, item.name
		item.mu.Unlock()
		o, err := operations.Copy(ctx, item.c.fremote, o, name, cacheObj)
		item.mu.Lock()
		if err != nil {
			if errors.Is(err, fs.ErrorCantUploadEmptyFiles) {
				fs.Errorf(name, "Writeback failed: %v", err)
				return nil
			}
			return fmt.Errorf("vfs cache: failed to transfer file from cache to remote: %w", err)
		}
		item.o = o
		item._updateFingerprint()
	}

	// Write the object back to the VFS layer before we mark it as
	// clean, otherwise it will become eligible for removal which
	// can cause a deadlock
	if storeFn != nil && item.o != nil {

Review comment (performance):
This is a fix for #7760  isn't it - it should say `Fixes #7760` in the commit messsage. Can you also write what the problem was and how it fixed it in the commit message too - thanks!

I think a better fix would be to create the local backend with the encoding that we want, something like this (untested)

```patch
diff --git a/vfs/vfscache/cache.go b/vfs/vfscache/cache.go
index 9bcfc90ee..0dc3b7630 100644
--- a/vfs/vfscache/cache.go
+++ b/vfs/vfscache/cache.go
@@ -212,7 +212,7 @@ func (c *Cache) createItemDir(name string) (string, error) {
 
 // getBackend gets a backend for a cache root dir
 func getBackend(ctx context.Context, parentPath string, name string, relativeDirPath string) (fs.Fs, error) {
-	path := fmt.Sprintf("%s/%s/%s", parentPath, name, relativeDirPath)
+	path := fmt.Sprintf(":local,encoding=%v:%s/%s/%s", encoder.OS, parentPath, name, relativeDirPath)
 	return fscache.Get(ctx, path)
 }
```

Code after:
			err = fmt.Errorf("internal error: item %q already open in the cache", item.name)
		}
		oldItem.mu.Unlock()
	}

	// Relock the Item.mu for the return
	item.mu.Lock()

	// Create the downloaders
	if item.o != nil {
		item.downloaders = downloaders.New(item, item.c.opt, item.name, item.o)
	}

	return err
}

// Store stores the local cache file to the remote object, returning
// the new remote object. objOld is the old object if known.
//
// Call with lock held
func (item *Item) _store(ctx context.Context, storeFn StoreFn) (err error) {
	// defer log.Trace(item.name, "item=%p", item)("err=%v", &err)

	// Transfer the temp file to the remote
	cacheObj, err := item.c.fcache.NewObject(ctx, item.name)
	if err != nil && err != fs.ErrorObjectNotFound {
		return fmt.Errorf("vfs cache: failed to find cache file: %w", err)
	}

	// Object has disappeared if cacheObj == nil
	if cacheObj != nil {
		o, name := item.o, item.name
		item.mu.Unlock()
		o, err := operations.Copy(ctx, item.c.fremote, o, name, cacheObj)
		item.mu.Lock()
		if err != nil {
			if errors.Is(err, fs.ErrorCantUploadEmptyFiles) {
				fs.Errorf(name, "Writeback failed: %v", err)
				return nil
			}
			return fmt.Errorf("vfs cache: failed to transfer file from cache to remote: %w", err)
		}
		item.o = o
		item._updateFingerprint()
	}

	// Write the object back to the VFS layer before we mark it as
	// clean, otherwise it will become eligible for removal which
	// can cause a deadlock
	if storeFn != nil && item.o != nil {
		fs.Debugf(item.name, "vfs cache: writeback object to VFS layer")