-/* ReiserFS filesystem
-
- Copyright (C) 2001 Jeffrey Mahoney (jeffm@suse.com)
-
- Adapted from GRUB
-
- Copyright (C) 2000, 2001 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.
+/*
+ * fs_reiserfs.c - an implementation for the Reiser filesystem
+ *
+ * Copyright (C) 2001 Jeffrey Mahoney (jeffm@suse.com)
+ *
+ * Adapted from Grub
+ *
+ * Copyright (C) 2000, 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
-*/
#include "types.h"
#include "ctype.h"
#include "string.h"
#include "fs.h"
#include "errors.h"
#include "debug.h"
+#include "bootinfo.h"
#include "reiserfs/reiserfs.h"
/* Exported in struct fs_t */
-static int reiserfs_open( struct boot_file_t *file, const char *dev_name,
- struct partition_t *part, const char *file_name );
+static int reiserfs_open( struct boot_file_t *file, struct partition_t *part,
+ struct boot_fspec_t *fspec);
static int reiserfs_read( struct boot_file_t *file, unsigned int size,
void *buffer );
static int
-reiserfs_open( struct boot_file_t *file, const char *dev_name,
- struct partition_t *part, const char *file_name )
+reiserfs_open( struct boot_file_t *file, struct partition_t *part,
+ struct boot_fspec_t *fspec)
{
static char buffer[1024];
+ char *dev_name = fspec->dev;
+ char *file_name = fspec->file;
DEBUG_ENTER;
DEBUG_OPEN;
memset( INFO, 0, sizeof(struct reiserfs_state) );
INFO->file = file;
- if (part)
+ if (fspec->part)
{
DEBUG_F( "Determining offset for partition %d\n", part->part_number );
- INFO->partition_offset = ((__u64)(part->part_start)) * ((__u64)part->blocksize);
+ INFO->partition_offset = ((uint64_t)part->part_start) * part->blocksize;
DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
part->part_start,
part->blocksize );
else
INFO->partition_offset = 0;
- sprintf( buffer, "%s:%d", dev_name, 0 ); /* 0 is full disk in OF */
+ strncpy(buffer, dev_name, 1020);
+ if (_machine != _MACH_bplan)
+ strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */
+
file->of_device = prom_open( buffer );
DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
buffer, file_name, INFO->partition_offset );
static __inline__ __u32
-log2( __u32 word )
+reiserfs_log2( __u32 word )
{
int i = 0;
while( word && (word & (1 << ++i)) == 0 );
{
__u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
: INFO->blocksize;
- unsigned long long pos = block * fs_blocksize;
- pos += INFO->partition_offset + start;
+ unsigned long long pos = (unsigned long long)block * (unsigned long long)fs_blocksize;
+ pos += (unsigned long long)INFO->partition_offset + (unsigned long long)start;
DEBUG_F( "Reading %u bytes, starting at block %u, disk offset %Lu\n",
length, block, pos );
if (!prom_lseek( file->of_device, pos )) {
/* Read a block from ReiserFS file system, taking the journal into
* account. If the block nr is in the journal, the block from the
- * journal taken.
+ * journal taken.
*/
static int
block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
while ( transactions-- > 0 )
{
int i = 0;
- int j_len;
+ int j_len = 0;
if ( *journal_table != 0xffffffff )
{
/* Search for the blockNr in cached journal */
- j_len = le32_to_cpu(*journal_table++);
+ j_len = le32_to_cpu((*journal_table)++);
while ( i++ < j_len )
{
if ( le32_to_cpu(*journal_table++) == blockNr )
DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
blockNr, translatedNr - INFO->journal_block );
- /* We must continue the search, as this block may be overwritten in
+ /* We must continue the search, as this block may be overwritten in
* later transactions. */
not_found:
desc_block = (desc_block + 2 + j_len) & journal_mask;
* we can still read the rest from the disk on demand.
*
* The first number of valid transactions and the descriptor block of the
- * first valid transaction are held in INFO. The transactions are all
- * adjacent, but we must take care of the journal wrap around.
+ * first valid transaction are held in INFO. The transactions are all
+ * adjacent, but we must take care of the journal wrap around.
*/
static int
journal_init( void )
{
int i;
- /* Cache the length and the realblock numbers in the table. *
+ /* Cache the length and the realblock numbers in the table. *
* The block number of descriptor can easily be computed. *
* and need not to be stored here. */
*journal_table++ = desc.j_len;
INFO->version = le16_to_cpu(super.s_version);
INFO->blocksize = le16_to_cpu(super.s_blocksize);
- INFO->blocksize_shift = log2( INFO->blocksize );
+ INFO->blocksize_shift = reiserfs_log2( INFO->blocksize );
INFO->journal_block = le32_to_cpu(super.s_journal_block);
INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size);
* My tree node cache is organized as following
* 0 ROOT node
* 1 LEAF node (if the ROOT is also a LEAF it is copied here
- * 2-n other nodes on current path from bottom to top.
+ * 2-n other nodes on current path from bottom to top.
* if there is not enough space in the cache, the top most are
* omitted.
*
* next_key() gets the next key in tree order.
*
* This means, that I can only sequential reads of files are
- * efficient, but this really doesn't hurt for grub.
+ * efficient, but this really doesn't hurt for grub.
*/
/* Read in the node at the current path and depth into the node cache.
{
char *cache = CACHE(depth);
int num_cached = INFO->cached_slots;
+ errnum = 0;
if ( depth < num_cached )
{
}
/* Get the next key, i.e. the key following the last retrieved key in
- * tree order. INFO->current_ih and
+ * tree order. INFO->current_ih and
* INFO->current_info are adapted accordingly. */
static int
next_key( void )
cache = CACHE( depth );
else
{
- cache = read_tree_node( INFO->blocks[depth], --depth );
+ /* Save depth as using it twice as args to read_tree_node()
+ * has undefined behaviour */
+ __u16 d = depth;
+ cache = read_tree_node( INFO->blocks[d], --depth );
if ( !cache )
return 0;
}
DEBUG_F( " depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
if ( key_nr == nr_item )
- /* This is the last item in this block, set the next_key_nr *
+ /* This is the last item in this block, set the next_key_nr *
* to 0 */
INFO->next_key_nr[depth] = 0;
return 1;
}
-/* preconditions: reiserfs_read_super already executed, therefore
+/* preconditions: reiserfs_read_super already executed, therefore
* INFO block is valid
- * returns: 0 if error (errnum is set),
+ * returns: 0 if error (errnum is set),
* nonzero iff we were able to find the key successfully.
- * postconditions: on a nonzero return, the current_ih and
+ * postconditions: on a nonzero return, the current_ih and
* current_item fields describe the key that equals the
* searched key. INFO->next_key contains the next key after
* the searched key.
int nr_item;
int i;
struct item_head *ih;
-
+ errnum = 0;
DEBUG_F( "search_stat:\n key %u:%u:0:0\n", le32_to_cpu(dir_id),
le32_to_cpu(objectid) );
__u32 offset;
__u32 to_read;
char *prev_buf = buf;
-
+ errnum = 0;
DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );
}
-/* preconditions: reiserfs_read_super already executed, therefore
+/* preconditions: reiserfs_read_super already executed, therefore
* INFO block is valid
* returns: 0 if error, nonzero iff we were able to find the file successfully
* postconditions: on a nonzero return, INFO->fileinfo contains the info
- * of the file we were trying to look up, filepos is 0 and filemax is
+ * of the file we were trying to look up, filepos is 0 and filemax is
* the size of the file.
*/
static int
char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
int link_count = 0;
int mode;
+ errnum = 0;
dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
return 0;
}
- /* Copy the remaining name to the end of the symlink data. Note *
+ /* Copy the remaining name to the end of the symlink data. Note *
* that DIRNAME and LINKBUF may overlap! */
memmove( linkbuf + INFO->file->len, dirname, len + 1 );
{
int cmp;
- /* Directory names in ReiserFS are not null * terminated.
+ /* Directory names in ReiserFS are not null * terminated.
* We write a temporary 0 behind it. * NOTE: that this
* may overwrite the first block in * the tree cache.
* That doesn't hurt as long as we * don't call next_key
if ( cmp == 0 )
goto found;
}
- /* The beginning of this name marks the end of the next name.
+ /* The beginning of this name marks the end of the next name.
*/
name_end = filename;
de_head++;
tmp.linear = le64_to_cpu( tmp.linear );
return tmp.offset_v2.k_type;
}
-
+
inline loff_t
offset_v2_k_offset( struct offset_v2 *v2 )
{
return TYPE_ANY;
}
-/*
+/*
* Local variables:
- * c-file-style: "K&R"
+ * c-file-style: "k&r"
* c-basic-offset: 5
* End:
*/