odirectReader: handle EOF correctly (#11998)

EOF may be sent along with data so queue it up and 
return it when the buffer is empty.

Also, when reading data without direct io don't add a buffer 
that only results in extra memcopy.
This commit is contained in:
Klaus Post 2021-04-07 17:32:59 +02:00 committed by GitHub
parent 0a1db6d41b
commit d2ac2f758e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 9 deletions

View File

@ -1100,11 +1100,13 @@ func (s *xlStorage) ReadVersion(ctx context.Context, volume, path, versionID str
} }
func (s *xlStorage) readAllData(volumeDir string, filePath string, requireDirectIO bool) (buf []byte, err error) { func (s *xlStorage) readAllData(volumeDir string, filePath string, requireDirectIO bool) (buf []byte, err error) {
var f *os.File var r io.ReadCloser
if requireDirectIO { if requireDirectIO {
var f *os.File
f, err = disk.OpenFileDirectIO(filePath, readMode, 0666) f, err = disk.OpenFileDirectIO(filePath, readMode, 0666)
r = &odirectReader{f, nil, nil, true, true, s, nil}
} else { } else {
f, err = OpenFile(filePath, readMode, 0) r, err = OpenFile(filePath, readMode, 0)
} }
if err != nil { if err != nil {
if osIsNotExist(err) { if osIsNotExist(err) {
@ -1138,10 +1140,8 @@ func (s *xlStorage) readAllData(volumeDir string, filePath string, requireDirect
return nil, err return nil, err
} }
or := &odirectReader{f, nil, nil, true, true, s, nil} defer r.Close()
defer or.Close() buf, err = ioutil.ReadAll(r)
buf, err = ioutil.ReadAll(or)
if err != nil { if err != nil {
err = osErrToFileErr(err) err = osErrToFileErr(err)
} }
@ -1316,7 +1316,7 @@ type odirectReader struct {
// Read - Implements Reader interface. // Read - Implements Reader interface.
func (o *odirectReader) Read(buf []byte) (n int, err error) { func (o *odirectReader) Read(buf []byte) (n int, err error) {
if o.err != nil { if o.err != nil && (len(o.buf) == 0 || o.freshRead) {
return 0, o.err return 0, o.err
} }
if o.buf == nil { if o.buf == nil {
@ -1343,20 +1343,22 @@ func (o *odirectReader) Read(buf []byte) (n int, err error) {
} }
} }
if n == 0 { if n == 0 {
// err is io.EOF // err is likely io.EOF
o.err = err o.err = err
return n, err return n, err
} }
o.err = err
o.buf = o.buf[:n] o.buf = o.buf[:n]
o.freshRead = false o.freshRead = false
} }
if len(buf) >= len(o.buf) { if len(buf) >= len(o.buf) {
n = copy(buf, o.buf) n = copy(buf, o.buf)
o.freshRead = true o.freshRead = true
return n, nil return n, o.err
} }
n = copy(buf, o.buf) n = copy(buf, o.buf)
o.buf = o.buf[n:] o.buf = o.buf[n:]
// There is more left in buffer, do not return any EOF yet.
return n, nil return n, nil
} }