I'm running into a problem using tar(1) to create a read-only file on an
aufs file system with two nfs4 branches.
----
test@sivtar-8e3b7f91b4ed:~/test$ ls
test@sivtar-8e3b7f91b4ed:~/test$ echo test > x
test@sivtar-8e3b7f91b4ed:~/test$ chmod 0400 x
test@sivtar-8e3b7f91b4ed:~/test$ tar cvf x.tar x
x
test@sivtar-8e3b7f91b4ed:~/test$ rm x
rm: remove write-protected regular file ?x?? y
test@sivtar-8e3b7f91b4ed:~/test$ tar xvf x.tar
x
tar: x: Cannot open: Permission denied
tar: Exiting with failure status due to previous errors
test@sivtar-8e3b7f91b4ed:~/test$ ls -l
total 12
-r-------- 1 test test    0 Apr 5 04:03 x
-rw-r--r-- 1 test test 10240 Apr 5 04:03 x.tar
test@sivtar-8e3b7f91b4ed:~/test$
----
I've narrowed it down to this test case:
----
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
 int fd = open("x", O_WRONLY|O_CREAT, 0400);
 if (fd < 0)
   return 1;
 write(fd, "test\n", 5);
 return 0;
}
----
which wrongly fails on aufs with nfs4 branches. The correct behavior is for
the open() call to succeed and for the resulting file descriptor to be
writable; instead, the file is created but -EACCES is returned by open().
The open(2) man page documents this behavior, and tar(1) relies on it.
The relevant strace when running on aufs:
----
open("x", O_WRONLY|O_CREAT, 0400)Â Â Â Â Â Â = -1 EACCES (Permission
denied)
----
The strace when running directly on nfs4:
----
open("x", O_WRONLY|O_CREAT, 0400)Â Â Â Â Â Â = 3
write(3, "test\n", 5)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â = 5
----
This error seems to affect multiple or all versions of aufs, but the
specific data for the version that produced the above traces is:
aufs version: [Â Â Â 1.060148] aufs 3.x-rcN-20150330
I'm using kernel 4.0.0-rc6 in qemu.
I've attached a shell log that I believe contains all the information you
request for bug reports; please do let me know if I've missed something.
I've had a look at the relevant code in fs/namei.c, and it appears to me the
problem is that lookup_open(), in the absence of an ->atomic_open method,
falls back to creating a file with vfs_create, then opening it with
vfs_open, which fails in this case. It's not clear to me what a good fix
would be, though implementing ->atomic_open should work.
As an experiment, I've disabled nfs4's ->atomic_open method, and the result
was that with the modified kernel, my test program fails even directly on
the nfs file system. It still succeeds both directly on a ramfs and on an
aufs using said ramfs, but that appears to be because ramfs has no ->open at
all
aufs-data
Description: Binary data
------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
