fuse
changeset 5 bef1e4dd8e85
parent 2 79eb9a0609af
child 12 46a3e65e850f
--- a/fuse	Fri Jul 22 17:06:09 2011 +0200
+++ b/fuse	Sun Jul 24 00:22:11 2011 +0200
@@ -32,7 +32,8 @@
 { package fs;
   use strict;
   use warnings;
-  use POSIX qw(:errno_h);
+  use POSIX qw(:errno_h); 
+  use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
   use autodie qw(:all);
 
   our ($ROOT, $DATA, $IDX);
@@ -40,18 +41,15 @@
   my %CACHE;
 
     sub getattr {
-		my $path = $IDX . shift;
-		return stat $path if -d $path;
-		# rest are the idx
-		my @attr = stat $path or return -(ENOENT);
-		my %meta = _get_meta($path);
-		use Data::Dumper;
-		warn Dumper \%meta;
-		$attr[7] = $meta{devsize};
-		$attr[9] = $meta{timestamp};
-		$attr[2] &= ~0222;		# r/o
-		warn Dumper \@attr;
-		return @attr;
+	my $path = $IDX . shift;
+	return stat $path if -d $path;
+	# rest are the idx
+	my @attr = stat $path or return -(ENOENT);
+	my %meta = _get_meta($path);
+	$attr[7] = $meta{devsize};
+	$attr[9] = $meta{timestamp};
+	$attr[2] &= ~0222;		# r/o
+	return @attr;
     }
 
     sub getdir {
@@ -60,7 +58,6 @@
 	return (readdir($dh), 0);
     }
 
-
     sub openfile {
 	my $path = $IDX . shift;
 	return 0 if exists $FILE{$path};
@@ -78,6 +75,7 @@
 	    $block-- if not $FILE{$path}{meta}{format};
 	    $FILE{$path}{blocklist}{$block} = $file;
 	}
+	close $fh;
 	return 0;
     }
 
@@ -88,7 +86,7 @@
 	return "" if $offset >= $finfo->{meta}{devsize};
 
 	my $buffer = "";
-	for (my $need = $size; $need; $need = $size - length($buffer)) {
+	for (my $need = $size; $need > 0; $need = $size - length($buffer)) {
 	    $buffer .= _readblock($finfo, $need, $offset + length($buffer));
 	}
 
@@ -108,10 +106,25 @@
 	    return substr $CACHE{$finfo}{$block}, $blockoffset, $length;
 	}
 
-	open(my $fh => "$DATA/" . $finfo->{blocklist}{$block});
-	seek($fh => $blockoffset, 0) or die "seek: $!";
-	local $/ = \$length;
-	return scalar <$fh>;
+	my $fn = "$DATA/" . $finfo->{blocklist}{$block};
+	if (-e $fn) {
+		open(my $fh => $fn);
+		binmode($fh);
+		seek($fh => $blockoffset, 0) or die "seek: $!";
+		local $/ = \$length;
+		return scalar <$fh>;
+	}
+	elsif (-e "$fn.gz") {
+		open(my $fh => "$fn.gz");
+		binmode($fh);
+		my $buffer;
+		gunzip($fh => \$buffer)
+			or die $GunzipError;
+		close($fh);
+		return substr($buffer, $blockoffset, $size);
+	}
+	
+	die "$fn: $!\n";
     }
 
     sub writebuffer {
@@ -120,10 +133,11 @@
 	my $size = length($buffer);
 	my $finfo = $FILE{$path} or die "File $path is not opened!";
 
-	my $written = 0;
-	while ($written < $size) {
-	     my $n = _writeblock($finfo, substr($buffer, $written), $offset + $written); 
-	     return $written if not $n;
+	for (my $written = 0; $written < $size;) {
+	     # OPTIMIZE: we should not ask for writing more than the
+	     # blocksize
+	     my $n = _writeblock($finfo, substr($buffer, $written), $offset + $written) 
+		or return $written;
 	     $written += $n;
 	}
 	return $size;
@@ -137,14 +151,15 @@
 	my $blockoffset = $offset % $finfo->{meta}{blocksize};
 
 	if (not exists $CACHE{$finfo}{$block}) {
-	    open(my $fh => "$DATA/" . $finfo->{blocklist}{$block});
-	    local $/ = undef;
-	    $CACHE{$finfo}{$block} = <$fh>;
-	    close($fh);
+	    #open(my $fh => "$DATA/" . $finfo->{blocklist}{$block});
+	    #local $/ = undef;
+	    #$CACHE{$finfo}{$block} = <$fh>;
+	    #close($fh);
+	    $CACHE{$finfo}{$block} = _readblock($finfo, $finfo->{meta}{blocksize}, $block * $finfo->{meta}{blocksize});
 	}
 
 	my $length = $finfo->{meta}{blocksize} - $blockoffset;
-	$length = $size if $size <= $length;
+	$length = $size if $size < $length;
 
 	substr($CACHE{$finfo}{$block}, $blockoffset, $length)
 	    = substr($buffer, 0, $length);