forked from TrueCloudLab/restic
sftp: check for truncated files without an extra backend request
This commit is contained in:
parent
c6d74458ee
commit
eaa3f81d6b
1 changed files with 18 additions and 13 deletions
|
@ -425,7 +425,24 @@ func (r *SFTP) checkNoSpace(dir string, size int64, origErr error) error {
|
|||
// Load runs fn with a reader that yields the contents of the file at h at the
|
||||
// given offset.
|
||||
func (r *SFTP) Load(ctx context.Context, h backend.Handle, length int, offset int64, fn func(rd io.Reader) error) error {
|
||||
return util.DefaultLoad(ctx, h, length, offset, r.openReader, fn)
|
||||
return util.DefaultLoad(ctx, h, length, offset, r.openReader, func(rd io.Reader) error {
|
||||
if length == 0 {
|
||||
return fn(rd)
|
||||
}
|
||||
|
||||
// there is no direct way to efficiently check whether the file is too short
|
||||
// rd is already a LimitedReader which can be used to track the number of bytes read
|
||||
err := fn(rd)
|
||||
|
||||
// check the underlying reader to be agnostic to however fn() handles the returned error
|
||||
_, rderr := rd.Read([]byte{0})
|
||||
if rderr == io.EOF && rd.(*backend.LimitedReadCloser).N != 0 {
|
||||
// file is too short
|
||||
return fmt.Errorf("%w: %v", errTooShort, err)
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (r *SFTP) openReader(_ context.Context, h backend.Handle, length int, offset int64) (io.ReadCloser, error) {
|
||||
|
@ -434,18 +451,6 @@ func (r *SFTP) openReader(_ context.Context, h backend.Handle, length int, offse
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
_ = f.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
size := fi.Size()
|
||||
if size < offset+int64(length) {
|
||||
_ = f.Close()
|
||||
return nil, errTooShort
|
||||
}
|
||||
|
||||
if offset > 0 {
|
||||
_, err = f.Seek(offset, 0)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue