2008-05-20 Bean <bean123ch@gmail.com>
* fs/fshelp.c (grub_fshelp_map_block): New function. (grub_fshelp_find_file): Use 64-bit type for pos and block address. Use `>>' and `&' operator to avoid 64-bit divide and modulo. * include/grub/fshelp.h (grub_fshelp_journal_type): New enum. (GRUB_FSHELP_JOURNAL_UNUSED_MAPPING): New macro. (grub_fshelp_journal): New structure. (grub_fshelp_map_block): New function prototype. (grub_fshelp_read_file): Use grub_disk_addr_t as block type. (grub_fshelp_map_block): Likewise. * fs/ext2.c (EXT3_FEATURE_COMPAT_HAS_JOURNAL): New macro. (EXT3_JOURNAL_MAGIC_NUMBER): Likewise. (EXT3_JOURNAL_DESCRIPTOR_BLOCK): Likewise. (EXT3_JOURNAL_COMMIT_BLOCK): Likewise. (EXT3_JOURNAL_SUPERBLOCK_V1): Likewise. (EXT3_JOURNAL_SUPERBLOCK_V2): Likewise. (EXT3_JOURNAL_REVOKE_BLOCK): Likewise. (EXT3_JOURNAL_FLAG_ESCAPE): Likewise. (EXT3_JOURNAL_FLAG_SAME_UUID): Likewise. (EXT3_JOURNAL_FLAG_DELETED): Likewise. (EXT3_JOURNAL_FLAG_LAST_TAG): Likewise. (grub_ext2_sblock): New members for journal support. (grub_ext3_journal_header): New structure. (grub_ext3_journal_revoke_header): Likewise. (grub_ext3_journal_block_tag): Likewise. (grub_ext3_journal_sblock): Likewise. (grub_fshelp_node): New members logfile and journal. (grub_ext2_read_block): Change block type to grub_disk_addr_t. Use grub_fshelp_map_block to get real block number. (grub_ext2_blockgroup): Use grub_fshelp_map_block to get real block number. (grub_ext2_read_inode): Likewise. (grub_ext3_get_journal): New function. (grub_read_inode): Initialize journal using grub_ext3_get_journal. (grub_ext2_close): Release memory used by journal. * fs/reiserfs.c (REISERFS_MAGIC_STRING): Changed to "ReIsEr". (REISERFS_MAGIC_DESC_BLOCK): New macro. (grub_reiserfs_transaction_header): Renamed to grub_reiserfs_description_block, replace field data with real_blocks. (grub_reiserfs_commit_block): New structure. (grub_reiserfs_data): New member journal. (grub_reiserfs_get_item): Use grub_fshelp_map_block to get real block number. (grub_reiserfs_read_symlink): Likewise. (grub_reiserfs_iterate_dir): Likewise. (grub_reiserfs_open): Likewise. (grub_reiserfs_read): Likewise. (grub_reiserfs_get_journal): New function. (grub_reiserfs_mount): Use "ReIsEr" as super block magic, as there are three varieties ReIsErFs, ReIsEr2Fs and ReIsEr3Fs. Initialize journal using grub_reiserfs_get_journal. (grub_reiserfs_close): Release memory used by journal. * fs/affs.c (grub_affs_read_block): Change block type to grub_disk_addr_t. Use grub_divmod64 to do 64-bit division. * fs/afs.c (grub_afs_read_block): Change block type to grub_disk_addr_t. * fs/hfsplus.c (grub_hfsplus_read_block): Likewise. * fs/ntfs.c (grub_ntfs_read_block): Likewise. * fs/udf.c (grub_udf_read_block): Change block type to grub_disk_addr_t. Use type cast to avoid warning. * fs/xfs.c (grub_xfs_read_block): Likewise.
This commit is contained in:
parent
b7c6bed50e
commit
887d2619bf
71
ChangeLog
71
ChangeLog
|
@ -1,3 +1,74 @@
|
|||
2008-05-20 Bean <bean123ch@gmail.com>
|
||||
|
||||
* fs/fshelp.c (grub_fshelp_map_block): New function.
|
||||
(grub_fshelp_find_file): Use 64-bit type for pos and block address.
|
||||
Use `>>' and `&' operator to avoid 64-bit divide and modulo.
|
||||
|
||||
* include/grub/fshelp.h (grub_fshelp_journal_type): New enum.
|
||||
(GRUB_FSHELP_JOURNAL_UNUSED_MAPPING): New macro.
|
||||
(grub_fshelp_journal): New structure.
|
||||
(grub_fshelp_map_block): New function prototype.
|
||||
(grub_fshelp_read_file): Use grub_disk_addr_t as block type.
|
||||
(grub_fshelp_map_block): Likewise.
|
||||
|
||||
* fs/ext2.c (EXT3_FEATURE_COMPAT_HAS_JOURNAL): New macro.
|
||||
(EXT3_JOURNAL_MAGIC_NUMBER): Likewise.
|
||||
(EXT3_JOURNAL_DESCRIPTOR_BLOCK): Likewise.
|
||||
(EXT3_JOURNAL_COMMIT_BLOCK): Likewise.
|
||||
(EXT3_JOURNAL_SUPERBLOCK_V1): Likewise.
|
||||
(EXT3_JOURNAL_SUPERBLOCK_V2): Likewise.
|
||||
(EXT3_JOURNAL_REVOKE_BLOCK): Likewise.
|
||||
(EXT3_JOURNAL_FLAG_ESCAPE): Likewise.
|
||||
(EXT3_JOURNAL_FLAG_SAME_UUID): Likewise.
|
||||
(EXT3_JOURNAL_FLAG_DELETED): Likewise.
|
||||
(EXT3_JOURNAL_FLAG_LAST_TAG): Likewise.
|
||||
(grub_ext2_sblock): New members for journal support.
|
||||
(grub_ext3_journal_header): New structure.
|
||||
(grub_ext3_journal_revoke_header): Likewise.
|
||||
(grub_ext3_journal_block_tag): Likewise.
|
||||
(grub_ext3_journal_sblock): Likewise.
|
||||
(grub_fshelp_node): New members logfile and journal.
|
||||
(grub_ext2_read_block): Change block type to grub_disk_addr_t. Use
|
||||
grub_fshelp_map_block to get real block number.
|
||||
(grub_ext2_blockgroup): Use grub_fshelp_map_block to get real block
|
||||
number.
|
||||
(grub_ext2_read_inode): Likewise.
|
||||
(grub_ext3_get_journal): New function.
|
||||
(grub_read_inode): Initialize journal using grub_ext3_get_journal.
|
||||
(grub_ext2_close): Release memory used by journal.
|
||||
|
||||
* fs/reiserfs.c (REISERFS_MAGIC_STRING): Changed to "ReIsEr".
|
||||
(REISERFS_MAGIC_DESC_BLOCK): New macro.
|
||||
(grub_reiserfs_transaction_header): Renamed to
|
||||
grub_reiserfs_description_block, replace field data with real_blocks.
|
||||
(grub_reiserfs_commit_block): New structure.
|
||||
(grub_reiserfs_data): New member journal.
|
||||
(grub_reiserfs_get_item): Use grub_fshelp_map_block to get real block
|
||||
number.
|
||||
(grub_reiserfs_read_symlink): Likewise.
|
||||
(grub_reiserfs_iterate_dir): Likewise.
|
||||
(grub_reiserfs_open): Likewise.
|
||||
(grub_reiserfs_read): Likewise.
|
||||
(grub_reiserfs_get_journal): New function.
|
||||
(grub_reiserfs_mount): Use "ReIsEr" as super block magic, as there are
|
||||
three varieties ReIsErFs, ReIsEr2Fs and ReIsEr3Fs. Initialize journal
|
||||
using grub_reiserfs_get_journal.
|
||||
(grub_reiserfs_close): Release memory used by journal.
|
||||
|
||||
* fs/affs.c (grub_affs_read_block): Change block type to
|
||||
grub_disk_addr_t. Use grub_divmod64 to do 64-bit division.
|
||||
|
||||
* fs/afs.c (grub_afs_read_block): Change block type to grub_disk_addr_t.
|
||||
|
||||
* fs/hfsplus.c (grub_hfsplus_read_block): Likewise.
|
||||
|
||||
* fs/ntfs.c (grub_ntfs_read_block): Likewise.
|
||||
|
||||
* fs/udf.c (grub_udf_read_block): Change block type to
|
||||
grub_disk_addr_t. Use type cast to avoid warning.
|
||||
|
||||
* fs/xfs.c (grub_xfs_read_block): Likewise.
|
||||
|
||||
2008-05-16 Christian Franke <franke@computer.org>
|
||||
|
||||
* commands/cat.c (grub_cmd_cat): Remove non-ESC keys from keyboard queue
|
||||
|
|
10
fs/affs.c
10
fs/affs.c
|
@ -109,18 +109,19 @@ static grub_dl_t my_mod;
|
|||
#endif
|
||||
|
||||
|
||||
static int
|
||||
grub_affs_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
static grub_disk_addr_t
|
||||
grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
int links;
|
||||
grub_uint32_t pos;
|
||||
int block = node->block;
|
||||
struct grub_affs_file file;
|
||||
struct grub_affs_data *data = node->data;
|
||||
grub_uint32_t mod;
|
||||
|
||||
/* Find the block that points to the fileblock we are looking up by
|
||||
following the chain until the right table is reached. */
|
||||
for (links = fileblock / (data->htsize); links; links--)
|
||||
for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
|
||||
{
|
||||
grub_disk_read (data->disk, block + data->blocksize - 1,
|
||||
data->blocksize * (GRUB_DISK_SECTOR_SIZE
|
||||
|
@ -133,7 +134,7 @@ grub_affs_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
}
|
||||
|
||||
/* Translate the fileblock to the block within the right table. */
|
||||
fileblock = fileblock % (data->htsize);
|
||||
fileblock = mod;
|
||||
grub_disk_read (data->disk, block,
|
||||
GRUB_AFFS_BLOCKPTR_OFFSET
|
||||
+ (data->htsize - fileblock - 1) * sizeof (pos),
|
||||
|
@ -567,4 +568,3 @@ GRUB_MOD_FINI(affs)
|
|||
{
|
||||
grub_fs_unregister (&grub_affs_fs);
|
||||
}
|
||||
|
||||
|
|
6
fs/afs.c
6
fs/afs.c
|
@ -199,12 +199,12 @@ grub_afs_read_inode (struct grub_afs_data *data,
|
|||
}
|
||||
|
||||
static int
|
||||
grub_afs_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_afs_sblock *sb = &node->data->sblock;
|
||||
struct grub_afs_datastream *ds = &node->inode.stream;
|
||||
|
||||
if ((grub_uint32_t) fileblock < U64 (sb, ds->max_direct_range))
|
||||
if (fileblock < U64 (sb, ds->max_direct_range))
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -215,7 +215,7 @@ grub_afs_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
fileblock -= U16 (sb, ds->direct[i].len);
|
||||
}
|
||||
}
|
||||
else if ((grub_uint32_t) fileblock < U64 (sb, ds->max_indirect_range))
|
||||
else if (fileblock < U64 (sb, ds->max_indirect_range))
|
||||
{
|
||||
int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
|
||||
struct grub_afs_blockrun indir[ptrs_per_blk];
|
||||
|
|
261
fs/ext2.c
261
fs/ext2.c
|
@ -71,6 +71,21 @@
|
|||
? EXT2_GOOD_OLD_INODE_SIZE \
|
||||
: grub_le_to_cpu16 (data->sblock.inode_size))
|
||||
|
||||
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
|
||||
|
||||
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
|
||||
|
||||
#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1
|
||||
#define EXT3_JOURNAL_COMMIT_BLOCK 2
|
||||
#define EXT3_JOURNAL_SUPERBLOCK_V1 3
|
||||
#define EXT3_JOURNAL_SUPERBLOCK_V2 4
|
||||
#define EXT3_JOURNAL_REVOKE_BLOCK 5
|
||||
|
||||
#define EXT3_JOURNAL_FLAG_ESCAPE 1
|
||||
#define EXT3_JOURNAL_FLAG_SAME_UUID 2
|
||||
#define EXT3_JOURNAL_FLAG_DELETED 4
|
||||
#define EXT3_JOURNAL_FLAG_LAST_TAG 8
|
||||
|
||||
/* The ext2 superblock. */
|
||||
struct grub_ext2_sblock
|
||||
{
|
||||
|
@ -109,6 +124,21 @@ struct grub_ext2_sblock
|
|||
char volume_name[16];
|
||||
char last_mounted_on[64];
|
||||
grub_uint32_t compression_info;
|
||||
grub_uint8_t prealloc_blocks;
|
||||
grub_uint8_t prealloc_dir_blocks;
|
||||
grub_uint16_t reserved_gdt_blocks;
|
||||
grub_uint8_t journal_uuid[16];
|
||||
grub_uint32_t journal_inum;
|
||||
grub_uint32_t journal_dev;
|
||||
grub_uint32_t last_orphan;
|
||||
grub_uint32_t hash_seed[4];
|
||||
grub_uint8_t def_hash_version;
|
||||
grub_uint8_t jnl_backup_type;
|
||||
grub_uint16_t reserved_word_pad;
|
||||
grub_uint32_t default_mount_opts;
|
||||
grub_uint32_t first_meta_bg;
|
||||
grub_uint32_t mkfs_time;
|
||||
grub_uint32_t jnl_blocks[17];
|
||||
};
|
||||
|
||||
/* The ext2 blockgroup. */
|
||||
|
@ -166,6 +196,36 @@ struct ext2_dirent
|
|||
grub_uint8_t filetype;
|
||||
};
|
||||
|
||||
struct grub_ext3_journal_header
|
||||
{
|
||||
grub_uint32_t magic;
|
||||
grub_uint32_t block_type;
|
||||
grub_uint32_t sequence;
|
||||
};
|
||||
|
||||
struct grub_ext3_journal_revoke_header
|
||||
{
|
||||
struct grub_ext3_journal_header header;
|
||||
grub_uint32_t count;
|
||||
grub_uint32_t data[0];
|
||||
};
|
||||
|
||||
struct grub_ext3_journal_block_tag
|
||||
{
|
||||
grub_uint32_t block;
|
||||
grub_uint32_t flags;
|
||||
};
|
||||
|
||||
struct grub_ext3_journal_sblock
|
||||
{
|
||||
struct grub_ext3_journal_header header;
|
||||
grub_uint32_t block_size;
|
||||
grub_uint32_t maxlen;
|
||||
grub_uint32_t first;
|
||||
grub_uint32_t sequence;
|
||||
grub_uint32_t start;
|
||||
};
|
||||
|
||||
struct grub_fshelp_node
|
||||
{
|
||||
struct grub_ext2_data *data;
|
||||
|
@ -181,6 +241,8 @@ struct grub_ext2_data
|
|||
grub_disk_t disk;
|
||||
struct grub_ext2_inode *inode;
|
||||
struct grub_fshelp_node diropen;
|
||||
struct grub_fshelp_node logfile;
|
||||
grub_fshelp_journal_t journal;
|
||||
};
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
|
@ -196,20 +258,21 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
|
|||
struct grub_ext2_block_group *blkgrp)
|
||||
{
|
||||
return grub_disk_read (data->disk,
|
||||
((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
|
||||
(grub_fshelp_map_block (data->journal,
|
||||
grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
|
||||
<< LOG2_EXT2_BLOCK_SIZE (data)),
|
||||
group * sizeof (struct grub_ext2_block_group),
|
||||
sizeof (struct grub_ext2_block_group), (char *) blkgrp);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
grub_ext2_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
static grub_disk_addr_t
|
||||
grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_ext2_data *data = node->data;
|
||||
struct grub_ext2_inode *inode = &node->inode;
|
||||
int blknr;
|
||||
int blksz = EXT2_BLOCK_SIZE (data);
|
||||
unsigned int blksz = EXT2_BLOCK_SIZE (data);
|
||||
int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
|
||||
|
||||
/* Direct blocks. */
|
||||
|
@ -221,7 +284,8 @@ grub_ext2_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
grub_uint32_t indir[blksz / 4];
|
||||
|
||||
if (grub_disk_read (data->disk,
|
||||
grub_le_to_cpu32 (inode->blocks.indir_block)
|
||||
grub_fshelp_map_block(data->journal,
|
||||
grub_le_to_cpu32 (inode->blocks.indir_block))
|
||||
<< log2_blksz,
|
||||
0, blksz, (char *) indir))
|
||||
return grub_errno;
|
||||
|
@ -237,13 +301,15 @@ grub_ext2_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
grub_uint32_t indir[blksz / 4];
|
||||
|
||||
if (grub_disk_read (data->disk,
|
||||
grub_le_to_cpu32 (inode->blocks.double_indir_block)
|
||||
grub_fshelp_map_block(data->journal,
|
||||
grub_le_to_cpu32 (inode->blocks.double_indir_block))
|
||||
<< log2_blksz,
|
||||
0, blksz, (char *) indir))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_disk_read (data->disk,
|
||||
grub_le_to_cpu32 (indir[rblock / perblock])
|
||||
grub_fshelp_map_block(data->journal,
|
||||
grub_le_to_cpu32 (indir[rblock / perblock]))
|
||||
<< log2_blksz,
|
||||
0, blksz, (char *) indir))
|
||||
return grub_errno;
|
||||
|
@ -259,10 +325,9 @@ grub_ext2_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
blknr = -1;
|
||||
}
|
||||
|
||||
return blknr;
|
||||
return grub_fshelp_map_block (data->journal, blknr);
|
||||
}
|
||||
|
||||
|
||||
/* Read LEN bytes from the file described by DATA starting with byte
|
||||
POS. Return the amount of read bytes in READ. */
|
||||
static grub_ssize_t
|
||||
|
@ -308,8 +373,9 @@ grub_ext2_read_inode (struct grub_ext2_data *data,
|
|||
|
||||
/* Read the inode. */
|
||||
if (grub_disk_read (data->disk,
|
||||
((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
|
||||
<< LOG2_EXT2_BLOCK_SIZE (data)),
|
||||
grub_fshelp_map_block(data->journal,
|
||||
grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
|
||||
<< LOG2_EXT2_BLOCK_SIZE (data),
|
||||
EXT2_INODE_SIZE (data) * blkoff,
|
||||
sizeof (struct grub_ext2_inode), (char *) inode))
|
||||
return grub_errno;
|
||||
|
@ -317,6 +383,169 @@ grub_ext2_read_inode (struct grub_ext2_data *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ext3_get_journal (struct grub_ext2_data *data)
|
||||
{
|
||||
char buf[1 << LOG2_BLOCK_SIZE (data)];
|
||||
struct grub_ext3_journal_sblock *jsb;
|
||||
grub_fshelp_journal_t log;
|
||||
int last_num, num, block, log2bs;
|
||||
grub_uint32_t seq;
|
||||
|
||||
auto void next_block (void);
|
||||
void next_block (void)
|
||||
{
|
||||
block++;
|
||||
if (block >= log->last_block)
|
||||
block = log->first_block;
|
||||
}
|
||||
|
||||
data->journal = 0;
|
||||
|
||||
if (! (data->sblock.feature_compatibility & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
|
||||
return;
|
||||
|
||||
if (! data->sblock.journal_inum)
|
||||
return;
|
||||
|
||||
data->logfile.data = data;
|
||||
data->logfile.ino = data->sblock.journal_inum;
|
||||
data->logfile.inode_read = 1;
|
||||
|
||||
if (grub_ext2_read_inode (data, data->logfile.ino, &data->logfile.inode))
|
||||
return;
|
||||
|
||||
log2bs = LOG2_EXT2_BLOCK_SIZE (data);
|
||||
if (grub_fshelp_read_file (data->disk, &data->logfile, 0,
|
||||
0, sizeof (struct grub_ext3_journal_sblock),
|
||||
buf, grub_ext2_read_block,
|
||||
sizeof (buf), log2bs) !=
|
||||
sizeof (struct grub_ext3_journal_sblock))
|
||||
return;
|
||||
|
||||
jsb = (struct grub_ext3_journal_sblock *) &buf[0];
|
||||
if (grub_be_to_cpu32 (jsb->header.magic) != EXT3_JOURNAL_MAGIC_NUMBER)
|
||||
return;
|
||||
|
||||
/* Empty journal. */
|
||||
if (! jsb->start)
|
||||
return;
|
||||
|
||||
log = grub_malloc (sizeof (struct grub_fshelp_journal) +
|
||||
grub_be_to_cpu32 (jsb->maxlen) * sizeof (grub_disk_addr_t));
|
||||
if (! log)
|
||||
return;
|
||||
|
||||
log->type = GRUB_FSHELP_JOURNAL_TYPE_FILE;
|
||||
log->node = &data->logfile;
|
||||
log->get_block = grub_ext2_read_block;
|
||||
log->first_block = grub_be_to_cpu32 (jsb->first);
|
||||
log->last_block = grub_be_to_cpu32 (jsb->maxlen);
|
||||
log->start_block = grub_be_to_cpu32 (jsb->start);
|
||||
|
||||
last_num = num = 0;
|
||||
block = log->start_block;
|
||||
seq = grub_be_to_cpu32 (jsb->sequence);
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct grub_ext3_journal_header *jh;
|
||||
|
||||
if (grub_fshelp_read_file (data->disk, &data->logfile, 0,
|
||||
block << (log2bs + 9), sizeof (buf),
|
||||
buf, grub_ext2_read_block,
|
||||
log->last_block << (log2bs + 9),
|
||||
log2bs) !=
|
||||
(int) sizeof (buf))
|
||||
break;
|
||||
|
||||
jh = (struct grub_ext3_journal_header *) &buf[0];
|
||||
if (grub_be_to_cpu32 (jh->magic) != EXT3_JOURNAL_MAGIC_NUMBER)
|
||||
break;
|
||||
|
||||
if (grub_be_to_cpu32 (jh->sequence) != seq)
|
||||
break;
|
||||
|
||||
log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
|
||||
next_block();
|
||||
|
||||
switch (grub_be_to_cpu32 (jh->block_type))
|
||||
{
|
||||
case EXT3_JOURNAL_DESCRIPTOR_BLOCK:
|
||||
{
|
||||
struct grub_ext3_journal_block_tag *tag;
|
||||
int ofs, flags;
|
||||
|
||||
ofs = sizeof (struct grub_ext3_journal_header);
|
||||
|
||||
do
|
||||
{
|
||||
tag = (struct grub_ext3_journal_block_tag *) &buf[ofs];
|
||||
ofs += sizeof (struct grub_ext3_journal_block_tag);
|
||||
|
||||
if (ofs > (int) sizeof (buf))
|
||||
break;
|
||||
|
||||
flags = grub_be_to_cpu32 (tag->flags);
|
||||
if (! (flags & EXT3_JOURNAL_FLAG_SAME_UUID))
|
||||
ofs += 16;
|
||||
|
||||
log->mapping[num++] = grub_be_to_cpu32 (tag->block);
|
||||
next_block();
|
||||
}
|
||||
while (! (flags & EXT3_JOURNAL_FLAG_LAST_TAG));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
case EXT3_JOURNAL_COMMIT_BLOCK:
|
||||
{
|
||||
seq++;
|
||||
last_num = num - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
case EXT3_JOURNAL_REVOKE_BLOCK:
|
||||
{
|
||||
struct grub_ext3_journal_revoke_header *jrh;
|
||||
grub_uint32_t i;
|
||||
|
||||
jrh = (struct grub_ext3_journal_revoke_header *) jh;
|
||||
|
||||
for (i = 0; i < grub_be_to_cpu32 (jrh->count); i++)
|
||||
{
|
||||
int j;
|
||||
grub_uint32_t map;
|
||||
|
||||
map = grub_be_to_cpu32 (jrh->data[i]);
|
||||
for (j = 0; j < num; j++)
|
||||
if (log->mapping[j] == map)
|
||||
log->mapping[j] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
last_num = 0;
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
|
||||
quit:
|
||||
if (! last_num)
|
||||
grub_free (log);
|
||||
else
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sizeof (struct grub_fshelp_journal) +
|
||||
last_num * sizeof (grub_disk_addr_t);
|
||||
|
||||
log->num_mappings = last_num;
|
||||
data->journal = grub_realloc (log, size);
|
||||
}
|
||||
}
|
||||
|
||||
static struct grub_ext2_data *
|
||||
grub_ext2_mount (grub_disk_t disk)
|
||||
{
|
||||
|
@ -336,12 +565,14 @@ grub_ext2_mount (grub_disk_t disk)
|
|||
if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC)
|
||||
goto fail;
|
||||
|
||||
data->disk = disk;
|
||||
grub_ext3_get_journal (data);
|
||||
|
||||
data->diropen.data = data;
|
||||
data->diropen.ino = 2;
|
||||
data->diropen.inode_read = 1;
|
||||
|
||||
data->inode = &data->diropen.inode;
|
||||
data->disk = disk;
|
||||
|
||||
grub_ext2_read_inode (data, 2, data->inode);
|
||||
if (grub_errno)
|
||||
|
@ -540,7 +771,11 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
|||
static grub_err_t
|
||||
grub_ext2_close (grub_file_t file)
|
||||
{
|
||||
grub_free (file->data);
|
||||
if (file->data)
|
||||
{
|
||||
grub_free (((struct grub_ext2_data *) file->data)->journal);
|
||||
grub_free (file->data);
|
||||
}
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
grub_dl_unref (my_mod);
|
||||
|
|
56
fs/fshelp.c
56
fs/fshelp.c
|
@ -72,7 +72,7 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
|
|||
|
||||
void free_node (grub_fshelp_node_t node)
|
||||
{
|
||||
if (node != rootnode && node != currroot)
|
||||
if (node != rootnode && node != currroot)
|
||||
grub_free (node);
|
||||
}
|
||||
|
||||
|
@ -223,25 +223,26 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
|
|||
grub_ssize_t
|
||||
grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
|
||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||
unsigned offset, unsigned length),
|
||||
int pos, grub_size_t len, char *buf,
|
||||
int (*get_block) (grub_fshelp_node_t node, int block),
|
||||
unsigned offset,
|
||||
unsigned length),
|
||||
grub_off_t pos, grub_size_t len, char *buf,
|
||||
grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
|
||||
grub_disk_addr_t block),
|
||||
grub_off_t filesize, int log2blocksize)
|
||||
{
|
||||
int i;
|
||||
int blockcnt;
|
||||
grub_disk_addr_t i, blockcnt;
|
||||
int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
|
||||
|
||||
/* Adjust LEN so it we can't read past the end of the file. */
|
||||
if (len > filesize)
|
||||
len = filesize;
|
||||
if (pos + len > filesize)
|
||||
len = filesize - pos;
|
||||
|
||||
blockcnt = ((len + pos) + blocksize - 1) / blocksize;
|
||||
blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS);
|
||||
|
||||
for (i = pos / blocksize; i < blockcnt; i++)
|
||||
for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++)
|
||||
{
|
||||
int blknr;
|
||||
int blockoff = pos % blocksize;
|
||||
grub_disk_addr_t blknr;
|
||||
int blockoff = pos & (blocksize - 1);
|
||||
int blockend = blocksize;
|
||||
|
||||
int skipfirst = 0;
|
||||
|
@ -255,7 +256,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
|
|||
/* Last block. */
|
||||
if (i == blockcnt - 1)
|
||||
{
|
||||
blockend = (len + pos) % blocksize;
|
||||
blockend = (len + pos) & (blocksize - 1);
|
||||
|
||||
/* The last portion is exactly blocksize. */
|
||||
if (! blockend)
|
||||
|
@ -263,7 +264,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
|
|||
}
|
||||
|
||||
/* First block. */
|
||||
if (i == pos / blocksize)
|
||||
if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS)))
|
||||
{
|
||||
skipfirst = blockoff;
|
||||
blockend -= skipfirst;
|
||||
|
@ -310,3 +311,30 @@ grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow)
|
|||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_disk_addr_t
|
||||
grub_fshelp_map_block (grub_fshelp_journal_t log, grub_disk_addr_t block)
|
||||
{
|
||||
int map_block;
|
||||
|
||||
if (! log)
|
||||
return block;
|
||||
|
||||
for (map_block = log->num_mappings - 1; map_block >= 0; map_block--)
|
||||
{
|
||||
if (log->mapping[map_block] == block)
|
||||
break;
|
||||
}
|
||||
|
||||
if (map_block < 0)
|
||||
return block;
|
||||
|
||||
map_block += log->start_block;
|
||||
if (map_block >= log->last_block)
|
||||
map_block -= log->last_block - log->first_block;
|
||||
|
||||
if (log->type == GRUB_FSHELP_JOURNAL_TYPE_BLOCK)
|
||||
return log->blkno + map_block;
|
||||
else
|
||||
return log->get_block (log->node, map_block);
|
||||
}
|
||||
|
|
|
@ -285,8 +285,8 @@ static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
|
|||
|
||||
/* Search for the block FILEBLOCK inside the file NODE. Return the
|
||||
blocknumber of this block on disk. */
|
||||
static int
|
||||
grub_hfsplus_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
static grub_disk_addr_t
|
||||
grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_hfsplus_btnode *nnode = 0;
|
||||
int blksleft = fileblock;
|
||||
|
|
|
@ -331,8 +331,8 @@ retry:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ntfs_read_block (grub_fshelp_node_t node, int block)
|
||||
static grub_disk_addr_t
|
||||
grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
|
||||
{
|
||||
struct grub_ntfs_rlst *ctx;
|
||||
|
||||
|
|
181
fs/reiserfs.c
181
fs/reiserfs.c
|
@ -52,7 +52,8 @@
|
|||
|
||||
#define REISERFS_SUPER_BLOCK_OFFSET 0x10000
|
||||
#define REISERFS_MAGIC_LEN 12
|
||||
#define REISERFS_MAGIC_STRING "ReIsEr2Fs\0\0\0"
|
||||
#define REISERFS_MAGIC_STRING "ReIsEr"
|
||||
#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
|
||||
/* If the 3rd bit of an item state is set, then it's visible. */
|
||||
#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)
|
||||
#define REISERFS_MAX_LABEL_LENGTH 16
|
||||
|
@ -109,8 +110,6 @@ struct grub_reiserfs_superblock
|
|||
grub_uint32_t inode_generation;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#ifdef GRUB_REISERFS_JOURNALING
|
||||
# error "Journaling not yet supported."
|
||||
struct grub_reiserfs_journal_header
|
||||
{
|
||||
grub_uint32_t last_flush_uid;
|
||||
|
@ -118,15 +117,20 @@ struct grub_reiserfs_journal_header
|
|||
grub_uint32_t mount_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct grub_reiserfs_transaction_header
|
||||
struct grub_reiserfs_description_block
|
||||
{
|
||||
grub_uint32_t id;
|
||||
grub_uint32_t len;
|
||||
grub_uint32_t mount_id;
|
||||
char *data;
|
||||
char checksum[12];
|
||||
grub_uint32_t real_blocks[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct grub_reiserfs_commit_block
|
||||
{
|
||||
grub_uint32_t id;
|
||||
grub_uint32_t len;
|
||||
grub_uint32_t real_blocks[0];
|
||||
} __attribute__ ((packed));
|
||||
#endif
|
||||
|
||||
struct grub_reiserfs_stat_item_v1
|
||||
{
|
||||
|
@ -228,6 +232,7 @@ struct grub_reiserfs_data
|
|||
{
|
||||
struct grub_reiserfs_superblock superblock;
|
||||
grub_disk_t disk;
|
||||
grub_fshelp_journal_t journal;
|
||||
};
|
||||
|
||||
/* Internal-only functions. Not to be used outside of this file. */
|
||||
|
@ -504,8 +509,8 @@ grub_reiserfs_get_item (struct grub_reiserfs_data *data,
|
|||
do
|
||||
{
|
||||
grub_disk_read (data->disk,
|
||||
(((grub_disk_addr_t) block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS),
|
||||
grub_fshelp_map_block (data->journal, block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
(((grub_off_t) block_number * block_size)
|
||||
& (GRUB_DISK_SECTOR_SIZE - 1)),
|
||||
block_size, (char *) block_header);
|
||||
|
@ -655,8 +660,8 @@ grub_reiserfs_read_symlink (grub_fshelp_node_t node)
|
|||
|
||||
block_size = grub_le_to_cpu16 (node->data->superblock.block_size);
|
||||
len = grub_le_to_cpu16 (found.header.item_size);
|
||||
block = (((grub_disk_addr_t) found.block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS);
|
||||
block = (grub_fshelp_map_block (node->data->journal, found.block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS));
|
||||
offset = grub_le_to_cpu16 (found.header.item_location);
|
||||
|
||||
symlink_buffer = grub_malloc (len + 1);
|
||||
|
@ -675,6 +680,124 @@ grub_reiserfs_read_symlink (grub_fshelp_node_t node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_reiserfs_get_journal (struct grub_reiserfs_data *data)
|
||||
{
|
||||
int block_size = grub_le_to_cpu16 (data->superblock.block_size);
|
||||
char buf[block_size];
|
||||
struct grub_reiserfs_journal_header *jh;
|
||||
grub_fshelp_journal_t log;
|
||||
grub_uint32_t seq_id, mount_id;
|
||||
int num_blocks = grub_le_to_cpu32 (data->superblock.journal_original_size);
|
||||
int base_block = grub_le_to_cpu32 (data->superblock.journal_block);
|
||||
int last_num, num, block;
|
||||
|
||||
data->journal = 0;
|
||||
|
||||
if (! data->superblock.journal_block)
|
||||
return;
|
||||
|
||||
if (grub_disk_read (data->disk,
|
||||
(base_block + num_blocks)
|
||||
* (block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
0, sizeof (struct grub_reiserfs_journal_header),
|
||||
buf))
|
||||
return;
|
||||
|
||||
log = grub_malloc (sizeof (struct grub_fshelp_journal) +
|
||||
num_blocks * sizeof (grub_disk_addr_t));
|
||||
if (! log)
|
||||
return;
|
||||
|
||||
jh = (struct grub_reiserfs_journal_header *) &buf[0];
|
||||
|
||||
log->type = GRUB_FSHELP_JOURNAL_TYPE_BLOCK;
|
||||
log->blkno = base_block;
|
||||
log->first_block = 0;
|
||||
log->last_block = num_blocks;
|
||||
log->start_block = grub_le_to_cpu32 (jh->unflushed_offset);
|
||||
|
||||
seq_id = grub_le_to_cpu32 (jh->last_flush_uid);
|
||||
mount_id = grub_le_to_cpu32 (jh->mount_id);
|
||||
|
||||
last_num = num = 0;
|
||||
block = log->start_block;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct grub_reiserfs_description_block *db;
|
||||
struct grub_reiserfs_commit_block *cb;
|
||||
grub_uint32_t i, len, half_len, id, mid;
|
||||
|
||||
if (grub_disk_read (data->disk,
|
||||
(base_block + block)
|
||||
* (block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
0, sizeof (buf), buf))
|
||||
break;
|
||||
|
||||
if (grub_memcmp (&buf[block_size - REISERFS_MAGIC_LEN],
|
||||
REISERFS_MAGIC_DESC_BLOCK,
|
||||
sizeof (REISERFS_MAGIC_DESC_BLOCK) - 1))
|
||||
break;
|
||||
|
||||
db = (struct grub_reiserfs_description_block *) &buf[0];
|
||||
id = grub_le_to_cpu32 (db->id);
|
||||
len = grub_le_to_cpu32 (db->len);
|
||||
mid = grub_le_to_cpu32 (db->mount_id);
|
||||
if ((id <= seq_id) && (mid <= mount_id))
|
||||
break;
|
||||
|
||||
log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
|
||||
half_len = ((block_size - 24) >> 2);
|
||||
if (half_len > len)
|
||||
half_len = len;
|
||||
|
||||
for (i = 0; i < half_len; i++)
|
||||
log->mapping[num++] = db->real_blocks[i];
|
||||
|
||||
block += grub_le_to_cpu32 (db->len) + 1;
|
||||
if (block >= log->last_block)
|
||||
block -= log->last_block;
|
||||
|
||||
if (grub_disk_read (data->disk,
|
||||
(base_block + block)
|
||||
* (block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
0, sizeof (buf), buf))
|
||||
break;
|
||||
|
||||
cb = (struct grub_reiserfs_commit_block *) &buf[0];
|
||||
if ((grub_le_to_cpu32 (cb->id) != id) ||
|
||||
(grub_le_to_cpu32 (cb->len) != len))
|
||||
break;
|
||||
|
||||
for (i = 0; i < len - half_len; i++)
|
||||
log->mapping[num++] = cb->real_blocks[i];
|
||||
|
||||
last_num = num;
|
||||
log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
|
||||
|
||||
block++;
|
||||
if (block >= log->last_block)
|
||||
block -= log->last_block;
|
||||
|
||||
seq_id = id;
|
||||
mount_id = mid;
|
||||
};
|
||||
|
||||
if (! last_num)
|
||||
grub_free (log);
|
||||
else
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sizeof (struct grub_fshelp_journal) +
|
||||
last_num * sizeof (grub_disk_addr_t);
|
||||
|
||||
log->num_mappings = last_num;
|
||||
data->journal = grub_realloc (log, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the mounted filesystem structure and return it. */
|
||||
static struct grub_reiserfs_data *
|
||||
grub_reiserfs_mount (grub_disk_t disk)
|
||||
|
@ -688,12 +811,13 @@ grub_reiserfs_mount (grub_disk_t disk)
|
|||
if (grub_errno)
|
||||
goto fail;
|
||||
if (grub_memcmp (data->superblock.magic_string,
|
||||
REISERFS_MAGIC_STRING, REISERFS_MAGIC_LEN))
|
||||
REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem");
|
||||
goto fail;
|
||||
}
|
||||
data->disk = disk;
|
||||
grub_reiserfs_get_journal (data);
|
||||
return data;
|
||||
|
||||
fail:
|
||||
|
@ -741,8 +865,8 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
|||
struct grub_reiserfs_item_header *item_headers;
|
||||
|
||||
grub_disk_read (data->disk,
|
||||
(((grub_disk_addr_t) block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS),
|
||||
grub_fshelp_map_block (data->journal, block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
(((grub_off_t) block_number * block_size)
|
||||
& (GRUB_DISK_SECTOR_SIZE - 1)),
|
||||
block_size, (char *) block_header);
|
||||
|
@ -836,7 +960,8 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
|||
{
|
||||
struct grub_reiserfs_stat_item_v1 entry_v1_stat;
|
||||
grub_disk_read (data->disk,
|
||||
((grub_disk_addr_t) entry_block_number * block_size) >> GRUB_DISK_SECTOR_BITS,
|
||||
grub_fshelp_map_block (data->journal, entry_block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
grub_le_to_cpu16 (entry_item->header.item_location),
|
||||
sizeof (entry_v1_stat),
|
||||
(char *) &entry_v1_stat);
|
||||
|
@ -878,7 +1003,8 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
|||
{
|
||||
struct grub_reiserfs_stat_item_v2 entry_v2_stat;
|
||||
grub_disk_read (data->disk,
|
||||
((grub_disk_addr_t) entry_block_number * block_size) >> GRUB_DISK_SECTOR_BITS,
|
||||
grub_fshelp_map_block (data->journal, entry_block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
grub_le_to_cpu16 (entry_item->header.item_location),
|
||||
sizeof (entry_v2_stat),
|
||||
(char *) &entry_v2_stat);
|
||||
|
@ -1026,8 +1152,8 @@ grub_reiserfs_open (struct grub_file *file, const char *name)
|
|||
{
|
||||
struct grub_reiserfs_stat_item_v1 entry_v1_stat;
|
||||
grub_disk_read (data->disk,
|
||||
(((grub_disk_addr_t) block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS),
|
||||
grub_fshelp_map_block (data->journal, block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
entry_location
|
||||
+ (((grub_off_t) block_number * block_size)
|
||||
& (GRUB_DISK_SECTOR_SIZE - 1)),
|
||||
|
@ -1040,8 +1166,8 @@ grub_reiserfs_open (struct grub_file *file, const char *name)
|
|||
{
|
||||
struct grub_reiserfs_stat_item_v2 entry_v2_stat;
|
||||
grub_disk_read (data->disk,
|
||||
(((grub_disk_addr_t) block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS),
|
||||
grub_fshelp_map_block (data->journal, block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
entry_location
|
||||
+ (((grub_off_t) block_number * block_size)
|
||||
& (GRUB_DISK_SECTOR_SIZE - 1)),
|
||||
|
@ -1109,8 +1235,8 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
|
|||
switch (found.type)
|
||||
{
|
||||
case GRUB_REISERFS_DIRECT:
|
||||
block = (((grub_disk_addr_t) found.block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS);
|
||||
block = (grub_fshelp_map_block (data->journal, found.block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS));
|
||||
grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
|
||||
if (initial_position < current_position + item_size)
|
||||
{
|
||||
|
@ -1142,8 +1268,8 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
|
|||
if (! indirect_block_ptr)
|
||||
goto fail;
|
||||
grub_disk_read (found.data->disk,
|
||||
(((grub_disk_addr_t) found.block_number * block_size)
|
||||
>> GRUB_DISK_SECTOR_BITS),
|
||||
grub_fshelp_map_block (data->journal, found.block_number) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS),
|
||||
grub_le_to_cpu16 (found.header.item_location),
|
||||
item_size, (char *) indirect_block_ptr);
|
||||
if (grub_errno)
|
||||
|
@ -1154,9 +1280,9 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
|
|||
&& current_position < final_position;
|
||||
indirect_block++)
|
||||
{
|
||||
block = ((grub_disk_addr_t)
|
||||
grub_le_to_cpu32 (indirect_block_ptr[indirect_block])
|
||||
* block_size) >> GRUB_DISK_SECTOR_BITS;
|
||||
block = (grub_fshelp_map_block (data->journal,
|
||||
grub_le_to_cpu32 (indirect_block_ptr[indirect_block])) *
|
||||
(block_size >> GRUB_DISK_SECTOR_BITS));
|
||||
grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
|
||||
if (current_position + block_size >= initial_position)
|
||||
{
|
||||
|
@ -1255,6 +1381,7 @@ grub_reiserfs_close (grub_file_t file)
|
|||
struct grub_fshelp_node *node = file->data;
|
||||
struct grub_reiserfs_data *data = node->data;
|
||||
|
||||
grub_free (data->journal);
|
||||
grub_free (data);
|
||||
grub_free (node);
|
||||
#ifndef GRUB_UTIL
|
||||
|
|
6
fs/sfs.c
6
fs/sfs.c
|
@ -219,8 +219,8 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
|
|||
return grub_error (GRUB_ERR_FILE_READ_ERROR, "SFS extent not found");
|
||||
}
|
||||
|
||||
static int
|
||||
grub_sfs_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
static grub_disk_addr_t
|
||||
grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
int blk = node->block;
|
||||
int size = 0;
|
||||
|
@ -239,7 +239,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
if (err)
|
||||
return 0;
|
||||
|
||||
if (fileblock < size)
|
||||
if (fileblock < (unsigned int) size)
|
||||
return fileblock + blk;
|
||||
|
||||
fileblock -= size;
|
||||
|
|
8
fs/udf.c
8
fs/udf.c
|
@ -404,8 +404,8 @@ grub_udf_read_icb (struct grub_udf_data *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_udf_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
static grub_disk_addr_t
|
||||
grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
char *ptr;
|
||||
int len;
|
||||
|
@ -429,7 +429,7 @@ grub_udf_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
len /= sizeof (struct grub_udf_short_ad);
|
||||
while (len > 0)
|
||||
{
|
||||
if (fileblock < (int) U32 (ad->length))
|
||||
if (fileblock < U32 (ad->length))
|
||||
return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 :
|
||||
(grub_udf_get_block (node->data,
|
||||
node->part_ref,
|
||||
|
@ -448,7 +448,7 @@ grub_udf_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
len /= sizeof (struct grub_udf_long_ad);
|
||||
while (len > 0)
|
||||
{
|
||||
if (fileblock < (int) U32 (ad->length))
|
||||
if (fileblock < U32 (ad->length))
|
||||
return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ? 0 :
|
||||
(grub_udf_get_block (node->data,
|
||||
ad->block.part_ref,
|
||||
|
|
10
fs/xfs.c
10
fs/xfs.c
|
@ -220,8 +220,8 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
grub_xfs_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
static grub_disk_addr_t
|
||||
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_xfs_btree_node *leaf = 0;
|
||||
int ex, nrec;
|
||||
|
@ -244,7 +244,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
|
||||
for (i = 0; i < nrec; i++)
|
||||
{
|
||||
if ((grub_uint64_t) fileblock < grub_be_to_cpu64 (keys[i]))
|
||||
if (fileblock < grub_be_to_cpu64 (keys[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -292,8 +292,8 @@ grub_xfs_read_block (grub_fshelp_node_t node, int fileblock)
|
|||
for (ex = 0; ex < nrec; ex++)
|
||||
{
|
||||
grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex);
|
||||
int offset = GRUB_XFS_EXTENT_OFFSET (exts, ex);
|
||||
int size = GRUB_XFS_EXTENT_SIZE (exts, ex);
|
||||
grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex);
|
||||
grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex);
|
||||
|
||||
/* Sparse block. */
|
||||
if (fileblock < offset)
|
||||
|
|
|
@ -34,6 +34,34 @@ enum grub_fshelp_filetype
|
|||
GRUB_FSHELP_SYMLINK
|
||||
};
|
||||
|
||||
enum grub_fshelp_journal_type
|
||||
{
|
||||
GRUB_FSHELP_JOURNAL_TYPE_BLOCK,
|
||||
GRUB_FSHELP_JOURNAL_TYPE_FILE
|
||||
};
|
||||
|
||||
#define GRUB_FSHELP_JOURNAL_UNUSED_MAPPING (grub_disk_addr_t) -1
|
||||
|
||||
struct grub_fshelp_journal
|
||||
{
|
||||
int type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
grub_fshelp_node_t node;
|
||||
grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, grub_disk_addr_t block);
|
||||
};
|
||||
grub_disk_addr_t blkno;
|
||||
};
|
||||
int first_block;
|
||||
int last_block;
|
||||
int start_block;
|
||||
int num_mappings;
|
||||
grub_disk_addr_t mapping[0];
|
||||
};
|
||||
typedef struct grub_fshelp_journal *grub_fshelp_journal_t;
|
||||
|
||||
/* Lookup the node PATH. The node ROOTNODE describes the root of the
|
||||
directory tree. The node found is returned in FOUNDNODE, which is
|
||||
either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
|
||||
|
@ -64,15 +92,18 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
|
|||
grub_ssize_t
|
||||
EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node,
|
||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||
unsigned offset,
|
||||
unsigned length),
|
||||
int pos, grub_size_t len, char *buf,
|
||||
int (*get_block) (grub_fshelp_node_t node,
|
||||
int block),
|
||||
unsigned offset,
|
||||
unsigned length),
|
||||
grub_off_t pos, grub_size_t len, char *buf,
|
||||
grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
|
||||
grub_disk_addr_t block),
|
||||
grub_off_t filesize, int log2blocksize);
|
||||
|
||||
unsigned int
|
||||
EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize,
|
||||
unsigned int *pow);
|
||||
|
||||
grub_disk_addr_t
|
||||
EXPORT_FUNC(grub_fshelp_map_block) (grub_fshelp_journal_t log, grub_disk_addr_t block);
|
||||
|
||||
#endif /* ! GRUB_FSHELP_HEADER */
|
||||
|
|
Loading…
Reference in New Issue