mirror of
https://github.com/minio/minio.git
synced 2025-03-28 16:31:00 -04:00
fix: always check error upon w.Close() in Write() (#18111)
not checking w.Close() can prematurely make us think that the w.Write() actually succeeded, apparently Write() may or may not return an error but sometimes only during a Close() call to the fd we may see the error from Write() propagate. Fdatasync(w) on the FD would return an error requiring Close() error handling is less of a concern, however it may happen such that fdatasync() did not return an error, where as Close() would.
This commit is contained in:
parent
22ee678136
commit
cdeab19673
@ -1945,7 +1945,6 @@ func (s *xlStorage) writeAllDirect(ctx context.Context, filePath string, fileSiz
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return osErrToFileErr(err)
|
return osErrToFileErr(err)
|
||||||
}
|
}
|
||||||
defer w.Close()
|
|
||||||
|
|
||||||
var bufp *[]byte
|
var bufp *[]byte
|
||||||
switch {
|
switch {
|
||||||
@ -1968,17 +1967,33 @@ func (s *xlStorage) writeAllDirect(ctx context.Context, filePath string, fileSiz
|
|||||||
written, err = io.CopyBuffer(diskHealthWriter(ctx, w), r, *bufp)
|
written, err = io.CopyBuffer(diskHealthWriter(ctx, w), r, *bufp)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
w.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if written < fileSize && fileSize >= 0 {
|
if written < fileSize && fileSize >= 0 {
|
||||||
|
w.Close()
|
||||||
return errLessData
|
return errLessData
|
||||||
} else if written > fileSize && fileSize >= 0 {
|
} else if written > fileSize && fileSize >= 0 {
|
||||||
|
w.Close()
|
||||||
return errMoreData
|
return errMoreData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only interested in flushing the size_t not mtime/atime
|
// Only interested in flushing the size_t not mtime/atime
|
||||||
return Fdatasync(w)
|
if err = Fdatasync(w); err != nil {
|
||||||
|
w.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dealing with error returns from close() - 'man 2 close'
|
||||||
|
//
|
||||||
|
// A careful programmer will check the return value of close(), since it is quite possible that
|
||||||
|
// errors on a previous write(2) operation are reported only on the final close() that releases
|
||||||
|
// the open file descriptor.
|
||||||
|
//
|
||||||
|
// Failing to check the return value when closing a file may lead to silent loss of data.
|
||||||
|
// This can especially be observed with NFS and with disk quota.
|
||||||
|
return w.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *xlStorage) writeAll(ctx context.Context, volume string, path string, b []byte, sync bool) (err error) {
|
func (s *xlStorage) writeAll(ctx context.Context, volume string, path string, b []byte, sync bool) (err error) {
|
||||||
@ -2016,18 +2031,27 @@ func (s *xlStorage) writeAll(ctx context.Context, volume string, path string, b
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer w.Close()
|
|
||||||
|
|
||||||
n, err := w.Write(b)
|
n, err := w.Write(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
w.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if n != len(b) {
|
if n != len(b) {
|
||||||
|
w.Close()
|
||||||
return io.ErrShortWrite
|
return io.ErrShortWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Dealing with error returns from close() - 'man 2 close'
|
||||||
|
//
|
||||||
|
// A careful programmer will check the return value of close(), since it is quite possible that
|
||||||
|
// errors on a previous write(2) operation are reported only on the final close() that releases
|
||||||
|
// the open file descriptor.
|
||||||
|
//
|
||||||
|
// Failing to check the return value when closing a file may lead to silent loss of data.
|
||||||
|
// This can especially be observed with NFS and with disk quota.
|
||||||
|
return w.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *xlStorage) WriteAll(ctx context.Context, volume string, path string, b []byte) (err error) {
|
func (s *xlStorage) WriteAll(ctx context.Context, volume string, path string, b []byte) (err error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user