Nathan,
I mean when I downloaded the attachment it is hard for me to read it, it is something like following
is a bit messy code..
#!/usr/bin/perl -w # $Header: /cvsroot/lustre-tools/src/read-inodes,v 1.2 2011/03/16 00:04:17 jrappley Exp $ use strict; use File::Basename; use Getopt::Long; use Pod::Usage; use POSIX qw(ceil); use Fcntl 'SEEK_SET'; my $progname = basename $0; # Globals my $group = 0; my $inodesPerGroup = 0; my $inodeBlocksPerGroup = 0; my @usedInodes; my $freeIBlocks = 0; # Command line options my %arg; $arg
{verbose} = 0; sub dprint { if ($arg{verbose}
> 1)
{ print @_; }
} # Parse command line options Getopt::Long::Configure("bundling"); GetOptions( "h|help" => \$arg
{h}, "d|device=s" => \$arg{device}, "m|meta=s" => \$arg{meta}, "v|verbose+" => \$arg{verbose}, ) or pod2usage(-exitval => 2, -verbose => 1); pod2usage(1) if ($arg{h}
); pod2usage(1) if (scalar(@ARGV) Unable to render embedded object: File (= 0); pod2usage(1) if () not found. defined $arg
{meta}); if (defined $arg{device}) { open D, "<", "$arg{device}" or die "Couldn't open $arg{device}: $!"; } open M, "<", $arg{meta}
or die "Couldn't open $arg
{meta}
: $!"; while () { if (/Inodes per group:\s+(\d+)/)
{ $inodesPerGroup = $1; }
elsif (/Inode blocks per group:\s+(\d+)/)
{ $inodeBlocksPerGroup = $1; }
elsif (/^$/)
{ last; }
} if ($inodesPerGroup == 0 || $inodeBlocksPerGroup == 0)
{ print STDERR "Couldn't determine number of inodes per group, exiting\n"; exit 1; }
my $inodesPerBlock = $inodesPerGroup / $inodeBlocksPerGroup; my $firstItableBlock; while () { if (/^Group (\d+)/)
{ $group = $1; }
if (/Inode table at (\d+)/)
{ $firstItableBlock = $1; }
if (/(\d+) free inodes/)
{ $usedInodes[$group] = $inodesPerGroup - $1; }
if (/Free inodes:\s(.*)/) { # next if $group > 1; my @usedIBlocks; my $groupFreeIBlocks = 0; for my $i (0..$inodeBlocksPerGroup - 1)
{ $usedIBlocks[$i] = $inodesPerBlock; }
dprint "$group: ", join(" ", @usedIBlocks), "\n"; my @irange = split(/, /, $1); dprint "Group $group: ", join(" X ", @irange), "\n"; foreach my $range (@irange) { dprint "range: $range\n"; if ($range =~ /(\d+)-(\d+)/) { my $low = $1 - ($group * $inodesPerGroup); my $high = $2 - ($group * $inodesPerGroup); dprint "marking $low..$high\n"; for my $inum ($low..$high)
{ my $iBlock = ceil($inum / $inodesPerBlock) - 1; dprint "inum $inum block $iBlock\n"; $usedIBlocks[$iBlock]--; }
} else
{ my $inum = $range - ($group * $inodesPerGroup); my $iBlock = ceil($inum / $inodesPerBlock) - 1; dprint "marking $inum block $iBlock\n"; $usedIBlocks[$iBlock]--; }
} for my $i (0..$#usedIBlocks) { if ($usedIBlocks[$i] == 0) { $groupFreeIBlocks++; my $block = $firstItableBlock + $i; if (0)
{ dprint "group $group read ", $firstItableBlock + $i, "\n"; sysseek(D, $block * 4096, SEEK_SET); sysread(D, my $foo, 4096); }
} elsif (defined $arg
{device}
)
{ my $block = $firstItableBlock + $i; dprint "group $group read ", $firstItableBlock + $i, "\n"; sysseek(D, $block * 4096, SEEK_SET); sysread(D, my $foo, 4096); }
} $freeIBlocks += $groupFreeIBlocks; my @blockStr = map
{ sprintf "%3d", $_ }
@usedIBlocks; if ($arg
{verbose}
)
{ printf("%6d: %3d/%3d | %s\n", $group, $usedInodes[$group], $groupFreeIBlocks, join("", @blockStr)); }
} } print "Unused inode blocks: $freeIBlocks\n"; close M; _END_ =head1 NAME =head1 SYNOPSIS skeleton.pl [-h] =head1 DESCRIPTION =head1 OPTIONS =over 8 =item B<h|-help> Print a help message and exit. =back 8 =head1 EXAMPLES =head1 ENVIRONMENT =over 8 =item B FOO is an environment variable that somehow alters the execution of this program. =back 8 =head1 KNOWN BUGS =head1 CAVEATS =head1 DETAILS =head1 REPORTING BUGS =head1 AUTHOR =head1 SEE ALSO
Hi Jay Lan,
You could just ignore the 4 missing patches, and apply my patch directly, I build locally, it works.
Thanks,
Shilong