Bug 1577640 - getdents on cifs with 4k buffer loses files
Summary: getdents on cifs with 4k buffer loses files
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: kernel
Version: 7.5
Hardware: Unspecified
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Ronnie Sahlberg
QA Contact: xiaoli feng
URL:
Whiteboard:
Depends On:
Blocks: 1577173
TreeView+ depends on / blocked
 
Reported: 2018-05-13 17:00 UTC by Achilles Gaikwad
Modified: 2019-10-22 04:50 UTC (History)
9 users (show)

Fixed In Version: kernel-3.10.0-1025.el7
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-08-06 12:12:17 UTC
Target Upstream Version:


Attachments (Terms of Use)
C program which calls the syscall getdents64 with the given buffer size (1.80 KB, text/plain)
2018-05-13 17:00 UTC, Achilles Gaikwad
no flags Details


Links
System ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2019:2029 None None None 2019-08-06 12:13:28 UTC

Description Achilles 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

Comment 2 Frank Sorenson 2018-05-14 01:28:02 UTC
issue does not reproduce on rhel6 or upstream kernel

Comment 11 Bruno Meneguele 2019-03-15 19:18:12 UTC
Patch(es) committed on kernel-3.10.0-1025.el7

Comment 16 errata-xmlrpc 2019-08-06 12:12:17 UTC
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


Note You need to log in before you can comment on or make changes to this bug.