Set the backup boot sector in ntfsresize when the size is reliable

Traditionally the backup boot sector is not set by ntfsresize because
the exact partition size is not yet known. A chkdsk is triggered to
subsequently insert it.
However ntfsresize is frequently activated by a partition editor which
has an exact knowledge of the wanted layout, and the backup boot sector
can be inserted by ntfsresize. This is only done if the target partition
size is defined with no unit suffix, and it is a multiple of the sector
size. Anyway the backup boot sector cannot overwrite useful data as it
is inserted between the file system size and the target partition size.
edge.strict_endians
Jean-Pierre André 2013-07-30 10:17:28 +02:00
parent 66cdec13d9
commit 9d730b0da1
1 changed files with 36 additions and 10 deletions

View File

@ -145,6 +145,7 @@ static struct {
int info;
int infombonly;
int expand;
int reliable_size;
int show_progress;
int badsectors;
int check;
@ -424,8 +425,10 @@ static s64 get_new_volume_size(char *s)
if (size <= 0 || errno == ERANGE)
err_exit("Illegal new volume size\n");
if (!*suffix)
if (!*suffix) {
opt.reliable_size = 1;
return size;
}
if (strlen(suffix) == 2 && suffix[1] == 'i')
prefix_kind = 1024;
@ -2570,20 +2573,24 @@ static int setup_lcn_bitmap(struct bitmap *bm, s64 nr_clusters)
*/
static void update_bootsector(ntfs_resize_t *r)
{
NTFS_BOOT_SECTOR bs;
s64 bs_size = sizeof(NTFS_BOOT_SECTOR);
NTFS_BOOT_SECTOR *bs;
ntfs_volume *vol = r->vol;
s64 bs_size = vol->sector_size;
printf("Updating Boot record ...\n");
bs = (NTFS_BOOT_SECTOR*)ntfs_malloc(vol->sector_size);
if (!bs)
perr_exit("ntfs_malloc");
if (vol->dev->d_ops->seek(vol->dev, 0, SEEK_SET) == (off_t)-1)
perr_exit("lseek");
if (vol->dev->d_ops->read(vol->dev, &bs, bs_size) == -1)
if (vol->dev->d_ops->read(vol->dev, bs, bs_size) == -1)
perr_exit("read() error");
bs.number_of_sectors = cpu_to_sle64(r->new_volume_size *
bs.bpb.sectors_per_cluster);
bs->number_of_sectors = cpu_to_sle64(r->new_volume_size *
bs->bpb.sectors_per_cluster);
if (r->mftmir_old) {
r->progress.flags |= NTFS_PROGBAR_SUPPRESS;
@ -2594,12 +2601,12 @@ static void update_bootsector(ntfs_resize_t *r)
else
copy_clusters(r, r->mftmir_rl.lcn, r->mftmir_old,
r->mftmir_rl.length);
bs.mftmirr_lcn = cpu_to_sle64(r->mftmir_rl.lcn);
bs->mftmirr_lcn = cpu_to_sle64(r->mftmir_rl.lcn);
r->progress.flags &= ~NTFS_PROGBAR_SUPPRESS;
}
/* Set the start of the relocated MFT */
if (r->new_mft_start) {
bs.mft_lcn = cpu_to_sle64(r->new_mft_start->lcn);
bs->mft_lcn = cpu_to_sle64(r->new_mft_start->lcn);
/* no more need for the new MFT start */
free(r->new_mft_start);
r->new_mft_start = (runlist_element*)NULL;
@ -2609,8 +2616,25 @@ static void update_bootsector(ntfs_resize_t *r)
perr_exit("lseek");
if (!opt.ro_flag)
if (vol->dev->d_ops->write(vol->dev, &bs, bs_size) == -1)
if (vol->dev->d_ops->write(vol->dev, bs, bs_size) == -1)
perr_exit("write() error");
/*
* Set the backup boot sector, if the target size is
* either not defined or is defined with no multiplier
* suffix and is a multiple of the sector size.
* With these conditions we can be confident enough that
* the partition size is already defined or it will be
* later defined with the same exact value.
*/
if (!opt.ro_flag && opt.reliable_size
&& !(opt.bytes % vol->sector_size)) {
if (vol->dev->d_ops->seek(vol->dev, opt.bytes
- vol->sector_size, SEEK_SET) == (off_t)-1)
perr_exit("lseek");
if (vol->dev->d_ops->write(vol->dev, bs, bs_size) == -1)
perr_exit("write() error");
}
free(bs);
}
/**
@ -4372,8 +4396,10 @@ int main(int argc, char **argv)
"size!\nCorrupt partition table or incorrect device "
"partitioning?\n");
if (!opt.bytes && !opt.info && !opt.infombonly)
if (!opt.bytes && !opt.info && !opt.infombonly) {
opt.bytes = device_size;
opt.reliable_size = 1;
}
/* Take the integer part: don't make the volume bigger than requested */
new_size = opt.bytes / vol->cluster_size;