aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xfusearchive.py69
1 files changed, 64 insertions, 5 deletions
diff --git a/fusearchive.py b/fusearchive.py
index f8cce35..00a156d 100755
--- a/fusearchive.py
+++ b/fusearchive.py
@@ -380,7 +380,7 @@ class FuseArchive(Fuse):
def truncate(self, path, len):
# Truncate using the ftruncate on the file
dmsg( 2, "Using FuseArchiveFile to truncate " + path + " to " + str(len) )
- f = self.FuseArchiveFile( path, os.O_APPEND, 0 )
+ f = self.FuseArchiveFile( path, os.O_WRONLY | os.O_APPEND, 0 )
f.ftruncate(len)
f.release( 0 )
@@ -730,6 +730,7 @@ class FuseArchive(Fuse):
} )
+
return 1
@@ -760,11 +761,69 @@ class FuseArchive(Fuse):
stats.overstat( self.size )
return stats
- def ftruncate(self, len):
- if len > 0:
- print "WARNING: ftruncate is broken for non-zero len!!!"
+ def ftruncate(self, length):
+ if not self.wr:
+ return errno.IOError
+
+ curr_chunks = len( self.chunks )
+ need_chunks = ( length / self.chunk_size )
+ extra_bytes = length % self.chunk_size
+ dmsg( 3, "Ftruncate - " + str(length) )
+ dmsg( 3, " - curr_chunks: " + str( curr_chunks ) )
+ dmsg( 3, " - need_chunks: " + str( need_chunks ) )
+ dmsg( 3, " - extra_bytes: " + str( extra_bytes ) )
+
+ if extra_bytes:
+ dmsg( 3, "Need an extra chunk" )
+ need_chunks += 1
+
+ self._load_chunk( 0 )
+
+ pdb.set_trace()
+ if need_chunks == 0:
+ dmsg( 3, "Creating 0 chunk file" )
+ self.chunks = []
+ elif need_chunks > curr_chunks:
+ dmsg( 3, "Need to pad out file" )
+
+ # Just write out null bytes to the length requested
+ self.flush()
+ tmp_size = self.size
+ while tmp_size < length:
+ to_write = 4096
+ if tmp_size + to_write > length:
+ to_write = length - tmp_size
+
+ dmsg( 3, "Writing " + str( to_write ) + " bytes to extend file to " + str( length ) )
+ self.write( "\0" * to_write, tmp_size + 1 )
+ tmp_size += to_write
+
+ else:
+ dmsg( 3, "Truncating chunks" )
+ while True:
+ dmsg( 3, "Need chunks: " + str( need_chunks ) + " curr: " + str( curr_chunks ) )
+ if need_chunks == curr_chunks:
+ break
+
+ dmsg( 3, "Deleting chunk " + str( self.chunk_index ) )
+ self.chunks.pop()
+ curr_chunks = len( self.chunks )
+
+ # Now make sure this chunk is the right size, first load the
+ # last chunk
+ if len( self.chunks ):
+ self._load_chunk( len( self.chunks ) - 1 )
+ dmsg( 3, "Loaded final chunk, len: " + str( len( self.chunk ) ) )
+
+ # Now truncate or extend this item
+ if len( self.chunk ) < extra_bytes:
+ remaining = extra_bytes - len(self.chunk)
+ dmsg( 3, "Extending final chunk " + str( remaining ) + " bytes" )
+ self.chunk += "\0" * remaining
+ else:
+ dmsg( 3, "Truncating final chunk to " + str( extra_bytes ) )
+ self.chunk = self.chunk[ :extra_bytes ]
- self.chunks = []
self.modified = True
self._load_chunk( 0 )
self._fflush()