--- fuse-comp.pl 2007/07/10 02:57:03 29 +++ fuse-comp.pl 2007/09/02 11:38:59 38 @@ -10,7 +10,7 @@ use PerlIO::gzip; use File::Path; use Data::Dump qw/dump/; -use Carp qw/confess/; +use Carp qw/confess cluck/; use IO::File; use Getopt::Long; @@ -25,12 +25,14 @@ ); my $mount = { - from => '/tmp/comp', - to => '/tmp/no-comp', - tmp => '/dev/shm/comp', + from => shift @ARGV || '/tmp/comp', + to => shift @ARGV || '/tmp/no-comp', + tmp => shift @ARGV || '/dev/shm/comp', }; -my $skip_extensions_regex = qr/\.(?:sw[a-z]|gif|png|jpeg|jpg|avi|rar|zip|bz2|gz|tgz|avi|mpeg|mpg|tmp|temp)$/i; +warn "mount $mount->{from} to $mount->{to} using $mount->{tmp} as cache\n"; + +my $skip_extensions_regex = qr/gz|gz%|\.(?:sw[a-z]|gif|png|jpeg|jpg|avi|rar|zip|bz2|tgz|avi|mpeg|mpg|tmp|temp)$/i; # don't compress files smaller than this my $min_compress_size = 512; @@ -47,10 +49,14 @@ sub real_name { my ( $dir, $name ) = @_; if ( -e "$dir/${name}.gz" ) { - confess "ASSERT: unexpected $dir/$name exists" if -e "$dir/$name"; + cluck "ASSERT: unexpected $dir/$name exists" if -e "$dir/$name"; return "${name}.gz"; } - return $name; + if ( $name =~ m/\.gz$/ ) { + return $name . '%'; # protect (mingle) compressed files + } else { + return $name; + } } sub fixup { @@ -61,6 +67,7 @@ sub original_name { my $p = shift; $p =~ s/\.gz$//; + $p =~ s/\.gz%$/.gz/; # demungle compressed .gz files return $p; }; @@ -146,7 +153,7 @@ if ( -s $path ) { file_copy( '<:gzip', $path, '>', $tmp ) } else { - confess "ASSERT: filesystem corruption, $path is zero size\n"; + confess "ASSERT: filesystem corruption, $path is zero size in ",dump( $pending ); } $path = $tmp; $op = 'created'; @@ -155,7 +162,7 @@ confess "ASSERT: open shouldn't exist for $file in ", dump( $pending ) if defined( $pending->{$file}->{open} ); $pending->{$file}->{path} = $path; $pending->{$file}->{open} = 0; # not really opened, just uncompressed - warn "## tmp_file( $file ) $op $path [", -s $path, "]\n"; + warn "## tmp_file( $file ) $op $path [", -s $path, "]\n" if $debug; } return $path; } @@ -174,7 +181,7 @@ } elsif ( ! $path ) { $path = $pending_path; } elsif ( $pending_path ne $path ) { - confess "ASSERT: compressing into $path instead of $pending_path\n"; + confess "ASSERT: compressing into $path instead of $pending_path"; } } @@ -203,13 +210,21 @@ my ( $size_path, $size_comp ) = ( -s $path, -s $comp ); if ( $size_path <= $size_comp ) { - warn ">>> $size_path <= $size_comp leaving uncompressed\n"; + warn ">>> $size_path <= $size_comp leaving uncompressed $dest\n"; unlink $comp || confess "can't remove: $comp: $!"; + file_copy( '<', $path, '>', $dest ) if ( $path ne $dest ); } else { warn ">>> compressed $size_path -> $size_comp ",int(($size_comp * 100) / $size_path),"% $comp\n"; + # FIXME add timeout to remove uncompressed version? unlink $path || confess "can't remove $path: $!"; + + if ( -e $dest ) { + warn "## cleanup uncompressed $dest\n" if $debug; + unlink $dest || confess "can't remove $dest: $!"; + } } + } } @@ -241,17 +256,27 @@ warn "## open( $file, $mode ) pending: ", $pending->{$file}->{open}, " mode $mode: ", dump( $mode_desc )," $path [", -s $path, "]\n" if $debug; my $fh; + my $rv = 0; + + if ( ! -w $path ) { + my $old_mode = (stat $path)[2]; + my $new_mode = $old_mode | 0600; + chmod $new_mode, $path || confess "can't chmod $new_mode $path"; + warn "### modify mode $old_mode -> $new_mode for $path\n"; + $pending->{$file}->{mode} = $old_mode; + } if ( sysopen($fh , $path, $mode) ) { close($fh) || confess "can't close $path: $!"; warn "<<< sysopen $path [", -e $path ? -s $path : 'new' , "]\n"; $pending->{$file}->{open}++; - return 0; } else { warn "ERROR: can't open $path -- $!"; - return -$!; + $rv = -$!; } + return $rv; + } sub x_read { @@ -366,7 +391,7 @@ my $tmp = $mount->{tmp} . '/' . $old; if ( -e $tmp ) { if ( $new =~ m#\Q/.fuse_hidden\E# ) { - unlink $tmp || confess "can't unlink $tmp for $new\n"; + unlink $tmp || confess "can't unlink $tmp for $new"; } else { my $new_tmp = $mount->{tmp} . '/' . $new; rename $tmp, $new_tmp || confess "can't rename $tmp -> $new_tmp : $!"; @@ -454,7 +479,16 @@ $pending->{$file}->{open}--; if ( $pending->{$file}->{open} == 0 ) { - warn "## cleanup pending $file [", -s fixup($file), "]\n" if $debug; + + my $path = fixup( $file ); + + if ( my $old_mode = $pending->{$file}->{mode} ) { + chmod $old_mode, $path || confess "can't chmod $old_mode $path"; + warn "### restored mode $old_mode $path\n"; + + } + + warn "## cleanup pending $file [", -s $path, "]\n" if $debug; delete( $pending->{$file} ); }