Hi.
Attached is my work on reiserfs handling.
As I don't plan to work on it anytime soon, and as I was advised on IRC, I
port it here, in case someone want to use it as a base.
It does not follow the coding style, some part looks quite ugly (big hex
constants as bitmasks, grub_reiserfs_get_item and grub_reiserfe_iterate_dir
functions), has old commented out code (grub_reiserfs_read) and some debug
printfs commented out (grub_reiserfe_iterate_dir), conditionaly compiled
(GRUB_REISERFS_DEBUG), or always available.
As such, it was good enough to read tens of megabyte big files on a reiserfs
3.5 disk image on a PPC32 box. It handles symlinks as such, and showed no
read errors as far as I could tell. It was only tested in grub-emu, and never
on a live system.
To build grub2 with reiserfs module, add this file in the fs folder and add
a reference to this file in conf/*.rmk files .
Sorry for not finishing that work.
--
Vincent Pelletier
/* reiserfs.c - ReiserFS versions up to 3.6 */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
*
* 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
TODO:
implement journal handling (ram replay)
implement symlinks support
support items bigger than roughly (blocksize / 4) * blocksize
!! that goes for directories aswell, size in such case is metadata size.
test tail packing direct files
validate partition label position
*/
#warning TODO : journal, tail packing (?)
// #define GRUB_REISERFS_KEYV2_BITFIELD
// #define GRUB_REISERFS_DEBUG
// #define GRUB_REISERFS_JOURNALING
// #define GRUB_HEXDUMP
#include grub/err.h
#include grub/file.h
#include grub/mm.h
#include grub/misc.h
#include grub/disk.h
#include grub/dl.h
#include grub/types.h
#include grub/fshelp.h
#define MIN(a, b) (((a)(b))?(a):(b))
#define MAX(a, b) (((a)(b))?(a):(b))
#define REISERFS_SUPER_BLOCK_OFFSET 0x1
#define REISERFS_MAGIC_LEN 12
#define REISERFS_MAGIC_STRING ReIsEr2Fs\0\0\0
/* 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
#define REISERFS_LABEL_OFFSET 0x64
#define S_IFLNK 0xA000
#ifndef GRUB_UTIL
static grub_dl_t my_mod;
#endif
enum grub_reiserfs_item_type
{
GRUB_REISERFS_STAT,
GRUB_REISERFS_DIRECTORY,
GRUB_REISERFS_DIRECT,
GRUB_REISERFS_INDIRECT,
GRUB_REISERFS_ANY, /* Matches both _DIRECT and _INDIRECT when searching. */
GRUB_REISERFS_UNKNOWN
};
struct grub_reiserfs_superblock
{
grub_uint32_t block_count;
grub_uint32_t block_free_count;
grub_uint32_t root_block;
grub_uint32_t journal_block;
grub_uint32_t journal_device;
grub_uint32_t journal_original_size;
grub_uint32_t journal_max_transaction_size;
grub_uint32_t journal_block_count;
grub_uint32_t journal_max_batch;
grub_uint32_t journal_max_commit_age;
grub_uint32_t journal_max_transaction_age;
grub_uint16_t block_size;
grub_uint16_t oid_max_size;
grub_uint16_t oid_current_size;
grub_uint16_t state;
grub_uint8_t magic_string[REISERFS_MAGIC_LEN];
grub_uint32_t function_hash_code;
grub_uint16_t tree_height;
grub_uint16_t bitmap_number;
grub_uint16_t version;
grub_uint16_t reserved;
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;
grub_uint32_t unflushed_offset;
grub_uint32_t mount_id;
} __attribute__ ((packed));
struct grub_reiserfs_transaction_header
{
grub_uint32_t id;
grub_uint32_t len;
grub_uint32_t mount_id;
char *data;
char checksum[12];
} __attribute__ ((packed));
#endif
struct grub_reiserfs_stat_item_v1
{
grub_uint16_t mode;
grub_uint16_t hardlink_count;
grub_uint16_t uid;
grub_uint16_t gid;
grub_uint32_t size;
grub_uint32_t atime;
grub_uint32_t mtime;
grub_uint32_t ctime;
grub_uint32_t rdev;
grub_uint32_t first_direct_byte;
} __attribute__ ((packed));
struct grub_reiserfs_stat_item_v2
{
grub_uint16_t mode;
grub_uint16_t reserved;
grub_uint32_t hardlink_count;
grub_uint64_t size;
grub_uint32_t uid;
grub_uint32_t gid;
grub_uint32_t atime;
grub_uint32_t mtime;
grub_uint32_t ctime;
grub_uint32_t blocks;
grub_uint32_t