DescriptionAchilles Gaikwad
2018-05-13 17:00:18 UTC
Created attachment 1435776[details]
C program which calls the syscall getdents64 with the given buffer size
Description of problem:
When a program written in Go is listing directory contents in a CIFS mount with many files, the Linux kernel misses some files. When we increase the buffer size for getdents we get a proper listing and no files are lost.
Version-Release number of selected component (if applicable):
3.10.0-862.el7.x86_64
golang-src-1.9.4-1.el7.noarch
cifs-utils-6.2-10.el7.x86_64
golang-1.9.4-1.el7.x86_64
golang-bin-1.9.4-1.el7.x86_64
How reproducible:
Always
Steps to Reproduce:
1. mount -t cifs //cifs-server/cifs /mnt
2. touch /mnt/{1..1000}
3. ls -la /mnt | wc -l
4. go run man.go /mnt
5. ./man.o 4096 /mnt
Actual results:
# ls -la /mnt | wc -l
1003
# go run man.go /mnt
996
# ./getdents_ls 4096 /cifs | tail -n 1
Found 996 entries
Expected results:
# ls -la /mnt | wc -l
1003
# go run man.go /mnt
1002
# ./getdents_ls 4096 /cifs | tail -n 1
Found 1002 entries
Additional info:
I've attached the c program,
C program.
----------
# gcc -Wall getdents_ls.c -o getdents_ls
# getdents_ls [<buf_size> [<path>]]
GO program.
----------
# cat man.go
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Open(os.Args[1])
if err != nil {
panic(err)
}
names, err := f.Readdirnames(-1)
if err != nil {
panic(err)
}
fmt.Printf("%d\n", len(names)+2 /* ., .. */)
}
# go run man.go [<path>]]
github issue for more information: https://github.com/golang/go/issues/24015#issuecomment-369719030
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory, and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.
https://access.redhat.com/errata/RHSA-2019:2029