Fix mkntfs for large volumes where the number of clusters would
exceed the maximum of 32 bits and mkntfs would segfault. Now we increase the cluster size until the number of clusters no longer exceeds 32 bits or the maximum cluster size is reached. We then exit with an appropriate error message. (Thanks to Szaka for the bug report.) Also fix some compiler warnings in mkntfs with --enable-maintainer-mode. (Logical change 1.291)edge.strict_endians
parent
743f2c3632
commit
852af74c58
|
@ -205,7 +205,7 @@ struct {
|
|||
/**
|
||||
* Dprintf - debugging output (-vv); overriden by quiet (-q)
|
||||
*/
|
||||
void Dprintf(const char *fmt, ...)
|
||||
static void Dprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
@ -220,6 +220,7 @@ void Dprintf(const char *fmt, ...)
|
|||
/**
|
||||
* Eprintf - error output; ignores quiet (-q)
|
||||
*/
|
||||
void Eprintf(const char *fmt, ...);
|
||||
void Eprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -239,7 +240,7 @@ GEN_PRINTF(Qprintf, stdout, &opts.quiet, FALSE)
|
|||
/**
|
||||
* err_exit - error output and terminate; ignores quiet (-q)
|
||||
*/
|
||||
void err_exit(const char *fmt, ...)
|
||||
static void err_exit(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
@ -255,7 +256,7 @@ void err_exit(const char *fmt, ...)
|
|||
/**
|
||||
* copyright - print copyright statements
|
||||
*/
|
||||
void copyright(void)
|
||||
static void copyright(void)
|
||||
{
|
||||
fprintf(stderr, "Copyright (c) 2000-2003 Anton Altaparmakov\n"
|
||||
"Copyright (c) 2001-2003 Richard Russon\n"
|
||||
|
@ -266,7 +267,7 @@ void copyright(void)
|
|||
/**
|
||||
* license - print license statement
|
||||
*/
|
||||
void license(void)
|
||||
static void license(void)
|
||||
{
|
||||
fprintf(stderr, "%s", ntfs_gpl);
|
||||
}
|
||||
|
@ -274,8 +275,8 @@ void license(void)
|
|||
/**
|
||||
* usage - print a list of the parameters to the program
|
||||
*/
|
||||
void usage(void) __attribute__ ((noreturn));
|
||||
void usage(void)
|
||||
static void usage(void) __attribute__ ((noreturn));
|
||||
static void usage(void)
|
||||
{
|
||||
copyright();
|
||||
fprintf(stderr, "Usage: %s [options] device "
|
||||
|
@ -312,7 +313,7 @@ void usage(void)
|
|||
/**
|
||||
* parse_options
|
||||
*/
|
||||
void parse_options(int argc, char *argv[])
|
||||
static void parse_options(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
long l;
|
||||
|
@ -398,7 +399,7 @@ void parse_options(int argc, char *argv[])
|
|||
/**
|
||||
* append_to_bad_blocks
|
||||
*/
|
||||
void append_to_bad_blocks(unsigned long block)
|
||||
static void append_to_bad_blocks(unsigned long block)
|
||||
{
|
||||
long long *new_buf;
|
||||
|
||||
|
@ -416,8 +417,8 @@ void append_to_bad_blocks(unsigned long block)
|
|||
/**
|
||||
* mkntfs_write
|
||||
*/
|
||||
__inline__ long long mkntfs_write(struct ntfs_device *dev, const void *buf,
|
||||
long long count)
|
||||
static __inline__ long long mkntfs_write(struct ntfs_device *dev,
|
||||
const void *buf, long long count)
|
||||
{
|
||||
long long bytes_written, total;
|
||||
int retry;
|
||||
|
@ -460,8 +461,8 @@ __inline__ long long mkntfs_write(struct ntfs_device *dev, const void *buf,
|
|||
* Return the number of bytes written (minus padding) or -1 on error. Errno
|
||||
* will be set to the error code.
|
||||
*/
|
||||
s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl, const char *val,
|
||||
const s64 val_len, s64 *inited_size)
|
||||
static s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl,
|
||||
const char *val, const s64 val_len, s64 *inited_size)
|
||||
{
|
||||
s64 bytes_written, total, length, delta;
|
||||
int retry, i;
|
||||
|
@ -538,7 +539,7 @@ s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl, const char *val,
|
|||
* terminating null byte. If a unicode character was encountered which could
|
||||
* not be converted -1 is returned.
|
||||
*/
|
||||
int ucstos(char *dest, const uchar_t *src, int maxlen)
|
||||
static int ucstos(char *dest, const uchar_t *src, int maxlen)
|
||||
{
|
||||
uchar_t u;
|
||||
int i;
|
||||
|
@ -570,12 +571,12 @@ int ucstos(char *dest, const uchar_t *src, int maxlen)
|
|||
* write the terminating null unicode character and hence return -1 with errno
|
||||
* set to EINVAL.
|
||||
*/
|
||||
int stoucs(uchar_t *dest, const char *src, int maxlen)
|
||||
static int stoucs(uchar_t *dest, const char *src, int maxlen)
|
||||
{
|
||||
char c;
|
||||
int i;
|
||||
|
||||
if (maxlen < sizeof(uchar_t)) {
|
||||
if (maxlen < (int)sizeof(uchar_t)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -596,7 +597,7 @@ int stoucs(uchar_t *dest, const char *src, int maxlen)
|
|||
/**
|
||||
* dump_resident_attr_val
|
||||
*/
|
||||
void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len)
|
||||
static void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len)
|
||||
{
|
||||
const char *don_t_know = "Don't know what to do with this attribute "
|
||||
"type yet.";
|
||||
|
@ -737,7 +738,7 @@ void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len)
|
|||
/**
|
||||
* dump_resident_attr
|
||||
*/
|
||||
void dump_resident_attr(ATTR_RECORD *a)
|
||||
static void dump_resident_attr(ATTR_RECORD *a)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -760,7 +761,7 @@ void dump_resident_attr(ATTR_RECORD *a)
|
|||
/**
|
||||
* dump_mapping_pairs_array
|
||||
*/
|
||||
void dump_mapping_pairs_array(char *b, unsigned int max_len)
|
||||
static void dump_mapping_pairs_array(char *b, unsigned int max_len)
|
||||
{
|
||||
// TODO
|
||||
return;
|
||||
|
@ -769,7 +770,7 @@ void dump_mapping_pairs_array(char *b, unsigned int max_len)
|
|||
/**
|
||||
* dump_non_resident_attr
|
||||
*/
|
||||
void dump_non_resident_attr(ATTR_RECORD *a)
|
||||
static void dump_non_resident_attr(ATTR_RECORD *a)
|
||||
{
|
||||
s64 l;
|
||||
int i;
|
||||
|
@ -802,7 +803,7 @@ void dump_non_resident_attr(ATTR_RECORD *a)
|
|||
/**
|
||||
* dump_attr_record
|
||||
*/
|
||||
void dump_attr_record(ATTR_RECORD *a)
|
||||
static void dump_attr_record(ATTR_RECORD *a)
|
||||
{
|
||||
unsigned int u;
|
||||
char s[0x200];
|
||||
|
@ -897,7 +898,7 @@ void dump_attr_record(ATTR_RECORD *a)
|
|||
/**
|
||||
* dump_mft_record
|
||||
*/
|
||||
void dump_mft_record(MFT_RECORD *m)
|
||||
static void dump_mft_record(MFT_RECORD *m)
|
||||
{
|
||||
ATTR_RECORD *a;
|
||||
unsigned int u;
|
||||
|
@ -947,7 +948,7 @@ void dump_mft_record(MFT_RECORD *m)
|
|||
/**
|
||||
* format_mft_record
|
||||
*/
|
||||
void format_mft_record(MFT_RECORD *m)
|
||||
static void format_mft_record(MFT_RECORD *m)
|
||||
{
|
||||
ATTR_RECORD *a;
|
||||
|
||||
|
@ -1009,7 +1010,7 @@ void format_mft_record(MFT_RECORD *m)
|
|||
* -EINVAL Can only occur if mkntfs was compiled with -DEBUG. Means
|
||||
* the input parameters were faulty.
|
||||
*/
|
||||
int make_room_for_attribute(MFT_RECORD *m, char *pos, const u32 size)
|
||||
static int make_room_for_attribute(MFT_RECORD *m, char *pos, const u32 size)
|
||||
{
|
||||
u32 biu;
|
||||
|
||||
|
@ -1049,7 +1050,7 @@ int make_room_for_attribute(MFT_RECORD *m, char *pos, const u32 size)
|
|||
/**
|
||||
* deallocate_scattered_clusters
|
||||
*/
|
||||
void deallocate_scattered_clusters(const runlist *rl)
|
||||
static void deallocate_scattered_clusters(const runlist *rl)
|
||||
{
|
||||
LCN j;
|
||||
int i;
|
||||
|
@ -1079,7 +1080,7 @@ void deallocate_scattered_clusters(const runlist *rl)
|
|||
* TODO: We should be returning the size as well, but for mkntfs this is not
|
||||
* necessary.
|
||||
*/
|
||||
runlist *allocate_scattered_clusters(s64 clusters)
|
||||
static runlist *allocate_scattered_clusters(s64 clusters)
|
||||
{
|
||||
runlist *rl = NULL, *rlt;
|
||||
VCN vcn = 0LL;
|
||||
|
@ -1157,10 +1158,10 @@ err_end:
|
|||
*
|
||||
* Return 0 on success and -errno on error.
|
||||
*/
|
||||
int insert_positioned_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type,
|
||||
const char *name, u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const ATTR_FLAGS flags, const runlist *rl,
|
||||
const char *val, const s64 val_len)
|
||||
static int insert_positioned_attr_in_mft_record(MFT_RECORD *m,
|
||||
const ATTR_TYPES type, const char *name, u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const runlist *rl, const char *val, const s64 val_len)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *a;
|
||||
|
@ -1342,9 +1343,10 @@ err_out:
|
|||
* insert_non_resident_attr_in_mft_record
|
||||
* Return 0 on success and -errno on error.
|
||||
*/
|
||||
int insert_non_resident_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type,
|
||||
const char *name, u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const ATTR_FLAGS flags, const char *val, const s64 val_len)
|
||||
static int insert_non_resident_attr_in_mft_record(MFT_RECORD *m,
|
||||
const ATTR_TYPES type, const char *name, u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const char *val, const s64 val_len)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *a;
|
||||
|
@ -1532,9 +1534,10 @@ err_out:
|
|||
* insert_resident_attr_in_mft_record
|
||||
* Return 0 on success and -errno on error.
|
||||
*/
|
||||
int insert_resident_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type,
|
||||
const char *name, u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const ATTR_FLAGS flags, const RESIDENT_ATTR_FLAGS res_flags,
|
||||
static int insert_resident_attr_in_mft_record(MFT_RECORD *m,
|
||||
const ATTR_TYPES type, const char *name, u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const RESIDENT_ATTR_FLAGS res_flags,
|
||||
const char *val, const u32 val_len)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
|
@ -1635,7 +1638,7 @@ err_out:
|
|||
* add_attr_std_info
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags)
|
||||
static int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags)
|
||||
{
|
||||
STANDARD_INFORMATION si;
|
||||
int err;
|
||||
|
@ -1672,7 +1675,7 @@ int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags)
|
|||
* add_attr_file_name
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
|
||||
static int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
|
||||
const s64 allocated_size, const s64 data_size,
|
||||
const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
|
||||
const u32 reparse_point_tag, const char *file_name,
|
||||
|
@ -1755,7 +1758,7 @@ int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
|
||||
static int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1778,7 +1781,7 @@ int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
|
|||
* add_attr_data
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
static int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const char *val, const s64 val_len)
|
||||
{
|
||||
|
@ -1817,7 +1820,7 @@ int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_data_positioned(MFT_RECORD *m, const char *name,
|
||||
static int add_attr_data_positioned(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const ATTR_FLAGS flags, const runlist *rl,
|
||||
const char *val, const s64 val_len)
|
||||
|
@ -1842,7 +1845,7 @@ int add_attr_data_positioned(MFT_RECORD *m, const char *name,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
|
||||
static int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
|
||||
const int vol_name_len)
|
||||
{
|
||||
uchar_t *uname;
|
||||
|
@ -1879,7 +1882,7 @@ int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
|
|||
* add_attr_vol_info
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
|
||||
static int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
|
||||
const u8 major_ver, const u8 minor_ver)
|
||||
{
|
||||
VOLUME_INFORMATION vi;
|
||||
|
@ -1900,8 +1903,9 @@ int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
|
|||
* add_attr_index_root
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_index_root(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_TYPES indexed_attr_type,
|
||||
static int add_attr_index_root(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const ATTR_TYPES indexed_attr_type,
|
||||
const COLLATION_RULES collation_rule,
|
||||
const u32 index_block_size)
|
||||
{
|
||||
|
@ -1979,9 +1983,9 @@ int add_attr_index_root(MFT_RECORD *m, const char *name, const u32 name_len,
|
|||
* add_attr_index_alloc
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_index_alloc(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const char *index_alloc_val,
|
||||
const u32 index_alloc_val_len)
|
||||
static int add_attr_index_alloc(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const char *index_alloc_val, const u32 index_alloc_val_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1997,7 +2001,7 @@ int add_attr_index_alloc(MFT_RECORD *m, const char *name, const u32 name_len,
|
|||
* add_attr_bitmap
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
static int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const char *bitmap,
|
||||
const u32 bitmap_len)
|
||||
{
|
||||
|
@ -2025,7 +2029,7 @@ int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int add_attr_bitmap_positioned(MFT_RECORD *m, const char *name,
|
||||
static int add_attr_bitmap_positioned(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const runlist *rl, const char *bitmap, const u32 bitmap_len)
|
||||
{
|
||||
|
@ -2047,7 +2051,7 @@ int add_attr_bitmap_positioned(MFT_RECORD *m, const char *name,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int upgrade_to_large_index(MFT_RECORD *m, const char *name,
|
||||
static int upgrade_to_large_index(MFT_RECORD *m, const char *name,
|
||||
u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
INDEX_ALLOCATION **index)
|
||||
{
|
||||
|
@ -2206,7 +2210,7 @@ err_out:
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int make_room_for_index_entry_in_index_block(INDEX_BLOCK *index,
|
||||
static int make_room_for_index_entry_in_index_block(INDEX_BLOCK *index,
|
||||
INDEX_ENTRY *pos, u32 size)
|
||||
{
|
||||
u32 biu;
|
||||
|
@ -2259,7 +2263,7 @@ int make_room_for_index_entry_in_index_block(INDEX_BLOCK *index,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int insert_file_link_in_dir_index(INDEX_BLOCK *index, MFT_REF file_ref,
|
||||
static int insert_file_link_in_dir_index(INDEX_BLOCK *index, MFT_REF file_ref,
|
||||
FILE_NAME_ATTR *file_name, u32 file_name_size)
|
||||
{
|
||||
int err, i;
|
||||
|
@ -2391,7 +2395,7 @@ do_next:
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent,
|
||||
static int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent,
|
||||
MFT_RECORD *m_file, const MFT_REF ref_file,
|
||||
const s64 allocated_size, const s64 data_size,
|
||||
const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
|
||||
|
@ -2479,7 +2483,7 @@ int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent,
|
|||
/**
|
||||
* init_options
|
||||
*/
|
||||
void init_options(void)
|
||||
static void init_options(void)
|
||||
{
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.index_block_size = 4096;
|
||||
|
@ -2491,7 +2495,7 @@ void init_options(void)
|
|||
/**
|
||||
* mkntfs_exit
|
||||
*/
|
||||
void mkntfs_exit(void)
|
||||
static void mkntfs_exit(void)
|
||||
{
|
||||
if (index_block)
|
||||
free(index_block);
|
||||
|
@ -2521,7 +2525,7 @@ void mkntfs_exit(void)
|
|||
free(rl_index);
|
||||
if (opts.bad_blocks)
|
||||
free(opts.bad_blocks);
|
||||
if (opts.attr_defs != (ATTR_DEF*)attrdef_ntfs12_array)
|
||||
if (opts.attr_defs != (const ATTR_DEF*)attrdef_ntfs12_array)
|
||||
free(opts.attr_defs);
|
||||
if (!vol)
|
||||
return;
|
||||
|
@ -2677,7 +2681,7 @@ int main(int argc, char **argv)
|
|||
/* Validate sector size. */
|
||||
if ((opts.sector_size - 1) & opts.sector_size ||
|
||||
opts.sector_size < 256 || opts.sector_size > 4096)
|
||||
err_exit("Error: sector_size is invalid. It must be a power "
|
||||
err_exit("sector_size is invalid. It must be a power "
|
||||
"of two, and it must be\n greater or equal 256 and "
|
||||
"less than or equal 4096 bytes.\n");
|
||||
Dprintf("sector size = %i bytes\n", opts.sector_size);
|
||||
|
@ -2698,12 +2702,11 @@ int main(int argc, char **argv)
|
|||
if (!opts.volume_size)
|
||||
opts.volume_size = opts.nr_sectors * opts.sector_size;
|
||||
else if (opts.volume_size & (opts.sector_size - 1))
|
||||
err_exit("Error: volume_size is not a multiple of "
|
||||
"sector_size.\n");
|
||||
err_exit("volume_size is not a multiple of sector_size.\n");
|
||||
/* Validate volume size. */
|
||||
if (opts.volume_size < 1 << 20 /* 1MiB */)
|
||||
err_exit("Error: device is too small (%ikiB). Minimum NTFS "
|
||||
"volume size is 1MiB.\n", opts.volume_size / 1024);
|
||||
err_exit("Device is too small (%ikiB). Minimum NTFS volume "
|
||||
"size is 1MiB.\n", opts.volume_size / 1024);
|
||||
Dprintf("volume size = %llikiB\n", opts.volume_size / 1024);
|
||||
/* If user didn't specify the cluster size, determine it now. */
|
||||
if (!vol->cluster_size) {
|
||||
|
@ -2718,24 +2721,36 @@ int main(int argc, char **argv)
|
|||
/* For small volumes on devices with large sector sizes. */
|
||||
if (vol->cluster_size < (u32)opts.sector_size)
|
||||
vol->cluster_size = opts.sector_size;
|
||||
/*
|
||||
* For huge volumes, grow the cluster size until the number of
|
||||
* clusters fits into 32 bits or the cluster size exceeds the
|
||||
* maximum limit of 64kiB.
|
||||
*/
|
||||
while (opts.volume_size >> (ffs(vol->cluster_size) - 1 + 32)) {
|
||||
vol->cluster_size <<= 1;
|
||||
if (vol->cluster_size > 65536)
|
||||
err_exit("Device is too large to hold an NTFS "
|
||||
"volume (maximum size is "
|
||||
"256TiB).\n");
|
||||
}
|
||||
}
|
||||
/* Validate cluster size. */
|
||||
if (vol->cluster_size & (vol->cluster_size - 1) ||
|
||||
vol->cluster_size < (u32)opts.sector_size ||
|
||||
vol->cluster_size > 128 * (u32)opts.sector_size ||
|
||||
vol->cluster_size > 65536)
|
||||
err_exit("Error: cluster_size is invalid. It must be a power "
|
||||
"of two, be at least\nthe same as sector_size, be "
|
||||
"maximum 64kB, and the sectors per cluster value "
|
||||
"has\nto fit inside eight bits. (We do not support "
|
||||
"larger cluster sizes yet.)\n");
|
||||
err_exit("Cluster_size is invalid. It must be a power of two, "
|
||||
"be at least\nthe same as sector_size, be maximum "
|
||||
"64kiB, and the sectors per cluster value has\n"
|
||||
"to fit inside eight bits. (We do not support larger "
|
||||
"cluster sizes yet.)\n");
|
||||
vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
|
||||
Dprintf("cluster size = %i bytes\n", vol->cluster_size);
|
||||
if (vol->cluster_size > 4096) {
|
||||
if (opts.enable_compression) {
|
||||
if (!opts.force)
|
||||
err_exit("Error: cluster_size is above 4096 "
|
||||
"bytes and compression is "
|
||||
err_exit("Cluster_size is above 4096 bytes "
|
||||
"and compression is "
|
||||
"requested.\nThis is not "
|
||||
"possible due to limitations "
|
||||
"in the compression algorithm "
|
||||
|
@ -2764,6 +2779,17 @@ int main(int argc, char **argv)
|
|||
"and/or cluster/sector number.\n");
|
||||
Dprintf("number of clusters = %llu (0x%llx)\n", opts.nr_clusters,
|
||||
opts.nr_clusters);
|
||||
/* Number of clusters must fit within 32 bits (Win2k limitation). */
|
||||
if (opts.nr_clusters >> 32) {
|
||||
if (vol->cluster_size >= 65536)
|
||||
err_exit("Device is too large to hold an NTFS volume "
|
||||
"(maximum size is 256TiB).\n");
|
||||
err_exit("Number of clusters exceeds 32 bits. Please try "
|
||||
"again with a larger\ncluster size or leave "
|
||||
"the cluster size unspecified and the "
|
||||
"smallest possible\ncluster size for the size "
|
||||
"of the device will be used.\n");
|
||||
}
|
||||
/* Determine lcn bitmap byte size and allocate it. */
|
||||
lcn_bitmap_byte_size = (opts.nr_clusters + 7) >> 3;
|
||||
/* Needs to be multiple of 8 bytes. */
|
||||
|
@ -3362,7 +3388,7 @@ int main(int argc, char **argv)
|
|||
buf2 = NULL;
|
||||
if (bw != i) {
|
||||
int _e = errno;
|
||||
char *_s;
|
||||
const char *_s;
|
||||
|
||||
if (bw == -1LL)
|
||||
_s = strerror(_e);
|
||||
|
|
Loading…
Reference in New Issue