mukulyadav49 / macfuse

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

open for O_APPEND does not include O_APPEND bit in open message flags #132

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
  wget http://swtch.com/fusetest-0.4.tar.gz  # also attached
  tar xzvf fusetest-0.4.tar.gz
  cd fusetest-0.4
  make
  ./fusetest -D simple /mnt
  ./open /mnt/f append

Fusetest is a simple fuse file server that, when run in simple mode,
presents a single file /mnt/f.  It ignores setattr requests but allows them
to succeed.  Running with -D prints the fuse traffic prefixed by FUSE:.  
Running ./open /mnt/f append executes open("/mnt/f", O_WRONLY|O_APPEND).

The expected output from fusetest when running ./open /mnt/f append is an
Open message that includes the O_APPEND bit, but MacFUSE does not.

Here is Linux output (the "append: 3" line is output from ./open):

linux# ./open /mnt/f append
    FUSE -> len 2 unique 0x2  Lookup nodeid 0x1 name 'f'
    FUSE <- unique 0x2 (Lookup) nodeid 0x2 gen 0x1 ...
    FUSE -> len 8 unique 0x3  Open nodeid 0x2 flags 0x8401 mode 0
    FUSE <- unique 0x3 (Open) fh 0x3 flags 0x1
append: 3
    FUSE -> len 16 unique 0x4  Flush nodeid 0x2 fh 0x3 flags 0
    FUSE <- unique 0x4 (Flush)
    FUSE -> len 16 unique 0x5  Release nodeid 0x2 fh 0x3 flags 0x8401
    FUSE <- unique 0x5 (Release)
linux# 

Notice the open flags 0x8401.  0x8000 is Linux O_LARGEFILE, and 0x1 is
O_WRONLY.  0x400 is O_APPEND.

On MacFUSE, I get:

mac# ./open /mnt/f append
    FUSE -> len 8 unique 0  Access nodeid 0x3 mask 0x2
    FUSE <- unique 0 (Access)
    FUSE -> len 8 unique 0  Open nodeid 0x3 flags 0x1 mode 0
    FUSE <- unique 0 (Open) fh 0x4 flags 0x1
append: 3
    FUSE -> len 24 unique 0  Release nodeid 0x3 fh 0x4 flags 0x1
    FUSE <- unique 0 (Release)
mac# 

Note that the open flags are just O_WRONLY.  O_APPEND is not passed along.

It should be.  Otherwise shared append-only files cannot be implemented on
the server side.  (If multiple machines are writing to the same file in
O_APPEND mode, the local kernel can't make sure the writes truly append,
while the file server can.)

Original issue reported on code.google.com by russ...@gmail.com on 27 Mar 2007 at 1:07

Attachments:

GoogleCodeExporter commented 9 years ago
Yes, and there might be some other flags that aren't passed along to user space 
too. This is mainly because of 
the reasons I mentioned in my comments for Issue #133. For example, a file 
handled opened O_WRONLY is 
different from a file handle that's opened (O_WRONLY,O_APPEND). MacFUSE, with 
file handle sharing, needs to do 
more fine grained discrimination, or there must be another, better solution 
altogether.

Original comment by si...@gmail.com on 28 Mar 2007 at 1:03

GoogleCodeExporter commented 9 years ago
Even though O_APPEND is not passed to the user-space daemon, it *is* handled 
correctly by the "local" kernel. 
Sure, there can be a case for the daemon still wanting to know (if a single 
file is being simultaneously written in 
append mode by multiple computers on a network).

Original comment by si...@gmail.com on 29 Mar 2007 at 3:28

GoogleCodeExporter commented 9 years ago
I made what looked like the obvious changes to add this (based on outside 
discussion):
Add fufh_type values corresponding to write-only-with-append and 
read-write-with-
append.
Extend fuse_filehandle_xlate_from_fflags and fuse_filehandle_xlate_to_oflags to 
cover those cases.

To go with those, I made a couple of other changes:
Changed the definition of fuse_node to make use of FUFH_MAXTYPE.
Removed a line of code I didn't understand that looked like it was overwriting 
the 
oflags from the user before passing them to the filesystem.

Comments welcome; if the style doesn't match closely enough, I can certainly 
fix the 
patch (unless someone else wants to).

Original comment by CDeVilb...@gmail.com on 5 Apr 2007 at 2:04

Attachments:

GoogleCodeExporter commented 9 years ago
CDeVilbiss:

Simply adding a couple more file handle types doesn't solve the problem. There 
are other caveats. For 
example, at the system call level, open(, O_CREAT...) is atomic, but 
internally, it results in two calls to the 
MacFUSE vnode operations: first for vnop_create (assuming the file doesn't 
exist) and then for vnop_open. 
Now, in open(), you could create a file with on-disk permissions of 0000 (that 
is, no access), but still have the 
descriptor open O_RDWR. However, vnop_create() doesn't know that which mode the 
file is going to be 
opened in later. What currently happens is that during vnop_create(), MacFUSE 
will fetch a "maximally 
permissive" O_RDWR file handle from FUSE. If the create succeeded, there will 
be a subsequent vnop_open, 
and only then will we know what flags are being used. Depending on which 
descriptor type we really want, 
MacFUSE moves (if needed) the O_RDWR handle to the appropriate slot. That's the 
reason for the line of code 
you said you didn't understand. In a situation like this, we can't have the 
notion of "maximally permissive" 
with O_APPEND (obviously, O_APPEND and !O_APPEND are mutually exclusive, so 
without knowing what the 
flags actually are going to be in open, which one will you get?). If we don't 
get the file handle during 
vnop_create but get it during vnop_open, we're not guaranteed to get the type 
of the file handle we want. 
Another side point: since we don't have 1:1 'struct files' and FUSE file 
handles to begin with, MacFUSE tries to 
reuse file handles when possible (for example, if the kernel already has O_RDWR 
and it needs O_WRONLY, it's 
not going to create another one).

Original comment by si...@gmail.com on 5 Apr 2007 at 7:39

GoogleCodeExporter commented 9 years ago
I agree with Amit.

Original comment by russ...@gmail.com on 5 Apr 2007 at 2:27

GoogleCodeExporter commented 9 years ago
Thanks for clarifying.  I had misunderstood the design earlier; I thought that 
every 
combination of flags would have an independent FUSE file handle, each of which 
would 
be shared only with the clients that had exactly-matching flags.

I was also confused by the two conflicting assignments to fufh->open_flags that 
were 
in that codepath in the version I have on the system where I made the patch.  I 
see 
that the trunk code online is more straightforward now.

Original comment by CDeVilb...@gmail.com on 6 Apr 2007 at 8:03

GoogleCodeExporter commented 9 years ago

Original comment by si...@gmail.com on 8 Jun 2007 at 8:01