Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Nick Craig-Wood
0731de6a51 smb: fix "unverified packet returned" error when using multithread copy
Before this change, in the WriterAt method we removed the session
while the WriterAt handle was still open.

This meant that in long lived multithread copies the session was
closed which caused the "unverified packet returned" errors.

This fixes the problem by wrapping it in a custom Close to close
remove the session only when the WriterAt handle is closed.

See: https://forum.rclone.org/t/problems-copying-big-files-from-local-to-remote-using-rclone-rc/42169/
2023-10-09 12:10:55 +01:00

View file

@ -12,6 +12,7 @@ import (
"sync/atomic"
"time"
smb2 "github.com/hirochachacha/go-smb2"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
"github.com/rclone/rclone/fs/config/configmap"
@ -476,6 +477,26 @@ func (f *Fs) About(ctx context.Context) (_ *fs.Usage, err error) {
return usage, nil
}
// Wrap a smb2.File with a custom Close method
type closeSession struct {
*smb2.File
close func() error
closed bool
}
// Close the handle and call the custom code
func (c *closeSession) Close() error {
err := c.File.Close()
if !c.closed {
err2 := c.close()
if err == nil {
err = err2
}
c.closed = true
}
return err
}
// OpenWriterAt opens with a handle for random access writes
//
// Pass in the remote desired and the size if known.
@ -509,10 +530,19 @@ func (f *Fs) OpenWriterAt(ctx context.Context, remote string, size int64) (fs.Wr
fl, err := cn.smbShare.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
o.fs.putConnection(&cn)
return nil, fmt.Errorf("failed to open: %w", err)
}
return fl, nil
// Connection is returned in the closeSession.Close method
c := &closeSession{
File: fl,
close: func() error {
o.fs.putConnection(&cn)
return nil
},
}
return c, nil
}
// Shutdown the backend, closing any background tasks and any