[<prev] [next>] [day] [month] [year] [list]
Message-ID: <2d735cb666872099b2c4c574e35aaeac2f7356ad.camel@gmail.com>
Date: Mon, 01 Jun 2020 21:58:36 +0200
From: Jakob Unterwurzacher <jakobunt@...il.com>
To: linux-cifs@...r.kernel.org
Cc: linux-kernel@...r.kernel.org
Subject: cifs vs Go: EINTR and ENOENT errors from getdents64
Hi, author of gocryptfs here, an encrypted overlay
filesystem written in Go.
A gocryptfs user reported [1] hitting EINTR errors
when gocryptfs is used on a cifs mount.
I wrote a minimal reproducer, getdents.go [2], that runs
getdents64 in a loop and I can reproduce the issue easily.
I additionally see ENOENT errors.
The errors can also be seen via the high-level Readdirnames()
function that the Go stdlib provides [6].
I am running kernel 5.6.13 and Samba 4.12.2 for this test.
I have a cifs share mounted as shown in [3], populated
with 1001 empty files using
touch $(seq 1000 2000)
. When running getdents.go [2] against this mount, good cases look
like this (output from getdents.go):
--- example 0 ---
unix.Getdents: n=4176; n=4176; n=4176; n=4176; n=4176; n=3192; n=0; err=<nil>; total 24072 bytes
unix.Getdents: n=4176; n=4176; n=4176; n=4176; n=24; n=4152; n=3192; n=0; err=<nil>; total 24072 bytes
INTR errors look like this (getdents.go output and corresponding
kernel debug messages that were enabled acc. to [4]):
--- example 1 ---
unix.Getdents: n=-1; err=interrupted system call; total 0 bytes
[168340.499471] fs/cifs/file.c: CIFS VFS: leaving cifs_closedir (xid = 24238) rc = 0
[168340.599686] fs/cifs/readdir.c: Full path: start at: 0
[168340.599696] fs/cifs/transport.c: signal is pending before sending any data
[168340.599698] smb2_add_credits: 310 callbacks suppressed
[168340.599699] fs/cifs/smb2ops.c: add 1 credits total=8192
[168340.599701] fs/cifs/smb2ops.c: query_dir_first: open failed rc=-4
[168340.599702] fs/cifs/readdir.c: initiate cifs search rc -4
[168340.599979] fs/cifs/file.c: Closedir inode = 0x0000000067f9a79c
[168340.599981] fs/cifs/file.c: CIFS VFS: in cifs_closedir as Xid: 24240 with uid: 1026
[168340.599982] fs/cifs/file.c: Freeing private data in close dir
[168340.599983] fs/cifs/file.c: CIFS VFS: leaving cifs_closedir (xid = 24240) rc = 0
--- example 2 ---
unix.Getdents: n=-1; err=interrupted system call; total 0 bytes
[168453.792894] Status code returned 0x80000006 STATUS_NO_MORE_FILES
[168453.893360] fs/cifs/transport.c: signal is pending before sending any data
[168453.893363] fs/cifs/smb2ops.c: query_dir_first: open failed rc=-4
ENOENT errors look like this:
--- example 3 ---
unix.Getdents: n=4176; n=4176; n=4176; n=4176; n=4176; n=-1; err=no such file or directory; total 20880 bytes
[168517.187072] Status code returned 0x80000006 STATUS_NO_MORE_FILES
[168517.300252] fs/cifs/transport.c: signal is pending before sending any data
[168517.300255] fs/cifs/readdir.c: fce error -2
--- example 4 ---
unix.Getdents: n=4176; n=4176; n=4176; n=1440; n=2736; n=-1; err=no such file or directory; total 16704 bytes
[168650.603145] Status code returned 0x80000006 STATUS_NO_MORE_FILES
[168650.713831] fs/cifs/transport.c: signal is pending before sending any data
[168650.713835] fs/cifs/readdir.c: fce error -2
I have the same thing written in C does not show
any problems [5].
The Go runtime uses signals heavily, could this be a
reason for the behavoir I am seeing? I can trigger
the problem more quickly when I resize the terminal
window (causing SIGWINCH). Note that the Go runtime
sets SA_RESTART on all signal handlers.
I can handle the EINTR errors by retrying, no problem.
Should I also retry when I get ENOENT?
Thanks,
Jakob
[1] https://github.com/rfjakob/gocryptfs/issues/483
[2] https://github.com/rfjakob/gocryptfs/blob/master/contrib/getdents-debug/getdents/getdents.go
[3] //127.0.0.1/samba-test on /mnt/samba-test type cifs
(rw,relatime,vers=3.1.1,cache=strict,username=jakob,uid=1026,forceuid,gid=1026,forcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mappos
ix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1,user=jakob)
[4] https://wiki.samba.org/index.php/LinuxCIFS_troubleshooting#Enabling_Debugging
[5] https://github.com/rfjakob/gocryptfs/blob/master/contrib/getdents-debug/getdents_c/getdents.c
[6] https://github.com/golang/go/issues/39237
Powered by blists - more mailing lists