diff options
| -rwxr-xr-x | fusearchive.py | 35 | 
1 files changed, 30 insertions, 5 deletions
| diff --git a/fusearchive.py b/fusearchive.py index a0cdb18..f3567aa 100755 --- a/fusearchive.py +++ b/fusearchive.py @@ -46,6 +46,14 @@ dirty_size = 1024 * 1024 * 1;  # This is the number of actualy blocks in that size  dirty_flush = int( dirty_size / magic_blocksize ) +# This is a cache of open files by inode, to fix the lseek == size problem +# this causes a failure in fsx-linux becuase to to lseek(fd,0,seek_end) it +# apparently does a getattr to find the file length then subtracts the +# offset from that to pass to write or whatever, since the offset is passed +# to write and we don't maintain one internally.  xmp.py also fails this +# test. +dirty_cache = {} +  def flag2mode(flags):      md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'}      m = md[flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)] @@ -344,11 +352,19 @@ class FuseArchive(Fuse):          treefile = "./tree" + path          if os.path.isfile( treefile ): -            logging.debug( "Delegating getattr to FuserArchiveFile" ) - -            f = self.FuseArchiveFile( path, os.O_RDONLY, 0 ) -            stats = f.fgetattr() -            f.release( 0 ) +            logging.debug( "Delegating getattr to FuserArchiveFile for " + path ) + +            # Check in the dirty cache first (to handle lseek and the +            # relatively broken implmentation in fuse/python) +            if path in dirty_cache: +                logging.info( "WORKAROUND: lseek appears to do a gettattr if whence is SEEK_END, using dirty cache object" ) +                f = dirty_cache[ path ] +                stats = f.fgetattr() +                # no release, it's still being used +            else: +                f = self.FuseArchiveFile( path, os.O_RDONLY, 0 ) +                stats = f.fgetattr() +                f.release( 0 )          else:              logging.debug( "Using os.lstat to get stats" )              stats = os.lstat( treefile ) @@ -725,6 +741,10 @@ class FuseArchive(Fuse):              logging.debug( "Chunk size is now: " + str(len(self.chunk)) )              logging.debug( "File size is now: " + str(self.size) ) + +            # Mark us in the dirty cache +            dirty_cache[ self.orig_path ] = self +              return len(buf)          # BUG: If you cp -a a file then quickly ls -l sometimes it doesn't show @@ -766,6 +786,10 @@ class FuseArchive(Fuse):                      'chunk_size': self.chunk_size                  } ) +                # Not dirty anymore +                if self.orig_path in dirty_cache: +                    del dirty_cache[ self.orig_path ] +              logging.debug( "_fflush exit" )              return 1 @@ -854,6 +878,7 @@ class FuseArchive(Fuse):              self.modified = True              self.size = length              self._load_chunk( 0 ) +            # Don't need to mark dirty cache because we're flushing              self._fflush()          def lock(self, cmd, owner, **kw): | 
