fuse
changeset 15 f218b05f1da4
parent 12 46a3e65e850f
child 16 867424a1db61
equal deleted inserted replaced
14:73b95264a70c 15:f218b05f1da4
    63   use POSIX qw(:errno_h); 
    63   use POSIX qw(:errno_h); 
    64   use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
    64   use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
    65   use autodie qw(:all);
    65   use autodie qw(:all);
    66 
    66 
    67   our ($ROOT, $DATA, $IDX);
    67   our ($ROOT, $DATA, $IDX);
    68   my %FILE;
    68   my %IMAGE;
    69   my %CACHE;
    69   my %DIRTY;
    70 
    70 
    71     sub getattr {
    71     sub getattr {
    72 	my $path = $IDX . shift;
    72 	my $path = $IDX . shift;
    73 	return stat $path if -d $path;
    73 	return stat $path if -d $path;
    74 	# rest are the idx
    74 	# rest are the idx
    86 	return (readdir($dh), 0);
    86 	return (readdir($dh), 0);
    87     }
    87     }
    88 
    88 
    89     sub openfile {
    89     sub openfile {
    90 	my $path = $IDX . shift;
    90 	my $path = $IDX . shift;
    91 	return 0 if exists $FILE{$path};
    91 	return 0 if exists $IMAGE{$path};
    92 	$FILE{$path}{meta} = { _get_meta($path) };
    92 	$IMAGE{$path}{meta} = { _get_meta($path) };
    93 	$FILE{$path}{blocklist} = {};
    93 	$IMAGE{$path}{blocklist} = {};
    94 
    94 
    95 	open(my $fh => $path);
    95 	open(my $fh => $path);
    96 	{   # the file header
    96 	{   # the file header
    97 	    local $/ = "";
    97 	    local $/ = "";
    98 	    scalar <$fh>;
    98 	    scalar <$fh>;
    99 	}
    99 	}
   100 	while (<$fh>) {
   100 	while (<$fh>) {
   101 	    /^#/ and last;
   101 	    /^#/ and last;
   102 	    my ($block, $cs, $file) = split;
   102 	    my ($block, $cs, $file) = split;
   103 	    $block-- if not $FILE{$path}{meta}{format};
   103 	    $block-- if not $IMAGE{$path}{meta}{format};
   104 	    $FILE{$path}{blocklist}{$block} = $file;
   104 	    $IMAGE{$path}{blocklist}{$block} = $file;
   105 	}
   105 	}
   106 	close $fh;
   106 	close $fh;
   107 	return 0;
   107 	return 0;
   108     }
   108     }
   109 
   109 
   110     sub readbuffer {
   110     sub readbuffer {
   111 	my $path = $IDX . shift;
   111 	my $path = $IDX . shift;
   112 	my ($size, $offset) = @_;
   112 	my ($size, $offset) = @_;
   113 	my $finfo = $FILE{$path} or die "File $path is not opened!";
   113 	my $finfo = $IMAGE{$path} or die "File $path is not opened!";
   114 	return "" if $offset >= $finfo->{meta}{devsize};
   114 	return "" if $offset >= $finfo->{meta}{devsize};
   115 
   115 
   116 	my $buffer = "";
   116 	my $buffer = "";
   117 	for (my $need = $size; $need > 0; $need = $size - length($buffer)) {
   117 	for (my $need = $size; $need > 0; $need = $size - length($buffer)) {
   118 	    $buffer .= _readblock($finfo, $need, $offset + length($buffer));
   118 	    $buffer .= _readblock($finfo, $need, $offset + length($buffer));
   128 	my $blockoffset = $offset % $finfo->{meta}{blocksize};
   128 	my $blockoffset = $offset % $finfo->{meta}{blocksize};
   129 
   129 
   130 	my $length = $finfo->{meta}{blocksize} - $blockoffset;
   130 	my $length = $finfo->{meta}{blocksize} - $blockoffset;
   131 	$length = $size if $size <= $length;
   131 	$length = $size if $size <= $length;
   132 
   132 
   133 	if (exists $CACHE{$finfo}{$block}) {
   133 	if (exists $DIRTY{$finfo}{$block}) {
   134 	    return substr $CACHE{$finfo}{$block}, $blockoffset, $length;
   134 	    return substr $DIRTY{$finfo}{$block}, $blockoffset, $length;
   135 	}
   135 	}
   136 
   136 
   137 	my $fn = "$DATA/" . $finfo->{blocklist}{$block};
   137 	my $fn = "$DATA/" . $finfo->{blocklist}{$block};
   138 	if (-e $fn) {
   138 	if (-e $fn) {
   139 		open(my $fh => $fn);
   139 		open(my $fh => $fn);
   157 
   157 
   158     sub writebuffer {
   158     sub writebuffer {
   159 	my $path = $IDX . shift;
   159 	my $path = $IDX . shift;
   160 	my ($buffer, $offset) = @_;
   160 	my ($buffer, $offset) = @_;
   161 	my $size = length($buffer);
   161 	my $size = length($buffer);
   162 	my $finfo = $FILE{$path} or die "File $path is not opened!";
   162 	my $finfo = $IMAGE{$path} or die "File $path is not opened!";
   163 
   163 
   164 	for (my $written = 0; $written < $size;) {
   164 	for (my $written = 0; $written < $size;) {
   165 	     # OPTIMIZE: we should not ask for writing more than the
   165 	     # OPTIMIZE: we should not ask for writing more than the
   166 	     # blocksize
   166 	     # blocksize
   167 	     my $n = _writeblock($finfo, substr($buffer, $written), $offset + $written) 
   167 	     my $n = _writeblock($finfo, substr($buffer, $written), $offset + $written) 
   176 	my $size = length($buffer);
   176 	my $size = length($buffer);
   177 
   177 
   178 	my $block = int($offset / $finfo->{meta}{blocksize});
   178 	my $block = int($offset / $finfo->{meta}{blocksize});
   179 	my $blockoffset = $offset % $finfo->{meta}{blocksize};
   179 	my $blockoffset = $offset % $finfo->{meta}{blocksize};
   180 
   180 
   181 	if (not exists $CACHE{$finfo}{$block}) {
   181 	if (not exists $DIRTY{$finfo}{$block}) {
   182 	    #open(my $fh => "$DATA/" . $finfo->{blocklist}{$block});
   182 	    $DIRTY{$finfo}{$block} = _readblock(
   183 	    #local $/ = undef;
   183 		    $finfo, 
   184 	    #$CACHE{$finfo}{$block} = <$fh>;
   184 		    $finfo->{meta}{blocksize}, 
   185 	    #close($fh);
   185 		    $block * $finfo->{meta}{blocksize});
   186 	    $CACHE{$finfo}{$block} = _readblock($finfo, $finfo->{meta}{blocksize}, $block * $finfo->{meta}{blocksize});
       
   187 	}
   186 	}
   188 
   187 
   189 	my $length = $finfo->{meta}{blocksize} - $blockoffset;
   188 	my $length = $finfo->{meta}{blocksize} - $blockoffset;
   190 	$length = $size if $size < $length;
   189 	$length = $size if $size < $length;
   191 
   190 
   192 	substr($CACHE{$finfo}{$block}, $blockoffset, $length)
   191 	substr($DIRTY{$finfo}{$block}, $blockoffset, $length)
   193 	    = substr($buffer, 0, $length);
   192 	    = substr($buffer, 0, $length);
   194 
   193 
   195 	return $length;
   194 	return $length;
   196     }
   195     }
   197 
   196