mirror of
https://github.com/minio/minio.git
synced 2025-11-20 01:50:24 -05:00
Posix CreateFile should work for compressed lengths (#7584)
This commit is contained in:
committed by
kannappanr
parent
a436f2baa5
commit
c113d4e49c
93
cmd/posix.go
93
cmd/posix.go
@@ -187,7 +187,7 @@ func newPosix(path string) (*posix, error) {
|
||||
p := &posix{
|
||||
connected: true,
|
||||
diskPath: path,
|
||||
// 1MiB buffer pool for posix internal operations.
|
||||
// 4MiB buffer pool for posix internal operations.
|
||||
pool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
b := directio.AlignedBlock(posixWriteBlockSize)
|
||||
@@ -1028,10 +1028,9 @@ func (s *posix) ReadFileStream(volume, path string, offset, length int64) (io.Re
|
||||
|
||||
// CreateFile - creates the file.
|
||||
func (s *posix) CreateFile(volume, path string, fileSize int64, r io.Reader) (err error) {
|
||||
if fileSize < 0 {
|
||||
if fileSize < -1 {
|
||||
return errInvalidArgument
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err == errFaultyDisk {
|
||||
atomic.AddInt32(&s.ioErrCount, 1)
|
||||
@@ -1120,69 +1119,69 @@ func (s *posix) CreateFile(volume, path string, fileSize int64, r io.Reader) (er
|
||||
defer s.pool.Put(bufp)
|
||||
|
||||
buf := *bufp
|
||||
var written int64
|
||||
dioCount := int(fileSize) / len(buf)
|
||||
for i := 0; i < dioCount; i++ {
|
||||
|
||||
// Writes remaining bytes in the buffer.
|
||||
writeRemaining := func(w *os.File, buf []byte) (remainingWritten int, err error) {
|
||||
var n int
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err = w.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
written += int64(n)
|
||||
}
|
||||
// The following logic writes the remainging data such that it writes whatever best is possible (aligned buffer)
|
||||
// in O_DIRECT mode and remaining (unaligned buffer) in non-O_DIRECT mode.
|
||||
remaining := fileSize % int64(len(buf))
|
||||
if remaining != 0 {
|
||||
buf = buf[:remaining]
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remaining := len(buf)
|
||||
// The following logic writes the remainging data such that it writes whatever best is possible (aligned buffer)
|
||||
// in O_DIRECT mode and remaining (unaligned buffer) in non-O_DIRECT mode.
|
||||
remainingAligned := (remaining / directioAlignSize) * directioAlignSize
|
||||
remainingAlignedBuf := buf[:remainingAligned]
|
||||
remainingUnalignedBuf := buf[remainingAligned:]
|
||||
if len(remainingAlignedBuf) > 0 {
|
||||
var n int
|
||||
n, err = w.Write(remainingAlignedBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
written += int64(n)
|
||||
remainingWritten += n
|
||||
}
|
||||
if len(remainingUnalignedBuf) > 0 {
|
||||
var n int
|
||||
// Write on O_DIRECT fds fail if buffer is not 4K aligned, hence disable O_DIRECT.
|
||||
if err = disk.DisableDirectIO(w); err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
n, err = w.Write(remainingUnalignedBuf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
remainingWritten += n
|
||||
}
|
||||
return remainingWritten, nil
|
||||
}
|
||||
|
||||
var written int
|
||||
for {
|
||||
var n int
|
||||
n, err = io.ReadFull(r, buf)
|
||||
switch err {
|
||||
case nil:
|
||||
n, err = w.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
written += int64(n)
|
||||
written += n
|
||||
case io.ErrUnexpectedEOF:
|
||||
n, err = writeRemaining(w, buf[:n])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
written += n
|
||||
fallthrough
|
||||
case io.EOF:
|
||||
if fileSize != -1 {
|
||||
if written < int(fileSize) {
|
||||
return errLessData
|
||||
}
|
||||
if written > int(fileSize) {
|
||||
return errMoreData
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Do some sanity checks.
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != io.EOF {
|
||||
return errMoreData
|
||||
}
|
||||
|
||||
if written < fileSize {
|
||||
return errLessData
|
||||
}
|
||||
|
||||
if written > fileSize {
|
||||
return errMoreData
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *posix) WriteAll(volume, path string, buf []byte) (err error) {
|
||||
|
||||
Reference in New Issue
Block a user