Bug 43262

Summary: mkdir under automounted directory fails with EACCESS instead of EEXIST
Product: File System Reporter: Andrew McNabb (amcnabb)
Component: NFSAssignee: Trond Myklebust (trondmy)
Status: RESOLVED DOCUMENTED    
Severity: normal CC: alan
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: - Subsystem:
Regression: No Bisected commit-id:

Description Andrew McNabb 2012-05-18 15:44:56 UTC
Doing a mkdir("/net/prodigy/tmp"), where "/net/prodigy" is an automounted NFS directory, fails with EACCES instead of EEXIST. This error appears when the mkdir triggers the automount (and incidentally, even when a stat("/net/prodigy") was performed just previously).

It's not 100% clear if this is a kernel bug or unclear behavior in a corner case. This issue was brought up in the following Python bug report, where the conclusion is that it's a kernel bug:

http://bugs.python.org/issue14702
Comment 1 Alan 2012-05-18 20:41:36 UTC
(From python bug)

| I guess this is the magic in mkdir -p
|
| mkdir("expert", 0755)                   = -1 EACCES (Permission denied)
| chdir("expert")                         = 0
| mkdir("tmp", 0755)                      = -1 EEXIST (File exists)
|
| I'm not sure how I feel about that. I think we have more or less a policy in os & shutil not to change directories | unless really necessary (like make_archive).
Comment 2 Andrew McNabb 2012-05-21 15:29:34 UTC
(Also from the Python bug)

| > Event if it wasn't done, calling mkdir() ought to trigger the mount.
|
| I’m not sure if/where the behavior is defined – let’s what the Linux
people say.
Comment 3 Trond Myklebust 2012-05-21 15:52:43 UTC
The thing to note is Linus has decreed that for efficiency reasons,
autofs and other users of the d_automount field in struct dentry_operations
will now only automount if you attempt to actually access the directory.

The idea is to speed up 'ls -l' by avoiding unnecessary automount upcalls.

The recommended way to access the automounted directory itself today is
therefore to use the backslash-terminated notation /net/foo/bar/.
So if you  were to change your stat requests to stat('/net/prodigy/') then
that would likely trigger the automount instead of returning ENOENT.
Comment 4 Andrew McNabb 2012-05-21 16:11:42 UTC
Trond, thanks for the response. Just to clarify:

1) Did you mean to say that if you "change your stat requests to stat('/net/prodigy/.') then..."?

2) Intuitively, it seems like mkdir("/net/prodigy/tmp") would count as an access of "/net/prodigy" and would trigger a mount of "/net/prodigy". Does a mkdir of a subdirectory not count as an access of the parent directory?
Comment 5 Trond Myklebust 2012-05-21 17:04:50 UTC
Yes, any access to a subdir or child of /net/prodigy should trigger an
automount. I was looking at your 'stat()' calls in the python bug report
prior to the mkdir() attempt.