mirror of https://github.com/minio/minio.git
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:
parent
0a1db6d41b
commit
d2ac2f758e
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue