2009-12-10 Vladimir Serbinenko <phcoder@gmail.com>
Eliminate NTFS 4Gib barrier. * fs/ntfs.c (read_attr): Use grub_disk_addr_t and grub_size_t. (read_run_data): Likewise. (grub_ntfs_read_run_list): Likewise. (grub_ntfs_read_block): Likewise. (grub_ntfs_iterate_dir): Likewise. (read_mft): Likewise. (read_data): Likewise. Use COM_LOG_LEN. * fs/ntfscomp.c (read_block): Cast ctx->target_vcn & 0xF to unsigned to avoid 64-bit division * include/grub/ntfs.h (COM_LOG_LEN): New definition. (grub_ntfs_rlst): Use grub_disk_addr_t.
This commit is contained in:
parent
71ee178adb
commit
2e59983c82
4 changed files with 47 additions and 26 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2009-12-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Eliminate NTFS 4Gib barrier.
|
||||||
|
|
||||||
|
* fs/ntfs.c (read_attr): Use grub_disk_addr_t and grub_size_t.
|
||||||
|
(read_run_data): Likewise.
|
||||||
|
(grub_ntfs_read_run_list): Likewise.
|
||||||
|
(grub_ntfs_read_block): Likewise.
|
||||||
|
(grub_ntfs_iterate_dir): Likewise.
|
||||||
|
(read_mft): Likewise.
|
||||||
|
(read_data): Likewise.
|
||||||
|
Use COM_LOG_LEN.
|
||||||
|
* fs/ntfscomp.c (read_block): Cast ctx->target_vcn & 0xF to unsigned
|
||||||
|
to avoid 64-bit division
|
||||||
|
* include/grub/ntfs.h (COM_LOG_LEN): New definition.
|
||||||
|
(grub_ntfs_rlst): Use grub_disk_addr_t.
|
||||||
|
|
||||||
2009-12-10 Vladimir Serbinenko <phcoder@gmail.com>
|
2009-12-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
Eliminate grub-fstest 4Gib barrier.
|
Eliminate grub-fstest 4Gib barrier.
|
||||||
|
|
51
fs/ntfs.c
51
fs/ntfs.c
|
@ -63,7 +63,7 @@ fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
|
||||||
static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
|
static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
|
||||||
grub_uint32_t mftno);
|
grub_uint32_t mftno);
|
||||||
static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
|
static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
|
||||||
grub_uint32_t ofs, grub_uint32_t len,
|
grub_disk_addr_t ofs, grub_size_t len,
|
||||||
int cached,
|
int cached,
|
||||||
void
|
void
|
||||||
NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
|
NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
|
||||||
|
@ -72,7 +72,7 @@ static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
|
||||||
unsigned length));
|
unsigned length));
|
||||||
|
|
||||||
static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
grub_uint32_t ofs, grub_uint32_t len,
|
grub_disk_addr_t ofs, grub_size_t len,
|
||||||
int cached,
|
int cached,
|
||||||
void
|
void
|
||||||
NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
|
NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
|
||||||
|
@ -260,9 +260,9 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
read_run_data (char *run, int nn, grub_uint32_t * val, int sig)
|
read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
|
||||||
{
|
{
|
||||||
grub_uint32_t r, v;
|
grub_disk_addr_t r, v;
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
v = 1;
|
v = 1;
|
||||||
|
@ -284,7 +284,7 @@ grub_err_t
|
||||||
grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
|
grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
|
||||||
{
|
{
|
||||||
int c1, c2;
|
int c1, c2;
|
||||||
grub_uint32_t val;
|
grub_disk_addr_t val;
|
||||||
char *run;
|
char *run;
|
||||||
|
|
||||||
run = ctx->cur_run;
|
run = ctx->cur_run;
|
||||||
|
@ -335,25 +335,25 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
|
||||||
struct grub_ntfs_rlst *ctx;
|
struct grub_ntfs_rlst *ctx;
|
||||||
|
|
||||||
ctx = (struct grub_ntfs_rlst *) node;
|
ctx = (struct grub_ntfs_rlst *) node;
|
||||||
if ((grub_uint32_t) block >= ctx->next_vcn)
|
if (block >= ctx->next_vcn)
|
||||||
{
|
{
|
||||||
if (grub_ntfs_read_run_list (ctx))
|
if (grub_ntfs_read_run_list (ctx))
|
||||||
return -1;
|
return -1;
|
||||||
return ctx->curr_lcn;
|
return ctx->curr_lcn;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (ctx->flags & RF_BLNK) ? 0 : ((grub_uint32_t) block -
|
return (ctx->flags & RF_BLNK) ? 0 : (block -
|
||||||
ctx->curr_vcn + ctx->curr_lcn);
|
ctx->curr_vcn + ctx->curr_lcn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
|
read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
grub_uint32_t len, int cached,
|
grub_disk_addr_t ofs, grub_size_t len, int cached,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset,
|
unsigned offset,
|
||||||
unsigned length))
|
unsigned length))
|
||||||
{
|
{
|
||||||
grub_uint32_t vcn;
|
grub_disk_addr_t vcn;
|
||||||
struct grub_ntfs_rlst cc, *ctx;
|
struct grub_ntfs_rlst cc, *ctx;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
|
@ -388,7 +388,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
|
||||||
{
|
{
|
||||||
if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
|
if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
|
||||||
{
|
{
|
||||||
grub_uint32_t n;
|
grub_disk_addr_t n;
|
||||||
|
|
||||||
n = COM_LEN - (ofs - at->save_pos);
|
n = COM_LEN - (ofs - at->save_pos);
|
||||||
if (n > len)
|
if (n > len)
|
||||||
|
@ -411,11 +411,11 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
|
||||||
at->save_pos = 1;
|
at->save_pos = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vcn = ctx->target_vcn = (ofs / COM_LEN) * (COM_SEC / ctx->comp.spc);
|
vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc);
|
||||||
ctx->target_vcn &= ~0xF;
|
ctx->target_vcn &= ~0xF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vcn = ctx->target_vcn = (ofs >> BLK_SHR) / ctx->comp.spc;
|
vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0);
|
||||||
|
|
||||||
ctx->next_vcn = u32at (pa, 0x10);
|
ctx->next_vcn = u32at (pa, 0x10);
|
||||||
ctx->curr_lcn = 0;
|
ctx->curr_lcn = 0;
|
||||||
|
@ -427,11 +427,13 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
|
||||||
|
|
||||||
if (at->flags & AF_GPOS)
|
if (at->flags & AF_GPOS)
|
||||||
{
|
{
|
||||||
grub_uint32_t st0, st1;
|
grub_disk_addr_t st0, st1;
|
||||||
|
grub_uint32_t m;
|
||||||
|
|
||||||
|
grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
|
||||||
|
|
||||||
st0 =
|
st0 =
|
||||||
(ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc +
|
(ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
|
||||||
((ofs >> BLK_SHR) % ctx->comp.spc);
|
|
||||||
st1 = st0 + 1;
|
st1 = st0 + 1;
|
||||||
if (st1 ==
|
if (st1 ==
|
||||||
(ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
|
(ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
|
||||||
|
@ -462,8 +464,8 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
|
read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
|
||||||
grub_uint32_t len, int cached,
|
grub_size_t len, int cached,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset,
|
unsigned offset,
|
||||||
unsigned length))
|
unsigned length))
|
||||||
|
@ -479,9 +481,9 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
|
||||||
if (at->flags & AF_ALST)
|
if (at->flags & AF_ALST)
|
||||||
{
|
{
|
||||||
char *pa;
|
char *pa;
|
||||||
grub_uint32_t vcn;
|
grub_disk_addr_t vcn;
|
||||||
|
|
||||||
vcn = ofs / (at->mft->data->spc << BLK_SHR);
|
vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0);
|
||||||
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
|
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
|
||||||
while (pa < at->attr_end)
|
while (pa < at->attr_end)
|
||||||
{
|
{
|
||||||
|
@ -508,7 +510,7 @@ static grub_err_t
|
||||||
read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
|
read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
|
||||||
{
|
{
|
||||||
if (read_attr
|
if (read_attr
|
||||||
(&data->mmft.attr, buf, mftno * (data->mft_size << BLK_SHR),
|
(&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR),
|
||||||
data->mft_size << BLK_SHR, 0, 0))
|
data->mft_size << BLK_SHR, 0, 0))
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno);
|
return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno);
|
||||||
return fixup (data, buf, data->mft_size, "FILE");
|
return fixup (data, buf, data->mft_size, "FILE");
|
||||||
|
@ -640,7 +642,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
unsigned char *bitmap;
|
unsigned char *bitmap;
|
||||||
struct grub_ntfs_attr attr, *at;
|
struct grub_ntfs_attr attr, *at;
|
||||||
char *cur_pos, *indx, *bmp;
|
char *cur_pos, *indx, *bmp;
|
||||||
int bitmap_len, ret = 0;
|
int ret = 0;
|
||||||
|
grub_size_t bitmap_len;
|
||||||
struct grub_ntfs_file *mft;
|
struct grub_ntfs_file *mft;
|
||||||
|
|
||||||
mft = (struct grub_ntfs_file *) dir;
|
mft = (struct grub_ntfs_file *) dir;
|
||||||
|
@ -744,14 +747,14 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
if (bitmap)
|
if (bitmap)
|
||||||
{
|
{
|
||||||
grub_uint32_t v, i;
|
grub_disk_addr_t v, i;
|
||||||
|
|
||||||
indx = grub_malloc (mft->data->idx_size << BLK_SHR);
|
indx = grub_malloc (mft->data->idx_size << BLK_SHR);
|
||||||
if (indx == NULL)
|
if (indx == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
v = 1;
|
v = 1;
|
||||||
for (i = 0; i < (grub_uint32_t) bitmap_len * 8; i++)
|
for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++)
|
||||||
{
|
{
|
||||||
if (*bitmap & v)
|
if (*bitmap & v)
|
||||||
{
|
{
|
||||||
|
|
|
@ -209,7 +209,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nn = (16 - (ctx->target_vcn & 0xF)) / cpb;
|
nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb;
|
||||||
if (nn > num)
|
if (nn > num)
|
||||||
nn = num;
|
nn = num;
|
||||||
num -= nn;
|
num -= nn;
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
#define MAX_IDX (16384 >> BLK_SHR)
|
#define MAX_IDX (16384 >> BLK_SHR)
|
||||||
|
|
||||||
#define COM_LEN 4096
|
#define COM_LEN 4096
|
||||||
|
#define COM_LOG_LEN 12
|
||||||
#define COM_SEC (COM_LEN >> BLK_SHR)
|
#define COM_SEC (COM_LEN >> BLK_SHR)
|
||||||
|
|
||||||
#define AF_ALST 1
|
#define AF_ALST 1
|
||||||
|
@ -164,7 +165,7 @@ struct grub_ntfs_comp
|
||||||
struct grub_ntfs_rlst
|
struct grub_ntfs_rlst
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
grub_uint32_t target_vcn, curr_vcn, next_vcn, curr_lcn;
|
grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn;
|
||||||
char *cur_run;
|
char *cur_run;
|
||||||
struct grub_ntfs_attr *attr;
|
struct grub_ntfs_attr *attr;
|
||||||
struct grub_ntfs_comp comp;
|
struct grub_ntfs_comp comp;
|
||||||
|
|
Loading…
Reference in a new issue