fluiday / macfuse

Automatically exported from code.google.com/p/macfuse
Other
0 stars 0 forks source link

O_WRONLY mangled into O_RDWR during a CREATE opcode? #117

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. start fusexmp_fh
2. touch mountpoint/foo

What is the expected output? What do you see instead?

If you ktrace touch, you'll see that it calls open() with flags of 0x201
(O_CREAT | O_WRONLY)

If you instrument fusexmp_fh.c:xmp_create(), however, it gets called with
flags of 0x2

I can understand that O_CREAT gets stripped, but why does O_WRONLY get
mutated into O_RDWR?  A similar test on Linux leaves the non-O_CREAT flags
(0x8801) unchanged, as I would expect.

What version of the product are you using? On what operating system?

0.2.2 on Mac OS X 10.4.8

Original issue reported on code.google.com by sch...@gmail.com on 27 Feb 2007 at 9:31

GoogleCodeExporter commented 9 years ago
> I can understand that O_CREAT gets stripped

Although on second thought, why even strip O_CREAT?  The Linux code doesn't, 
and it
leads to stuff like:

#if (__FreeBSD__ >= 10)
    fd = open(path, fi->flags | O_CREAT, mode);
#else
    fd = open(path, fi->flags, mode);
#endif

as found in fusexmp_fh.c (and notably missing from fuse-python, which is what 
led me
to this bug in the first place)

Or if the OS pre-strips O_CREAT, why not put it back, in the interest of 
consistent
cross-platform fuse behaviour?

Original comment by sch...@gmail.com on 27 Feb 2007 at 9:49

GoogleCodeExporter commented 9 years ago
O_CREAT doesn't need to be stripped. I just "forgot" to add it back after a 
phase of experimentation when I 
was coming up with the file descriptor management part of MacFUSE. It's ironic 
that I even "fixed" it in 
fusexmp instead of the kernel. I'll fix it better. If you are willing to 
recompile the kernel extension from 
source, change line 314 of fusefs/fuse_vnops.c to have "O_CREAT | O_RDWR" 
instead of just "O_RDWR".

The O_RDWR is by design, on purpose. It's because of the way things work in Mac 
OS X. When you call the 
open() system call with O_CREAT, even though the  call is atomic from the 
caller's standpoint, I get two 
discrete vnode operation calls: vnop_create and vnop_open. In Mac OS X, within 
a loadable file system's vnode 
operations, you don't have access to file descriptors. In particular, in the 
create (which obviously occurs before 
the open), I can't know how this file is going to be opened later. Now, POSIX 
lets you do things like 'open
("foo", O_CREAT | O_WRONLY, 0000)' -- that is, using the descriptor, you can 
write to the file, even though its 
on-disk permissions are going to disallow writing for a subsequent open. If I 
am to support such semantics, I 
need to acquire through FUSE_CREATE a "maximally permissive" file descriptor 
that will let me do reads/writes 
-- as the need be -- as dictated by the subsequent open associated with the 
create. There are many other 
"interesting" details about this scheme that you can see by looking at the code.

Original comment by si...@gmail.com on 27 Feb 2007 at 10:18

GoogleCodeExporter commented 9 years ago
OK, that's quite a good answer.  I didn't know the details of OS X vnode 
semantics,
but it's makes sense.

I can survive with O_WRONLY being mapped to O_RDWR -- but the missing O_CREAT 
was
causing real headaches.

Thanks for your prompt reply!

Original comment by sch...@gmail.com on 27 Feb 2007 at 2:06

GoogleCodeExporter commented 9 years ago
O_CREAT stripping fixed in the next release.

Original comment by si...@gmail.com on 27 Feb 2007 at 7:43