mirror of
https://github.com/minio/minio.git
synced 2025-01-25 21:53:16 -05:00
optimize readdir() open calls to be dealt with directly via 'fd' (#18762)
This commit is contained in:
parent
e31081d79d
commit
39f9350697
@ -39,6 +39,8 @@ const (
|
|||||||
osMetricRename
|
osMetricRename
|
||||||
osMetricOpenFileW
|
osMetricOpenFileW
|
||||||
osMetricOpenFileR
|
osMetricOpenFileR
|
||||||
|
osMetricOpenFileWFd
|
||||||
|
osMetricOpenFileRFd
|
||||||
osMetricOpen
|
osMetricOpen
|
||||||
osMetricOpenFileDirectIO
|
osMetricOpenFileDirectIO
|
||||||
osMetricLstat
|
osMetricLstat
|
||||||
|
@ -39,6 +39,22 @@ func access(name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// openFileWithFD return 'fd' based file descriptor
|
||||||
|
func openFileWithFD(name string, flag int, perm os.FileMode) (fd int, err error) {
|
||||||
|
switch flag & writeMode {
|
||||||
|
case writeMode:
|
||||||
|
defer updateOSMetrics(osMetricOpenFileWFd, name)(err)
|
||||||
|
default:
|
||||||
|
defer updateOSMetrics(osMetricOpenFileRFd, name)(err)
|
||||||
|
}
|
||||||
|
var e error
|
||||||
|
fd, e = syscall.Open(name, flag|syscall.O_CLOEXEC, uint32(perm))
|
||||||
|
if e != nil {
|
||||||
|
return -1, &os.PathError{Op: "open", Path: name, Err: e}
|
||||||
|
}
|
||||||
|
return fd, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Forked from Golang but chooses to avoid performing lookup
|
// Forked from Golang but chooses to avoid performing lookup
|
||||||
//
|
//
|
||||||
// osMkdirAll creates a directory named path,
|
// osMkdirAll creates a directory named path,
|
||||||
@ -149,7 +165,7 @@ func parseDirEnt(buf []byte) (consumed int, name []byte, typ os.FileMode, err er
|
|||||||
// the directory itself, if the dirPath doesn't exist this function doesn't return
|
// the directory itself, if the dirPath doesn't exist this function doesn't return
|
||||||
// an error.
|
// an error.
|
||||||
func readDirFn(dirPath string, fn func(name string, typ os.FileMode) error) error {
|
func readDirFn(dirPath string, fn func(name string, typ os.FileMode) error) error {
|
||||||
f, err := OpenFile(dirPath, readMode, 0o666)
|
fd, err := openFileWithFD(dirPath, readMode, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if osErrToFileErr(err) == errFileNotFound {
|
if osErrToFileErr(err) == errFileNotFound {
|
||||||
return nil
|
return nil
|
||||||
@ -160,15 +176,16 @@ func readDirFn(dirPath string, fn func(name string, typ os.FileMode) error) erro
|
|||||||
// There may be permission error when dirPath
|
// There may be permission error when dirPath
|
||||||
// is at the root of the disk mount that may
|
// is at the root of the disk mount that may
|
||||||
// not have the permissions to avoid 'noatime'
|
// not have the permissions to avoid 'noatime'
|
||||||
f, err = Open(dirPath)
|
fd, err = openFileWithFD(dirPath, os.O_RDONLY, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if osErrToFileErr(err) == errFileNotFound {
|
if osErrToFileErr(err) == errFileNotFound {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return osErrToFileErr(err)
|
return osErrToFileErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
bufp := direntPool.Get().(*[]byte)
|
bufp := direntPool.Get().(*[]byte)
|
||||||
defer direntPool.Put(bufp)
|
defer direntPool.Put(bufp)
|
||||||
@ -181,7 +198,7 @@ func readDirFn(dirPath string, fn func(name string, typ os.FileMode) error) erro
|
|||||||
if boff >= nbuf {
|
if boff >= nbuf {
|
||||||
boff = 0
|
boff = 0
|
||||||
stop := globalOSMetrics.time(osMetricReadDirent)
|
stop := globalOSMetrics.time(osMetricReadDirent)
|
||||||
nbuf, err = syscall.ReadDirent(int(f.Fd()), buf)
|
nbuf, err = syscall.ReadDirent(fd, buf)
|
||||||
stop()
|
stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isSysErrNotDir(err) {
|
if isSysErrNotDir(err) {
|
||||||
@ -241,7 +258,7 @@ func readDirFn(dirPath string, fn func(name string, typ os.FileMode) error) erro
|
|||||||
// Return count entries at the directory dirPath and all entries
|
// Return count entries at the directory dirPath and all entries
|
||||||
// if count is set to -1
|
// if count is set to -1
|
||||||
func readDirWithOpts(dirPath string, opts readDirOpts) (entries []string, err error) {
|
func readDirWithOpts(dirPath string, opts readDirOpts) (entries []string, err error) {
|
||||||
f, err := OpenFile(dirPath, readMode, 0o666)
|
fd, err := openFileWithFD(dirPath, readMode, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !osIsPermission(err) {
|
if !osIsPermission(err) {
|
||||||
return nil, osErrToFileErr(err)
|
return nil, osErrToFileErr(err)
|
||||||
@ -249,12 +266,12 @@ func readDirWithOpts(dirPath string, opts readDirOpts) (entries []string, err er
|
|||||||
// There may be permission error when dirPath
|
// There may be permission error when dirPath
|
||||||
// is at the root of the disk mount that may
|
// is at the root of the disk mount that may
|
||||||
// not have the permissions to avoid 'noatime'
|
// not have the permissions to avoid 'noatime'
|
||||||
f, err = Open(dirPath)
|
fd, err = openFileWithFD(dirPath, os.O_RDONLY, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, osErrToFileErr(err)
|
return nil, osErrToFileErr(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
bufp := direntPool.Get().(*[]byte)
|
bufp := direntPool.Get().(*[]byte)
|
||||||
defer direntPool.Put(bufp)
|
defer direntPool.Put(bufp)
|
||||||
@ -273,7 +290,7 @@ func readDirWithOpts(dirPath string, opts readDirOpts) (entries []string, err er
|
|||||||
if boff >= nbuf {
|
if boff >= nbuf {
|
||||||
boff = 0
|
boff = 0
|
||||||
stop := globalOSMetrics.time(osMetricReadDirent)
|
stop := globalOSMetrics.time(osMetricReadDirent)
|
||||||
nbuf, err = syscall.ReadDirent(int(f.Fd()), buf)
|
nbuf, err = syscall.ReadDirent(fd, buf)
|
||||||
stop()
|
stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isSysErrNotDir(err) {
|
if isSysErrNotDir(err) {
|
||||||
|
@ -14,23 +14,25 @@ func _() {
|
|||||||
_ = x[osMetricRename-3]
|
_ = x[osMetricRename-3]
|
||||||
_ = x[osMetricOpenFileW-4]
|
_ = x[osMetricOpenFileW-4]
|
||||||
_ = x[osMetricOpenFileR-5]
|
_ = x[osMetricOpenFileR-5]
|
||||||
_ = x[osMetricOpen-6]
|
_ = x[osMetricOpenFileWFd-6]
|
||||||
_ = x[osMetricOpenFileDirectIO-7]
|
_ = x[osMetricOpenFileRFd-7]
|
||||||
_ = x[osMetricLstat-8]
|
_ = x[osMetricOpen-8]
|
||||||
_ = x[osMetricRemove-9]
|
_ = x[osMetricOpenFileDirectIO-9]
|
||||||
_ = x[osMetricStat-10]
|
_ = x[osMetricLstat-10]
|
||||||
_ = x[osMetricAccess-11]
|
_ = x[osMetricRemove-11]
|
||||||
_ = x[osMetricCreate-12]
|
_ = x[osMetricStat-12]
|
||||||
_ = x[osMetricReadDirent-13]
|
_ = x[osMetricAccess-13]
|
||||||
_ = x[osMetricFdatasync-14]
|
_ = x[osMetricCreate-14]
|
||||||
_ = x[osMetricSync-15]
|
_ = x[osMetricReadDirent-15]
|
||||||
_ = x[osMetricRename2-16]
|
_ = x[osMetricFdatasync-16]
|
||||||
_ = x[osMetricLast-17]
|
_ = x[osMetricSync-17]
|
||||||
|
_ = x[osMetricRename2-18]
|
||||||
|
_ = x[osMetricLast-19]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _osMetric_name = "RemoveAllMkdirAllMkdirRenameOpenFileWOpenFileROpenOpenFileDirectIOLstatRemoveStatAccessCreateReadDirentFdatasyncSyncRename2Last"
|
const _osMetric_name = "RemoveAllMkdirAllMkdirRenameOpenFileWOpenFileROpenFileWFdOpenFileRFdOpenOpenFileDirectIOLstatRemoveStatAccessCreateReadDirentFdatasyncSyncRename2Last"
|
||||||
|
|
||||||
var _osMetric_index = [...]uint8{0, 9, 17, 22, 28, 37, 46, 50, 66, 71, 77, 81, 87, 93, 103, 112, 116, 123, 127}
|
var _osMetric_index = [...]uint8{0, 9, 17, 22, 28, 37, 46, 57, 68, 72, 88, 93, 99, 103, 109, 115, 125, 134, 138, 145, 149}
|
||||||
|
|
||||||
func (i osMetric) String() string {
|
func (i osMetric) String() string {
|
||||||
if i >= osMetric(len(_osMetric_index)-1) {
|
if i >= osMetric(len(_osMetric_index)-1) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user