Created attachment 197991 [details] demonstrate problem with cached attributes The attached test.sh script demonstrates the problem. real-life Situation: A file (script) is created without execute permission on a exported filesystem. Next the script is accessed by a NFSv4 client (in our case a cluster node trying to execute it, which correctly fails). Next the modes of the script are fixed ("chmod +x") on the server (or on another nfs client) by the user. However, when execution is retried on the nfs client, it will continue to fail even after waiting multiple times longer than any nfs cache timeouts. This is nfsv4 specific. Results (of the attached test.sh script) : nfs mount option="" version wait status ---------------------------------------------- 3.14.54 300 FAIL(#1) 3.10.29 300 FAIL(#1) 4.0.5 300 FAIL(#1) 4.3.3 300 FAIL(#1) version=3.14.54 option wait status ---------------------------------------------- "" 40 FAIL(#1) nfsvers=3 40 OK noac 40 FAIL(#2) noac 300 FAIL(#2) actimeo=5 40 FAIL(#1) #1 : ./test.sh: line 31: /tmp/nfs_mnt/test.sh: Permission denied #2 : ./test.sh: /tmp/nfs_mnt/test.sh: /bin/sh: bad interpreter: Permission denied
The problem is in fs/nfs/dir.c nfs_permission() ( http://lxr.free-electrons.com/source/fs/nfs/dir.c#L2438 ) The call in line 2473 queries the server via _nfs4_proc_access for MAY_READ and MAY_ACCESS. The server response is used to update the "access" parameter in the cache, but not the "mode" parameter or the mode in the inode. In line 2487 is an additional check, where execute_ok(inode) uses inode->i_mode, which is never updated. The -EACCESS here is the one preventing the script from being executed. With nfs3 the problem doesn't manifest, because the LOOKUP used to find the script will get all attributes right away, so the cache is fresh. My test script executes well, when the check in 2487,2488 is removed. This check was refactored by https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f696a3659fc4b3a3bf4bc83d9dbec5e5a2ffd929 from namei.c into the individual permission functions of the filesystems. Do we need the check for nfs (where the access check has been done by the server and the mode might be misleading due to uid translation etc. anyway) ?
Created attachment 198231 [details] suggested patch
Fixed by NFS: Fix attribute cache revalidation NFS: Ensure we revalidate attributes before using execute_ok() NFSv4: Don't perform cached access checks before we've OPENed the file in v4.5-rc1