allow large buffer to list more entries per directory (#9785)

master
Harshavardhana 4 years ago committed by GitHub
parent 790323ac37
commit 423aeb0d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 0
      cmd/os-dirent_fileino.go
  2. 0
      cmd/os-dirent_ino.go
  3. 0
      cmd/os-dirent_namelen_bsd.go
  4. 0
      cmd/os-dirent_namelen_linux.go
  5. 0
      cmd/os-readdir_other.go
  6. 0
      cmd/os-readdir_test.go
  7. 31
      cmd/os-readdir_unix.go
  8. 4
      cmd/os-readdir_windows.go

@ -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…
Cancel
Save