Addition of file handles on open files rt-57517-file-handles
authorJustin Fletcher <gerph@gerph.org>
Sun, 16 May 2010 16:25:07 +0000 (18:25 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Sun, 16 May 2010 16:25:07 +0000 (18:25 +0200)
commitc66dce6e79b980376e51981561de6b52b6f6c364
treec3d2130276e0cceff7bdea166319e8c8ad0bb371
parentb67cad861f47e6f8b61e7c827527dd5a55d8c8b7
Addition of file handles on open files

Sat May 15 16:36:47 2010: Request 57517 was acted upon.
Transaction: Ticket created by gerph
       Queue: Fuse
     Subject: Addition of file handles on open files
   Broken in: 0.09_3
    Severity: (no value)
       Owner: Nobody
  Requestors: gerph@gerph.org
      Status: new
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=57517 >

Hiya,

Whilst trying to write a filesystem using the Fuse module, I found it
surprising that there were no 'file handles' available when you opened
a file. The only way you can know what file was referenced is by its
name, which is not useful if your filesystem is intended to return
different results for each file opened. It turned out in my case to not
matter, but consider a FS which returned a different story every time
you opened it. Or, more practically, a FS which returned the contents
of the latest checked in file - and whilst you were operating on the
file the latest checked in file changed. There are ways around this -
files becoming invariant whilst it has any open instances of itself or
similar - but these are not ideal.

The way that Fuse appears to do this is that the filesystem updates a
property ('fh') in the fuse_file_info structure on open, to contain the
context for the opened file. I've put together a change which allows
you to return a second parameter from open containing this value, which
is then passed to all the functions which operate on open files (read,
write, flush, release). Because we're retaining a reference to the SV
that was returned (and is otherwise unused in the perl) we also
increment the refcount on open, and decrement it on release - I think
that's all that's necessary to prevent a leak, but I've never done any
XS work before this so I can't be certain.

I'd expect that under normal circumstances you'd open a file, set up a
hashref containing properties for the file that you've opened and use
'return (0, $handle);' to return it. If you don't return a handle, the
old behaviour remains - undef will be passed to the implementation in
place of the handle (which the implementation wasn't expecting so won't
care about).

In addition, I've also added the ability to set the 'direct_io',
'keepcache' and 'nonseekable' properties by changing a hashref which is
passed to the 'open' call.

The archive I've attached contains the Fuse.pm and Fuse.xs files in
their entirity, together with the diffs from 0.09_3. There is also a
rudimentary example FS, based on the example one in the Fuse
distribution, which shows the file handle to be working. It seems to be
working in my more complex MythTV filesystem that I'm still trying to
make useful.

I couldn't actually test the nonseekable property as the fuse I have
seems to be 2.4, so I don't have that property available to me here -
I've just followed what the documentation says should be available.

I've not added anything to the tests, because I'm not sure how to do
that really, but I hope that the change to add the file handles is
useful.
Fuse.pm [changed mode: 0644->0755]
Fuse.xs [changed mode: 0644->0755]
examples/example.pl