mirror of
https://github.com/minio/minio.git
synced 2025-04-09 06:00:12 -04:00
allow large buffer to list more entries per directory (#9785)
This commit is contained in:
parent
790323ac37
commit
423aeb0d81
@ -21,13 +21,22 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The buffer must be at least a block long.
|
// The buffer must be at least a block long.
|
||||||
// refer https://github.com/golang/go/issues/24015
|
// refer https://github.com/golang/go/issues/24015
|
||||||
const blockSize = 8 << 10
|
const blockSize = 8 << 10 // 8192
|
||||||
|
|
||||||
|
// By default atleast 1000 entries in single getdents call
|
||||||
|
var direntPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
buf := make([]byte, blockSize*1000)
|
||||||
|
return &buf
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// unexpectedFileMode is a sentinel (and bogus) os.FileMode
|
// unexpectedFileMode is a sentinel (and bogus) os.FileMode
|
||||||
// value used to represent a syscall.DT_UNKNOWN Dirent.Type.
|
// value used to represent a syscall.DT_UNKNOWN Dirent.Type.
|
||||||
@ -90,9 +99,9 @@ func readDirFilterFn(dirPath string, filter func(name string, typ os.FileMode) e
|
|||||||
}
|
}
|
||||||
defer syscall.Close(fd)
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
buf := make([]byte, blockSize) // stack-allocated; doesn't escape
|
buf := make([]byte, blockSize)
|
||||||
boff := 0 // starting read position in buf
|
boff := 0 // starting read position in buf
|
||||||
nbuf := 0 // end valid data in buf
|
nbuf := 0 // end valid data in buf
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if boff >= nbuf {
|
if boff >= nbuf {
|
||||||
@ -105,7 +114,7 @@ func readDirFilterFn(dirPath string, filter func(name string, typ os.FileMode) e
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if nbuf <= 0 {
|
if nbuf <= 0 {
|
||||||
break
|
break // EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
consumed, name, typ, err := parseDirEnt(buf[boff:nbuf])
|
consumed, name, typ, err := parseDirEnt(buf[boff:nbuf])
|
||||||
@ -143,14 +152,16 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
|
|||||||
}
|
}
|
||||||
defer syscall.Close(fd)
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
buf := make([]byte, blockSize) // stack-allocated; doesn't escape
|
bufp := direntPool.Get().(*[]byte)
|
||||||
boff := 0 // starting read position in buf
|
defer direntPool.Put(bufp)
|
||||||
nbuf := 0 // end valid data in buf
|
|
||||||
|
boff := 0 // starting read position in buf
|
||||||
|
nbuf := 0 // end valid data in buf
|
||||||
|
|
||||||
for count != 0 {
|
for count != 0 {
|
||||||
if boff >= nbuf {
|
if boff >= nbuf {
|
||||||
boff = 0
|
boff = 0
|
||||||
nbuf, err = syscall.ReadDirent(fd, buf)
|
nbuf, err = syscall.ReadDirent(fd, *bufp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isSysErrNotDir(err) {
|
if isSysErrNotDir(err) {
|
||||||
return nil, errFileNotFound
|
return nil, errFileNotFound
|
||||||
@ -161,7 +172,7 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
consumed, name, typ, err := parseDirEnt(buf[boff:nbuf])
|
consumed, name, typ, err := parseDirEnt((*bufp)[boff:nbuf])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
@ -57,7 +57,6 @@ func readDirFilterFn(dirPath string, filter func(name string, typ os.FileMode) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
data := &syscall.Win32finddata{}
|
data := &syscall.Win32finddata{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
e := syscall.FindNextFile(syscall.Handle(d.Fd()), data)
|
e := syscall.FindNextFile(syscall.Handle(d.Fd()), data)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
@ -115,7 +114,7 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
|
|||||||
}
|
}
|
||||||
// Not a directory return error.
|
// Not a directory return error.
|
||||||
if !st.IsDir() {
|
if !st.IsDir() {
|
||||||
return nil, errFileAccessDenied
|
return nil, errFileNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &syscall.Win32finddata{}
|
data := &syscall.Win32finddata{}
|
||||||
@ -133,6 +132,7 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name := syscall.UTF16ToString(data.FileName[0:])
|
name := syscall.UTF16ToString(data.FileName[0:])
|
||||||
if name == "" || name == "." || name == ".." { // Useless names
|
if name == "" || name == "." || name == ".." { // Useless names
|
||||||
continue
|
continue
|
Loading…
x
Reference in New Issue
Block a user