summaryrefslogtreecommitdiffstats
path: root/perl-install/resize_fat
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/resize_fat')
-rw-r--r--perl-install/resize_fat/Makefile16
-rw-r--r--perl-install/resize_fat/README4
-rw-r--r--perl-install/resize_fat/any.pm95
-rw-r--r--perl-install/resize_fat/boot_sector.pm74
-rw-r--r--perl-install/resize_fat/c_rewritten.xs195
-rw-r--r--perl-install/resize_fat/dir_entry.pm27
-rw-r--r--perl-install/resize_fat/directory.pm43
-rw-r--r--perl-install/resize_fat/fat.pm85
-rw-r--r--perl-install/resize_fat/info_sector.pm15
-rw-r--r--perl-install/resize_fat/io.pm27
-rw-r--r--perl-install/resize_fat/main.pm139
11 files changed, 249 insertions, 471 deletions
diff --git a/perl-install/resize_fat/Makefile b/perl-install/resize_fat/Makefile
index a82ca8441..34c257a4e 100644
--- a/perl-install/resize_fat/Makefile
+++ b/perl-install/resize_fat/Makefile
@@ -1,10 +1,12 @@
-.PHONY: clean
+PRODUCT = libresize
+TARSOURCE = $(PRODUCT).tar.bz2
-c_rewritten: %: %.xs
- test -e Makefile_c || perl Makefile.PL
- $(MAKE) -f Makefile_c LD_RUN_PATH=
- rm -f ../auto/resize_fat ; ln -s ../resize_fat/blib/arch/auto ../auto/resize_fat
+.PHONY: clean tar
clean:
- test ! -e Makefile_c || $(MAKE) -f Makefile_c clean
- rm -f *~ *.o
+ rm -f *~ TAGS $(TARSOURCE)
+
+tar: clean
+ cp -f ../common.pm .
+ cd .. ; tar cfy $(TARSOURCE) $(PRODUCT) ; mv $(TARSOURCE) $(PRODUCT)
+ rm -f common.pm
diff --git a/perl-install/resize_fat/README b/perl-install/resize_fat/README
index 1c4798c82..2910c06c3 100644
--- a/perl-install/resize_fat/README
+++ b/perl-install/resize_fat/README
@@ -1,7 +1,5 @@
-TODO:
+just do ./resize.pm and look at usage.
-resize_fat::fat::update($fs) should be called before doing undoable things
-(before the sync in construct_dir_tree)
BUGS:
no known bugs :)
diff --git a/perl-install/resize_fat/any.pm b/perl-install/resize_fat/any.pm
index d06e2e755..d78a342be 100644
--- a/perl-install/resize_fat/any.pm
+++ b/perl-install/resize_fat/any.pm
@@ -2,78 +2,48 @@ package resize_fat::any;
use diagnostics;
use strict;
-use vars qw($FREE $FILE $DIRECTORY $UNMOVEABLE);
+use vars qw($FREE $FILE $DIRECTORY);
use common qw(:common :constant);
use resize_fat::fat;
use resize_fat::directory;
use resize_fat::dir_entry;
-use resize_fat::c_rewritten;
-$FREE = 0;
-$FILE = 1;
-$DIRECTORY = 2;
-$UNMOVEABLE = 8;
+$FREE = 0;
+$FILE = 1;
+$DIRECTORY = 2;
1;
-#- returns the number of clusters for a given filesystem type
+# returns the number of clusters for a given filesystem type
sub min_cluster_count($) {
my ($fs) = @_;
- (1 << $ {{ FAT16 => 12, FAT32 => 12 }}{$fs->{fs_type}}) - 12;
+ (1 << $ {{ FAT16 => 12, FAT32 => 16 }}{$fs->{fs_type}}) - 12;
}
sub max_cluster_count($) {
my ($fs) = @_;
- (1 << $ {{ FAT16 => 16, FAT32 => 28 }}{$fs->{fs_type}}) - 11;
+ $resize_fat::bad_cluster_value - 2;
}
-#- patch to get the function last_used that return the last used cluster of a fs.
-sub last_used($) {
- my ($fs) = @_;
-
- #- count in negative so absolute value count back to 2.
- foreach (-($fs->{nb_clusters}+1)..-2) { return -$_ if resize_fat::c_rewritten::flag(-$_) }
- die "any: empty FAT table of $fs->{nb_clusters} clusters";
-}
-#- patch to get the function last_unmoveable that return the last unmoveable cluster of a fs.
-sub last_unmoveable($) {
- my ($fs) = @_;
-
- #- count in negative so absolute value count back to 2.
- foreach (-($fs->{nb_clusters}+1)..-2) { return -$_ if 0x8 & resize_fat::c_rewritten::flag(-$_) }
-
- #- Oh at this point there are no unmoveable blocks!
- 2;
-}
-
-#- calculates the minimum size of a partition, in physical sectors
+# calculates the minimum size of a partition, in physical sectors
sub min_size($) {
my ($fs) = @_;
- my $count = $fs->{clusters}{count};
+ my $count = $fs->{clusters}->{count};
- #- directories are both in `used' and `dirs', so are counted twice
- #- It's done on purpose since we're moving all directories. So at the worse
- #- moment, 2 directories are there, but that way nothing wrong can happen :)
+ # directories are both in `used' and `dirs', so are counted twice
+ # It's done on purpose since we're moving all directories. So at the worse
+ # moment, 2 directories are there, but that way nothing wrong can happen :)
my $min_cluster_count = max(2 + $count->{used} + $count->{bad} + $count->{dirs}, min_cluster_count($fs));
- $min_cluster_count = max($min_cluster_count, last_unmoveable($fs));
-
- my $size = $min_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
- divide($fs->{cluster_offset}, $SECTORSIZE) +
- 64*1024*1024 / $SECTORSIZE; #- help with such more sectors (ie 64Mb).
-
- #- help zindozs again with 512Mb+ at least else partition is ignored.
- if ($resize_fat::isFAT32) {
- $size = max($size, 524*1024*1024 / $SECTORSIZE);
- }
- $size;
+ $min_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
+ divide($fs->{cluster_offset}, $SECTORSIZE);
}
-#- calculates the maximum size of a partition, in physical sectors
+# calculates the maximum size of a partition, in physical sectors
sub max_size($) {
my ($fs) = @_;
@@ -82,42 +52,31 @@ sub max_size($) {
$max_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
divide($fs->{cluster_offset}, $SECTORSIZE);
}
-#- calculates used size in order to avoid modifying anything.
-sub used_size($) {
- my ($fs) = @_;
-
- my $used_cluster_count = max(last_used($fs), min_cluster_count($fs));
-
- $used_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
- divide($fs->{cluster_offset}, $SECTORSIZE);
-}
-#- fills in fat_flag_map in c_rewritten.
-#- Each FAT entry is flagged as either FREE, FILE or DIRECTORY.
+# fills in $fs->{fat_flag_map}.
+# Each FAT entry is flagged as either FREE, FILE or DIRECTORY.
sub flag_clusters {
my ($fs) = @_;
- my ($cluster, $curr_dir_name, $entry, $type, $nb_dirs);
+ my ($cluster, $entry, $type);
my $f = sub {
- ($curr_dir_name, $entry) = @_;
+ ($entry) = @_;
$cluster = resize_fat::dir_entry::get_cluster($entry);
if (resize_fat::dir_entry::is_file($entry)) {
$type = $FILE;
- $type |= $UNMOVEABLE if resize_fat::dir_entry::is_unmoveable($entry);
} elsif (resize_fat::dir_entry::is_directory($entry)) {
$type = $DIRECTORY;
} else { return }
- my $nb = resize_fat::c_rewritten::checkFat($cluster, $type, "$curr_dir_name/$entry->{name}");
- print "resize_fat:flag_clusters: check fat returned $nb of type $type for $curr_dir_name/$entry->{name}\n";
- $nb_dirs += $nb if $type == $DIRECTORY;
- 0;
+ for (; !resize_fat::fat::is_eof($cluster); $cluster = resize_fat::fat::next($fs, $cluster)) {
+ $cluster == 0 and die "Bad FAT: unterminated chain for $entry->{name}\n";
+ $fs->{fat_flag_map}->[$cluster] and die "Bad FAT: cluster $cluster is cross-linked for $entry->{name}\n";
+ $fs->{fat_flag_map}->[$cluster] = $type;
+ $fs->{clusters}->{count}->{dirs}++ if $type == $DIRECTORY;
+ }
};
-
- #- this must call allocate_fat_flag that zeroes the buffer allocated.
- resize_fat::c_rewritten::allocate_fat_flag($fs->{nb_clusters} + 2);
-
+ $fs->{fat_flag_map} = [ ($FREE) x ($fs->{nb_clusters} + 2) ];
+ $fs->{clusters}->{count}->{dirs} = 0;
resize_fat::directory::traverse_all($fs, $f);
- $fs->{clusters}{count}{dirs} = $nb_dirs;
}
diff --git a/perl-install/resize_fat/boot_sector.pm b/perl-install/resize_fat/boot_sector.pm
index e7fa1c709..c236b1617 100644
--- a/perl-install/resize_fat/boot_sector.pm
+++ b/perl-install/resize_fat/boot_sector.pm
@@ -3,71 +3,67 @@ package resize_fat::boot_sector;
use diagnostics;
use strict;
-use common qw(:common :system :constant :functional);
+use common qw(:common :system :constant);
use resize_fat::io;
use resize_fat::any;
use resize_fat::directory;
-#- Oops, this will be unresizable on big-endian machine. trapped by signature.
my $format = "a3 a8 S C S C S S C S S S I I I S S I S S a458 S";
my @fields = (
- 'boot_jump', #- boot strap short or near jump
- 'system_id', #- Name - can be used to special case partition manager volumes
- 'sector_size', #- bytes per logical sector
- 'cluster_size_in_sectors', #- sectors/cluster
- 'nb_reserved', #- reserved sectors
- 'nb_fats', #- number of FATs
- 'nb_root_dir_entries', #- number of root directory entries
- 'small_nb_sectors', #- number of sectors: big_nb_sectors supersedes
- 'media', #- media code
- 'fat16_fat_length', #- sectors/FAT for FAT12/16
+ 'boot_jump', # boot strap short or near jump
+ 'system_id', # Name - can be used to special case partition manager volumes
+ 'sector_size', # bytes per logical sector
+ 'cluster_size_in_sectors', # sectors/cluster
+ 'nb_reserved', # reserved sectors
+ 'nb_fats', # number of FATs
+ 'nb_root_dir_entries', # number of root directory entries
+ 'small_nb_sectors', # number of sectors: big_nb_sectors supersedes
+ 'media', # media code
+ 'fat16_fat_length', # sectors/FAT for FAT12/16
'sectors_per_track',
'nb_heads',
- 'nb_hidden', #- (unused)
- 'big_nb_sectors', #- number of sectors (if small_nb_sectors == 0)
-
-#- FAT32-only entries
- 'fat32_fat_length', #- size of FAT in sectors
- 'fat32_flags', #- bit8: fat mirroring,
- #- low4: active fat
- 'fat32_version', #- minor * 256 + major
+ 'nb_hidden', # (unused)
+ 'big_nb_sectors', # number of sectors (if small_nb_sectors == 0)
+
+# FAT32-only entries
+ 'fat32_fat_length', # size of FAT in sectors
+ 'fat32_flags', # bit8: fat mirroring,
+ # low4: active fat
+ 'fat32_version', # minor * 256 + major
'fat32_root_dir_cluster',
'info_offset_in_sectors',
'fat32_backup_sector',
-#- Common again...
- 'boot_code', #- Boot code (or message)
- 'boot_sign', #- 0xAA55
+# Common again...
+ 'boot_code', # Boot code (or message)
+ 'boot_sign', # 0xAA55
);
1;
-#- trimfs_init_boot_sector() - reads in the boot sector - gets important info out
-#- of boot sector, and puts in main structure - performs sanity checks - returns 1
-#- on success, 0 on failureparameters: filesystem an empty structure to fill.
+# trimfs_init_boot_sector() - reads in the boot sector - gets important info out
+# of boot sector, and puts in main structure - performs sanity checks - returns 1
+# on success, 0 on failureparameters: filesystem an empty structure to fill.
sub read($) {
my ($fs) = @_;
-
+
my $boot = eval { resize_fat::io::read($fs, 0, $SECTORSIZE) }; $@ and die "reading boot sector failed on device $fs->{fs_name}";
@{$fs}{@fields} = unpack $format, $boot;
$fs->{nb_sectors} = $fs->{small_nb_sectors} || $fs->{big_nb_sectors};
- $fs->{cluster_size} = $fs->{cluster_size_in_sectors} * $fs->{sector_size};
+ $fs->{cluster_size} = $fs->{cluster_size_in_sectors} * $fs->{sector_size};
- $fs->{boot_sign} == 0xAA55 or die "Invalid signature for a MS-based filesystem.\n";
+ $fs->{boot_sign} == 0xAA55 or die "Invalid signature for a MS-based filesystem.";
+ $fs->{nb_fats} == 2 or die "Weird number of FATs: $fs->{nb_fats}, not 2.",
$fs->{nb_sectors} < 32 and die "Too few sectors for viable file system\n";
- $fs->{nb_fats} == 2 or cdie "Weird number of FATs: $fs->{nb_fats}, not 2.\n";
- $fs->{sector_size} == 512 or cdie "Strange sector_size != 512\n";
if ($fs->{fat16_fat_length}) {
- #- asserting FAT16, will be verified later on
- $resize_fat::isFAT32 = 0;
+ # asserting FAT16, will be verified later on
$fs->{fs_type} = 'FAT16';
$fs->{fs_type_size} = 16;
$fs->{fat_length} = $fs->{fat16_fat_length};
- $resize_fat::bad_cluster_value = 0xfff7; #- 2**16 - 1
} else {
$resize_fat::isFAT32 = 1;
$fs->{fs_type} = 'FAT32';
@@ -76,9 +72,9 @@ sub read($) {
$fs->{nb_root_dir_entries} = 0;
$fs->{info_offset} = $fs->{info_offset_in_sectors} * $fs->{sector_size};
- $resize_fat::bad_cluster_value = 0x0ffffff7;
}
-
+ $resize_fat::bad_cluster_value = (1 << $fs->{fs_type_size}) - 9;
+
$fs->{fat_offset} = $fs->{nb_reserved} * $fs->{sector_size};
$fs->{fat_size} = $fs->{fat_length} * $fs->{sector_size};
$fs->{root_dir_offset} = $fs->{fat_offset} + $fs->{fat_size} * $fs->{nb_fats};
@@ -87,12 +83,12 @@ sub read($) {
$fs->{nb_fat_entries} = divide($fs->{fat_size}, $fs->{fs_type_size} / 8);
- #- - 2 because clusters 0 & 1 doesn't exist
+ # - 2 because clusters 0 & 1 doesn't exist
$fs->{nb_clusters} = divide($fs->{nb_sectors} * $fs->{sector_size} - $fs->{cluster_offset}, $fs->{cluster_size}) - 2;
$fs->{dir_entries_per_cluster} = divide($fs->{cluster_size}, psizeof($format));
-#- $fs->{nb_clusters} >= resize_fat::any::min_cluster_count($fs) or die "error: not enough sectors for a $fs->{fs_type}\n";
+ $fs->{nb_clusters} >= resize_fat::any::min_cluster_count($fs) or die "error: not enough sectors for a $fs->{fs_type}\n";
$fs->{nb_clusters} < resize_fat::any::max_cluster_count($fs) or die "error: too many sectors for a $fs->{fs_type}\n";
}
@@ -103,7 +99,7 @@ sub write($) {
eval { resize_fat::io::write($fs, 0, $SECTORSIZE, $boot) }; $@ and die "writing the boot sector failed on device $fs->{fs_name}";
if ($resize_fat::isFAT32) {
- #- write backup
+ # write backup
eval { resize_fat::io::write($fs, $fs->{fat32_backup_sector} * $SECTORSIZE, $SECTORSIZE, $boot) };
$@ and die "writing the backup boot sector (#$fs->{fat32_backup_sector}) failed on device $fs->{fs_name}";
}
diff --git a/perl-install/resize_fat/c_rewritten.xs b/perl-install/resize_fat/c_rewritten.xs
index 92361097d..a42f3d133 100644
--- a/perl-install/resize_fat/c_rewritten.xs
+++ b/perl-install/resize_fat/c_rewritten.xs
@@ -4,105 +4,31 @@
/* set by scan_fat, used by next */
short *fat = NULL;
-char *fat_flag_map = NULL;
-unsigned int *fat_remap = NULL;
-int fat_remap_size;
int type_size, nb_clusters, bad_cluster_value;
-
-void free_all() {
-#define FREE(p) if (p) free(p), p = NULL;
- FREE(fat);
- FREE(fat_flag_map);
- FREE(fat_remap);
-#undef FREE
-}
+char *fat_flag_map;
unsigned int next(unsigned int cluster) {
short *p = fat + type_size * cluster;
- if (!fat) {
- free_all();
- croak("fat::next: trying to use null pointer");
- }
- if (cluster >= nb_clusters + 2) {
- free_all();
- croak("fat::next: cluster %d outside filesystem", cluster);
- }
+ if (cluster > nb_clusters + 2) croak("fat::next: cluster %d outside filesystem", cluster);
return type_size == 1 ? *p : *((unsigned int *) p);
}
-void set_next(unsigned int cluster, unsigned int val) {
- short *p = fat + type_size * cluster;
- if (!fat) {
- free_all();
- croak("fat::set_next: trying to use null pointer");
- }
- if (cluster >= nb_clusters + 2) {
- free_all();
- croak("fat::set_next: cluster %d outside filesystem", cluster);
- }
- type_size == 1 ? *p : *((unsigned int *) p) = val;
-}
-
MODULE = resize_fat::c_rewritten PACKAGE = resize_fat::c_rewritten
-void
-read_fat(fd, offset, size, magic)
- int fd
- int offset
- int size
- unsigned char magic
- PPCODE:
-{
- fat = (short *) malloc(size);
- if (!fat) {
- free_all();
- croak("read_fat: not enough memory");
- }
- if (lseek(fd, offset, SEEK_SET) != offset ||
- read(fd, fat, size) != size) {
- free_all();
- croak("read_fat: reading FAT failed");
- }
- if (magic != *(unsigned char *) fat) {
- free_all();
- croak("read_fat: FAT has invalid signature");
- }
-}
-
void
-write_fat(fd, size)
- int fd
- int size
- PPCODE:
-{
- if (write(fd, fat, size) != size) {
- free_all();
- croak("write_fat: write failed");
- }
-}
-
-void
-free_all()
- PPCODE:
- free_all();
-
-void
-scan_fat(nb_clusters_, type_size_)
+scan_fat(fat_, nb_clusters_, type_size_)
+ char *fat_
int nb_clusters_
int type_size_
PPCODE:
-{
unsigned int v;
int free = 0, bad = 0, used = 0;
short *p;
- type_size = type_size_; nb_clusters = nb_clusters_;
- bad_cluster_value = type_size == 32 ? 0x0ffffff7 : 0xfff7;
+ fat = (short*) fat_; type_size = type_size_; nb_clusters = nb_clusters_;
+ bad_cluster_value = type_size ? 0xffffff7 : 0xfff7;
- if (type_size % 16) {
- free_all();
- croak("scan_fat: unable to handle FAT%d", type_size);
- }
+ if (type_size % 16) fprintf(stderr, "unable to handle type_size"), exit(1);
type_size /= 16;
for (p = fat + 2 * type_size; p < fat + type_size * (nb_clusters + 2); p += type_size) {
@@ -116,7 +42,6 @@ scan_fat(nb_clusters_, type_size_)
PUSHs(sv_2mortal(newSViv(free)));
PUSHs(sv_2mortal(newSViv(bad)));
PUSHs(sv_2mortal(newSViv(used)));
-}
unsigned int
next(unused, cluster)
@@ -127,49 +52,20 @@ next(unused, cluster)
OUTPUT:
RETVAL
-void
-set_next(unused, cluster, val)
- void *unused
- unsigned int cluster
- unsigned int val
- CODE:
- set_next(cluster, val);
-
-void
-allocate_fat_flag(size)
- int size
- CODE:
- fat_flag_map = calloc(size, 1);
- if (!fat_flag_map) {
- free_all();
- croak("allocate_fat_flag: not enough memory");
- }
-
int
-checkFat(cluster, type, name)
+checkFat(fat_flag_map_, cluster, type, name)
+ char *fat_flag_map_
unsigned int cluster
int type
char *name
CODE:
int nb = 0;
+ fat_flag_map = fat_flag_map_;
- if (!fat_flag_map) {
- free_all();
- croak("Bad FAT: trying to use null pointer");
- }
for (; cluster < bad_cluster_value; cluster = next(cluster)) {
- if (cluster == 0) {
- free_all();
- croak("Bad FAT: unterminated chain for %s\n", name);
- }
- if (cluster >= nb_clusters + 2) {
- free_all();
- croak("Bad FAT: chain outside filesystem for %s\n", name);
- }
- if (fat_flag_map[cluster]) {
- free_all();
- croak("Bad FAT: cluster %d is cross-linked for %s\n", cluster, name);
- }
+ if (cluster == 0) croak("Bad FAT: unterminated chain for %s\n", name);
+
+ if (fat_flag_map[cluster]) croak("Bad FAT: cluster $cluster is cross-linked for %s\n", name);
fat_flag_map[cluster] = type;
nb++;
}
@@ -181,14 +77,6 @@ unsigned int
flag(cluster)
unsigned int cluster
CODE:
- if (!fat_flag_map) {
- free_all();
- croak("Bad FAT: trying to use null pointer");
- }
- if (cluster >= nb_clusters + 2) {
- free_all();
- croak("Bad FAT: going outside filesystem");
- }
RETVAL = fat_flag_map[cluster];
OUTPUT:
RETVAL
@@ -198,62 +86,5 @@ set_flag(cluster, flag)
unsigned int cluster
int flag
CODE:
- if (!fat_flag_map) {
- free_all();
- croak("Bad FAT: trying to use null pointer");
- }
- if (cluster >= nb_clusters + 2) {
- free_all();
- croak("Bad FAT: going outside filesystem");
- }
fat_flag_map[cluster] = flag;
-void
-allocate_fat_remap(size)
- int size
- CODE:
- fat_remap_size = size;
- fat_remap = (unsigned int *) calloc(size, sizeof(unsigned int *));
- if (!fat_remap) {
- free_all();
- croak("allocate_fat_remap: not enough memory");
- }
-
-unsigned int
-fat_remap(cluster)
- unsigned int cluster
- CODE:
- if (!fat_remap) {
- free_all();
- croak("fat_remap: trying to use null pointer");
- }
- if (cluster >= bad_cluster_value) {
- RETVAL = cluster; /* special cases */
- } else {
- if (cluster >= fat_remap_size) {
- free_all();
- croak("fat_remap: cluster %d >= %d in fat_remap", cluster, fat_remap_size);
- }
- RETVAL = fat_remap[cluster];
- }
- OUTPUT:
- RETVAL
-
-void
-set_fat_remap(cluster, val)
- unsigned int cluster
- unsigned int val
- CODE:
- if (!fat_remap) {
- free_all();
- croak("set_fat_remap: trying to use null pointer");
- }
- if (cluster >= fat_remap_size) {
- free_all();
- croak("set_fat_remap: cluster %d >= %d in set_fat_remap", cluster, fat_remap_size);
- }
- if (val < bad_cluster_value && val >= fat_remap_size) {
- free_all();
- croak("set_fat_remap: remapping cluster %d to cluster %d >= %d in set_fat_remap", cluster, val, fat_remap_size);
- }
- fat_remap[cluster] = val;
diff --git a/perl-install/resize_fat/dir_entry.pm b/perl-install/resize_fat/dir_entry.pm
index d944c04ac..fa5ebb344 100644
--- a/perl-install/resize_fat/dir_entry.pm
+++ b/perl-install/resize_fat/dir_entry.pm
@@ -5,10 +5,6 @@ use strict;
my $DELETED_FLAG = 0xe5;
-
-my $READ_ONLY_ATTR = 0x01;
-my $HIDDEN_ATTR = 0x02;
-my $SYSTEM_ATTR = 0x04;
my $VOLUME_LABEL_ATTR = 0x08;
my $VFAT_ATTR = 0x0f;
my $DIRECTORY_ATTR = 0x10;
@@ -17,7 +13,7 @@ my $DIRECTORY_ATTR = 0x10;
sub get_cluster($) {
my ($entry) = @_;
- $entry->{first_cluster} + ($resize_fat::isFAT32 ? $entry->{first_cluster_high} * (1 << 16) : 0);
+ $entry->{first_cluster} + ($resize_fat::isFAT32 ? $entry->{first_cluster_high} * 65536 : 0);
}
sub set_cluster($$) {
my ($entry, $val) = @_;
@@ -25,14 +21,14 @@ sub set_cluster($$) {
$entry->{first_cluster_high} = $val >> 16 if $resize_fat::isFAT32;
}
-sub is_unmoveable($) {
+sub is_directory_raw($) {
my ($entry) = @_;
- $entry->{attributes} & $HIDDEN_ATTR || $entry->{attributes} & $SYSTEM_ATTR;
+ !is_special_entry($entry) && $entry->{attributes} & $DIRECTORY_ATTR;
}
sub is_directory($) {
my ($entry) = @_;
- $entry->{attributes} & $DIRECTORY_ATTR && $entry->{name} !~ /^\.\.? / && !is_special_entry($entry);
+ is_directory_raw($entry) && $entry->{name} !~ /^\.\.? /;
}
sub is_volume($) {
@@ -50,7 +46,7 @@ sub is_special_entry($) {
my ($entry) = @_;
my ($c) = unpack "C", $entry->{name};
- #- skip empty slots, deleted files, and 0xF6?? (taken from kernel)
+ # skip empty slots, deleted files, and 0xF6?? (taken from kernel)
$c == 0 || $c == $DELETED_FLAG || $c == 0xF6 and return 1;
$entry->{attributes} == $VFAT_ATTR and return 1;
@@ -58,19 +54,18 @@ sub is_special_entry($) {
}
-#- return true if entry has been modified
-#- curr_dir_name is added to contains current directory name, "" for root.
+# return true if entry has been modified
sub remap {
- my ($curr_dir_name, $entry) = @_;
-
+ my ($fat_remap, $entry) = @_;
+
is_special_entry($entry) and return;
my $cluster = get_cluster($entry);
- my $new_cluster = resize_fat::c_rewritten::fat_remap($cluster);
+ my $new_cluster = $fat_remap->[$cluster];
- #-print "remapping cluster ", get_cluster($entry), " to $new_cluster";
+ #print "remapping cluster ", get_first_cluster($fs, $entry), " to $new_cluster";
- $new_cluster == $cluster and return; #- no need to modify
+ $new_cluster == $cluster and return; # no need to modify
set_cluster($entry, $new_cluster);
1;
diff --git a/perl-install/resize_fat/directory.pm b/perl-install/resize_fat/directory.pm
index 1bc1014c6..ab8ec5328 100644
--- a/perl-install/resize_fat/directory.pm
+++ b/perl-install/resize_fat/directory.pm
@@ -14,36 +14,35 @@ my @fields = (
'extension',
'attributes',
'is_upper_case_name',
- 'creation_time_low', #- milliseconds
+ 'creation_time_low', # milliseconds
'creation_time_high',
'creation_date',
'access_date',
- 'first_cluster_high', #- for FAT32
+ 'first_cluster_high', # for FAT32
'time',
'date',
'first_cluster',
'length',
);
-my $psizeof_format = psizeof($format);
1;
-sub entry_size { $psizeof_format }
+sub entry_size { psizeof($format) }
-#- call `f' for each entry of the directory
-#- if f return true, then modification in the entry are taken back
+# call `f' for each entry of the directory
+# if f return true, then modification in the entry are taken back
sub traverse($$$) {
- my ($directory, $curr_dir_name, $f) = @_;
+ my ($fs, $directory, $f) = @_;
- for (my $i = 0;; $i++) {
- my $raw = \substr($directory, $i * $psizeof_format, $psizeof_format);
+ for (my $i = 0; 1; $i++) {
+ my $raw = \substr($directory, $i * psizeof($format), psizeof($format));
- #- empty entry means end of directory
+ # empty entry means end of directory
$$raw =~ /^\0*$/ and return $directory;
my $entry; @{$entry}{@fields} = unpack $format, $$raw;
- &$f($curr_dir_name, $entry)
+ &$f($entry)
and $$raw = pack $format, @{$entry}{@fields};
}
$directory;
@@ -53,27 +52,27 @@ sub traverse_all($$) {
my ($fs, $f) = @_;
my $traverse_all; $traverse_all = sub {
- my ($curr_dir_name, $entry) = @_;
+ my ($entry) = @_;
- &$f($curr_dir_name, $entry);
+ &$f($entry);
- resize_fat::dir_entry::is_directory($entry)
- and traverse(resize_fat::io::read_file($fs, resize_fat::dir_entry::get_cluster($entry)), "$curr_dir_name/$entry->{name}", $traverse_all);
+ resize_fat::dir_entry::is_directory($entry)
+ and traverse($fs, resize_fat::io::read_file($fs, resize_fat::dir_entry::get_cluster($entry)), $traverse_all);
- undef; #- no need to write back (cf traverse)
+ undef; # no need to write back (cf traverse)
};
my $directory = $resize_fat::isFAT32 ?
resize_fat::io::read_file($fs, $fs->{fat32_root_dir_cluster}) :
resize_fat::io::read($fs, $fs->{root_dir_offset}, $fs->{root_dir_size});
- traverse($directory, "", $traverse_all);
- undef $traverse_all; #- circular reference is no good for perl's poor GC :(
+ traverse($fs, $directory, $traverse_all);
}
-#- function used by construct_dir_tree to translate the `cluster' fields in each
-#- directory entry
-sub remap($$) {
+# function used by construct_dir_tree to translate the `cluster' fields in each
+# directory entry
+sub remap {
my ($fs, $directory) = @_;
- traverse($directory, "", \&resize_fat::dir_entry::remap);
+
+ traverse($fs->{fat_remap}, $directory, sub { resize_fat::dir_entry::remap($fs->{fat_remap}, $_[0]) });
}
diff --git a/perl-install/resize_fat/fat.pm b/perl-install/resize_fat/fat.pm
index 0d8a32dfa..2b64bd6f7 100644
--- a/perl-install/resize_fat/fat.pm
+++ b/perl-install/resize_fat/fat.pm
@@ -5,17 +5,30 @@ use strict;
use resize_fat::any;
use resize_fat::io;
-use resize_fat::c_rewritten;
1;
sub read($) {
my ($fs) = @_;
- resize_fat::c_rewritten::read_fat(fileno $fs->{fd}, $fs->{fat_offset}, $fs->{fat_size}, $fs->{media});
+ @{$fs->{fats}} = map {
+ my $fat = eval { resize_fat::io::read($fs, $fs->{fat_offset} + $_ * $fs->{fat_size}, $fs->{fat_size}) };
+ $@ and die "reading fat #$_ failed";
+ vec($fat, 0, 8) == $fs->{media} or die "FAT $_ has invalid signature";
+ $fat;
+ } (0 .. $fs->{nb_fats} - 1);
- @{$fs->{clusters}{count}}{qw(free bad used)} =
- resize_fat::c_rewritten::scan_fat($fs->{nb_clusters}, $fs->{fs_type_size});
+ $fs->{fat} = $fs->{fats}->[0];
+
+ my ($free, $bad, $used) = (0, 0, 0);
+
+ for (my $i = 2; $i < $fs->{nb_clusters} + 2; $i++) {
+ my $cluster = &next($fs, $i);
+ if ($cluster == 0) { $free++; }
+ elsif ($cluster == $resize_fat::bad_cluster_value) { $bad++; }
+ else { $used++; }
+ }
+ @{$fs->{clusters}->{count}}{qw(free bad used)} = ($free, $bad, $used);
}
sub write($) {
@@ -23,34 +36,32 @@ sub write($) {
sysseek $fs->{fd}, $fs->{fat_offset}, 0 or die "write_fat: seek failed";
foreach (1..$fs->{nb_fats}) {
- resize_fat::c_rewritten::write_fat(fileno $fs->{fd}, $fs->{fat_size});
+ syswrite $fs->{fd}, $fs->{fat}, $fs->{fat_size} or die "write_fat: write failed";
}
}
-#- allocates where all the clusters will be moved to. Clusters before cut_point
-#- remain in the same position, however cluster that are part of a directory are
-#- moved regardless (this is a mechanism to prevent data loss) (cut_point is the
-#- first cluster that won't occur in the new fs)
+# allocates where all the clusters will be moved to. Clusters before cut_point
+# remain in the same position, however cluster that are part of a directory are
+# moved regardless (this is a mechanism to prevent data loss) (cut_point is the
+# first cluster that won't occur in the new fs)
sub allocate_remap {
my ($fs, $cut_point) = @_;
my ($cluster, $new_cluster);
- my $remap = sub { resize_fat::c_rewritten::set_fat_remap($cluster, $new_cluster) };
+ my $remap = sub { $fs->{fat_remap}->[$cluster] = $new_cluster; };
my $get_new = sub {
$new_cluster = get_free($fs);
0 < $new_cluster && $new_cluster < $cut_point or die "no free clusters";
- set_eof($fs, $new_cluster); #- mark as used
- #-log::ld("resize_fat: [$cluster,", &next($fs, $cluster), "...]->$new_cluster...");
+ set_eof($fs, $new_cluster); # mark as used
+ #log::ld("resize_fat: [$cluster,", &next($fs, $cluster), "...]->$new_cluster...");
};
- #- this must call allocate_fat_remap that zeroes the buffer allocated.
- resize_fat::c_rewritten::allocate_fat_remap($fs->{nb_clusters} + 2);
-
+ $fs->{fat_remap}->[0] = 0;
$fs->{last_free_cluster} = 2;
for ($cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
if ($cluster < $cut_point) {
- if (resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::DIRECTORY) {
+ if ($fs->{fat_flag_map}->[$cluster] == $resize_fat::any::DIRECTORY) {
&$get_new();
} else {
$new_cluster = $cluster;
@@ -64,26 +75,36 @@ sub allocate_remap {
}
-#- updates the fat for the resized filesystem
+# updates the fat for the resized filesystem
sub update {
my ($fs) = @_;
for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- if (resize_fat::c_rewritten::flag($cluster)) {
+ if ($fs->{fat_flag_map}->[$cluster]) {
my $old_next = &next($fs, $cluster);
- my $new = resize_fat::c_rewritten::fat_remap($cluster);
- my $new_next = resize_fat::c_rewritten::fat_remap($old_next);
+ my $new = $fs->{fat_remap}->[$cluster];
+ my $new_next = $fs->{fat_remap}->[$old_next];
set_available($fs, $cluster);
is_eof($old_next) ?
set_eof($fs, $new) :
- set_next ($fs, $new, $new_next);
+ set_next($fs, $new, $new_next);
}
}
}
+# - compares the two FATs (one's a backup that should match) - skips first entry
+# - its just a signature (already checked above) NOTE: checks for cross-linking
+# are done in count.c
+sub check($) {
+ my ($fs) = @_;
+ foreach (@{$fs->{fats}}) {
+ $_ eq $fs->{fats}->[0] or die "FAT tables do not match";
+ }
+}
+
sub endianness16($) { (($_[0] & 0xff) << 8) + ($_[0] >> 8); }
sub endianness($$) {
my ($val, $nb_bits) = @_;
@@ -97,9 +118,17 @@ sub endianness($$) {
$r;
}
-*next = \&resize_fat::c_rewritten::next;
-*set_next = \&resize_fat::c_rewritten::set_next;
+sub next($$) {
+ my ($fs, $cluster) = @_;
+ $cluster > $fs->{nb_clusters} + 2 and die "fat::next: cluster $cluster outside filesystem";
+ endianness(vec($fs->{fat}, $cluster, $fs->{fs_type_size}), $fs->{fs_type_size});
+}
+sub set_next($$$) {
+ my ($fs, $cluster, $new_v) = @_;
+ $cluster > $fs->{nb_clusters} + 2 and die "fat::set_next: cluster $cluster outside filesystem";
+ vec($fs->{fat}, $cluster, $fs->{fs_type_size}) = endianness($new_v, $fs->{fs_type_size});
+}
sub get_free($) {
@@ -111,28 +140,28 @@ sub get_free($) {
die "no free clusters";
}
-#- returns true if <cluster> represents an EOF marker
+# returns true if <cluster> represents an EOF marker
sub is_eof($) {
my ($cluster) = @_;
$cluster >= $resize_fat::bad_cluster_value;
}
sub set_eof($$) {
my ($fs, $cluster) = @_;
- set_next ($fs, $cluster, $resize_fat::bad_cluster_value + 1);
+ set_next($fs, $cluster, $resize_fat::bad_cluster_value + 1);
}
-#- returns true if <cluster> is empty. Note that this includes bad clusters.
+# returns true if <cluster> is empty. Note that this includes bad clusters.
sub is_empty($) {
my ($cluster) = @_;
$cluster == 0 || $cluster == $resize_fat::bad_cluster_value;
}
-#- returns true if <cluster> is available.
+# returns true if <cluster> is available.
sub is_available($) {
my ($cluster) = @_;
$cluster == 0;
}
sub set_available($$) {
my ($fs, $cluster) = @_;
- set_next ($fs, $cluster, 0);
+ set_next($fs, $cluster, 0);
}
diff --git a/perl-install/resize_fat/info_sector.pm b/perl-install/resize_fat/info_sector.pm
index dc459ef6c..c46ae15fc 100644
--- a/perl-install/resize_fat/info_sector.pm
+++ b/perl-install/resize_fat/info_sector.pm
@@ -6,13 +6,12 @@ use strict;
use common qw(:system);
use resize_fat::io;
-#- Oops, this will be unresizable on big-endian machine. trapped by signature.
my $format = "a484 I I I a16";
my @fields = (
'unused',
- 'signature', #- should be 0x61417272
- 'free_clusters', #- -1 for unknown
- 'next_cluster', #- most recently allocated cluster
+ 'signature', # should be 0x61417272
+ 'free_clusters', # -1 for unknown
+ 'next_cluster', # most recently allocated cluster
'unused2',
);
@@ -21,15 +20,15 @@ my @fields = (
sub read($) {
my ($fs) = @_;
- my $info = resize_fat::io::read($fs, $fs->{info_offset}, psizeof($format));
+ my $info = resize_fat::io::read($fs, $fs->{offset}, psizeof($format));
@{$fs->{info_sector}}{@fields} = unpack $format, $info;
- $fs->{info_sector}{signature} == 0x61417272 or die "Invalid information sector signature\n";
+ $fs->{info_sector}->{signature} == 0x61417272 or die "Invalid information sector signature\n";
}
sub write($) {
my ($fs) = @_;
- $fs->{info_sector}{free_clusters} = $fs->{clusters}->{count}->{free};
- $fs->{info_sector}{next_cluster} = 2;
+ $fs->{info_sector}->{free_clusters} = $fs->{clusters}->{count}->{free};
+ $fs->{info_sector}->{next_cluster} = 2;
my $info = pack $format, @{$fs->{info_sector}}{@fields};
diff --git a/perl-install/resize_fat/io.pm b/perl-install/resize_fat/io.pm
index 6543f9118..8ffaa8355 100644
--- a/perl-install/resize_fat/io.pm
+++ b/perl-install/resize_fat/io.pm
@@ -4,15 +4,13 @@ use diagnostics;
use strict;
use resize_fat::fat;
-use c;
1;
sub read($$$) {
my ($fs, $pos, $size) = @_;
- print "reading $size bytes at $pos\n";
- my $buf = "\0" x $size;
+ my $buf;
sysseek $fs->{fd}, $pos, 0 or die "seeking to byte #$pos failed on device $fs->{fs_name}";
sysread $fs->{fd}, $buf, $size or die "reading at byte #$pos failed on device $fs->{fs_name}";
$buf;
@@ -20,31 +18,36 @@ sub read($$$) {
sub write($$$$) {
my ($fs, $pos, $size, $buf) = @_;
sysseek $fs->{fd}, $pos, 0 or die "seeking to byte #$pos failed on device $fs->{fs_name}";
- syswrite $fs->{fd}, $buf or die "writing at byte #$pos failed on device $fs->{fs_name}";
+ syswrite $fs->{fd}, $buf, $size or die "writing at byte #$pos failed on device $fs->{fs_name}";
}
sub read_cluster($$) {
my ($fs, $cluster) = @_;
my $buf;
- my $pos = $fs->{cluster_offset} / 512 + $cluster * ($fs->{cluster_size} / 512);
- c::lseek_sector(fileno $fs->{fd}, $pos, 0) or die "seeking to sector #$pos failed on device $fs->{fs_name}";
- sysread $fs->{fd}, $buf, $fs->{cluster_size} or die "reading at sector #$pos failed on device $fs->{fs_name}";
+ eval {
+ $buf = &read($fs,
+ $fs->{cluster_offset} + $cluster * $fs->{cluster_size},
+ $fs->{cluster_size});
+ }; @$ and die "reading cluster #$cluster failed on device $fs->{fs_name}";
$buf;
}
sub write_cluster($$$) {
my ($fs, $cluster, $buf) = @_;
- my $pos = $fs->{cluster_offset} / 512 + $cluster * ($fs->{cluster_size} / 512);
- c::lseek_sector(fileno $fs->{fd}, $pos, 0) or die "seeking to sector #$pos failed on device $fs->{fs_name}";
- syswrite $fs->{fd}, $buf or die "writing at sector #$pos failed on device $fs->{fs_name}";
+ eval {
+ &write($fs,
+ $fs->{cluster_offset} + $cluster * $fs->{cluster_size},
+ $fs->{cluster_size},
+ $buf);
+ }; @$ and die "writing cluster #$cluster failed on device $fs->{fs_name}";
}
sub read_file($$) {
my ($fs, $cluster) = @_;
my $buf = '';
- for (; !resize_fat::fat::is_eof($cluster); $cluster = resize_fat::fat::next ($fs, $cluster)) {
+ for (; !resize_fat::fat::is_eof($cluster); $cluster = resize_fat::fat::next($fs, $cluster)) {
$cluster == 0 and die "Bad FAT: unterminated chain\n";
$buf .= read_cluster($fs, $cluster);
}
@@ -67,5 +70,5 @@ sub open($) {
check_mounted($fs->{device});
sysopen F, $fs->{fs_name}, 2 or sysopen F, $fs->{fs_name}, 0 or die "error opening device $fs->{fs_name} for writing\n";
- $fs->{fd} = *F;
+ $fs->{fd} = \*F;
}
diff --git a/perl-install/resize_fat/main.pm b/perl-install/resize_fat/main.pm
index 256031228..2d5f4f969 100644
--- a/perl-install/resize_fat/main.pm
+++ b/perl-install/resize_fat/main.pm
@@ -1,24 +1,5 @@
#!/usr/bin/perl
-# DiskDrake
-# Copyright (C) 1999 MandrakeSoft (pixel@linux-mandrake.com)
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# This is mainly a perl rewrite of the work of Andrew Clausen (libresize)
-
package resize_fat::main;
use diagnostics;
@@ -34,86 +15,79 @@ use resize_fat::fat;
use resize_fat::any;
+#@ARGV == 2 or die "usage: fatresize <device> <size>\n <size> = 100 means `resize to 100Mb'\n <size> = +10 means `keep 10Mb of free space'\n";
+#
+#my $fs = init($ARGV[0]);
+#resize($fs, $ARGV[1]);
+
1;
-#- - reads in the boot sector/partition info., and tries to make some sense of it
+# - reads in the boot sector/partition info., and tries to make some sense of it
sub new($$$) {
my ($type, $device, $fs_name) = @_;
my $fs = { device => $device, fs_name => $fs_name } ;
- eval {
- resize_fat::io::open($fs);
- resize_fat::boot_sector::read($fs);
- $resize_fat::isFAT32 and eval { resize_fat::info_sector::read($fs) };
- resize_fat::fat::read($fs);
- resize_fat::any::flag_clusters($fs);
- };
- if ($@) {
- close $fs->{fd};
- die;
- }
- bless $fs, $type;
-}
+ resize_fat::io::open($fs);
+ resize_fat::boot_sector::read($fs);
+ $resize_fat::isFAT32 and eval { resize_fat::info_sector::read($fs) };
+ resize_fat::fat::read($fs);
+ resize_fat::fat::check($fs);
+ resize_fat::any::flag_clusters($fs);
-sub DESTROY {
- my ($fs) = @_;
- close $fs->{fd};
- resize_fat::c_rewritten::free_all();
+ bless $fs, $type;
}
-#- copy all clusters >= <start_cluster> to a new place on the partition, less
-#- than <start_cluster>. Only copies files, not directories.
-#- (use of buffer needed because the seeks slow like hell the hard drive)
+# copy all clusters >= <start_cluster> to a new place on the partition, less
+# than <start_cluster>. Only copies files, not directories.
+# (use of buffer needed because the seeks slow like hell the hard drive)
sub copy_clusters {
my ($fs, $cluster) = @_;
my @buffer;
- my $flush = sub {
- while (@buffer) {
+ my $flush = sub {
+ while (@buffer) {
my $cluster = shift @buffer;
resize_fat::io::write_cluster($fs, $cluster, shift @buffer);
}
};
for (; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::FILE or next;
- push @buffer,
- resize_fat::c_rewritten::fat_remap($cluster),
- resize_fat::io::read_cluster($fs, $cluster);
+ $fs->{fat_flag_map}->[$cluster] == $resize_fat::any::FILE or next;
+ push @buffer, $fs->{fat_remap}->[$cluster], resize_fat::io::read_cluster($fs, $cluster);
@buffer > 50 and &$flush();
}
&$flush();
}
-#- Constructs the new directory tree to match the new file locations.
+# Constructs the new directory tree to match the new file locations.
sub construct_dir_tree {
my ($fs) = @_;
- if ($resize_fat::isFAT32) {
- #- fat32's root must remain in the first 64k clusters
- #- so don't set it as DIRECTORY, it will be specially handled
- resize_fat::c_rewritten::set_flag($fs->{fat32_root_dir_cluster}, $resize_fat::any::FREE);
+ if ($resize_fat::isFAT32) {
+ # fat32's root must remain in the first 64k clusters
+ # so don't set it as DIRECTORY, it will be specially handled
+ $fs->{fat_flag_map}->[$fs->{fat32_root_dir_cluster}] = $resize_fat::any::FREE;
}
for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::DIRECTORY or next;
+ $fs->{fat_flag_map}->[$cluster] == $resize_fat::any::DIRECTORY or next;
- resize_fat::io::write_cluster($fs,
- resize_fat::c_rewritten::fat_remap($cluster),
- resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
+ resize_fat::io::write_cluster($fs,
+ $fs->{fat_remap}->[$cluster],
+ resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
}
sync();
- #- until now, only free clusters have been written. it's a null operation if we stop here.
- #- it means no corruption :)
+ # until now, only free clusters have been written. it's a null operation if we stop here.
+ # it means no corruption :)
#
- #- now we must be as fast as possible!
+ # now we must be as fast as possible!
- #- remapping non movable root directory
+ # remapping non movable root directory
if ($resize_fat::isFAT32) {
my $cluster = $fs->{fat32_root_dir_cluster};
- resize_fat::io::write_cluster($fs,
- resize_fat::c_rewritten::fat_remap($cluster),
+ resize_fat::io::write_cluster($fs,
+ $fs->{fat_remap}->[$cluster],
resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
} else {
resize_fat::io::write($fs, $fs->{root_dir_offset}, $fs->{root_dir_size},
@@ -123,50 +97,44 @@ sub construct_dir_tree {
sub min_size($) { &resize_fat::any::min_size }
sub max_size($) { &resize_fat::any::max_size }
-sub used_size($) { &resize_fat::any::used_size }
-#- resize
-#- - size is in sectors
-#- - checks boundaries before starting
-#- - copies all data beyond new_cluster_count behind the frontier
+# resize
+# - size is in sectors
+# - checks boundaries before starting
+# - copies all data beyond new_cluster_count behind the frontier
sub resize {
my ($fs, $size) = @_;
my ($min, $max) = (min_size($fs), max_size($fs));
+
$size += $min if $size =~ /^\+/;
$size >= $min or die "Minimum filesystem size is $min sectors";
$size <= $max or die "Maximum filesystem size is $max sectors";
- log::l("resize_fat: Partition size will be ". ($size * $SECTORSIZE >> 20) ."Mb (well exactly ${size} sectors)");
+ log::l("resize_fat: Partition size fill be ", $size * $SECTORSIZE >> 20, "Mb (well exactly ${size} sectors)");
my $new_data_size = $size * $SECTORSIZE - $fs->{cluster_offset};
my $new_nb_clusters = divide($new_data_size, $fs->{cluster_size});
- my $used_size = used_size($fs);
- log::l("resize_fat: Break point for moving files is ". ($used_size * $SECTORSIZE >> 20) ." Mb ($used_size sectors)");
- if ($size < $used_size) {
- log::l("resize_fat: Allocating new clusters");
- resize_fat::fat::allocate_remap($fs, $new_nb_clusters);
+ log::l("resize_fat: Allocating new clusters");
+ resize_fat::fat::allocate_remap($fs, $new_nb_clusters);
- log::l("resize_fat: Copying files");
- copy_clusters($fs, $new_nb_clusters);
+ log::l("resize_fat: Copying files");
+ copy_clusters($fs, $new_nb_clusters);
- log::l("resize_fat: Copying directories");
- construct_dir_tree($fs);
+ log::l("resize_fat: Copying directories");
+ construct_dir_tree($fs);
- log::l("Writing new FAT...");
- resize_fat::fat::update($fs);
- resize_fat::fat::write($fs);
- } else {
- log::l("resize_fat: Nothing need to be moved");
- }
+ log::l("Writing new FAT...");
+ resize_fat::fat::update($fs);
+ resize_fat::fat::write($fs);
$fs->{nb_sectors} = $size;
$fs->{nb_clusters} = $new_nb_clusters;
- $fs->{clusters}{count}->{free} =
- $fs->{nb_clusters} - $fs->{clusters}{count}->{used} - $fs->{clusters}->{count}->{bad} - 2;
+ $fs->{clusters}->{count}->{free} =
+ $fs->{nb_clusters} - $fs->{clusters}->{count}->{used} - $fs->{clusters}->{count}->{bad};
$fs->{system_id} = 'was here!';
$fs->{small_nb_sectors} = 0;
@@ -176,10 +144,9 @@ sub resize {
resize_fat::boot_sector::write($fs);
- $resize_fat::isFAT32 and eval { resize_fat::info_sector::write($fs) }; #- doesn't matter if this fails - its pretty useless!
+ $resize_fat::isFAT32 and eval { resize_fat::info_sector::write($fs) }; # doesn't matter if this fails - its pretty useless!
sync();
- close $fs->{fd};
log::l("resize_fat: done");
}