]> git.ozlabs.org Git - yaboot.git/blobdiff - second/fs_reiserfs.c
Determine last ext3 LBA to fix wild LBA reads
[yaboot.git] / second / fs_reiserfs.c
index 28f6d4e8778d6521c5d8970d2a4c48ab1b2626ea..4ad1c2ec176dbb9bb7495e9550e0d4312c40643e 100644 (file)
@@ -1,35 +1,36 @@
-/* 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 "stdlib.h"
 #include "fs.h"
 #include "errors.h"
 #include "types.h"
 #include "ctype.h"
 #include "string.h"
 #include "stdlib.h"
 #include "fs.h"
 #include "errors.h"
+#include "debug.h"
 #include "reiserfs/reiserfs.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 );
 /* 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 );
@@ -75,7 +76,7 @@ reiserfs_open( struct boot_file_t *file, const char *dev_name,
      if (part)
      {
          DEBUG_F( "Determining offset for partition %d\n", part->part_number );
      if (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 );
          DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
                   part->part_start,
                   part->blocksize );
@@ -168,8 +169,8 @@ read_disk_block( struct boot_file_t *file, __u32 block, __u32 start,
 {
      __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
          : INFO->blocksize;
 {
      __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 )) {
      DEBUG_F( "Reading %u bytes, starting at block %u, disk offset %Lu\n",
              length, block, pos );
      if (!prom_lseek( file->of_device, pos )) {
@@ -190,7 +191,7 @@ journal_read( __u32 block, __u32 len, char *buffer )
 
 /* Read a block from ReiserFS file system, taking the journal into
  * account.  If the block nr is in the journal, the block from the
 
 /* 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 )
  */
 static int
 block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
@@ -258,7 +259,7 @@ block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
          DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
                   blockNr, translatedNr - INFO->journal_block );
 
          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;
           * later transactions. */
      not_found:
          desc_block = (desc_block + 2 + j_len) & journal_mask;
@@ -272,8 +273,8 @@ block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
  * we can still read the rest from the disk on demand.
  *
  * The first number of valid transactions and the descriptor block of the
  * 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 )
  */
 static int
 journal_init( void )
@@ -334,7 +335,7 @@ journal_init( void )
               {
                    int i;
 
               {
                    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;
                     * The block number of descriptor can easily be computed. *
                     * and need not to be stored here. */
                    *journal_table++ = desc.j_len;
@@ -504,7 +505,7 @@ reiserfs_read_super( void )
  * 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
  * 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.
  *
  *       if there is not enough space in the cache, the top most are
  *       omitted.
  *
@@ -514,7 +515,7 @@ reiserfs_read_super( void )
  *   next_key() gets the next key in tree order.
  *
  * This means, that I can only sequential reads of files are
  *   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.
  */
 
 /* Read in the node at the current path and depth into the node cache.
@@ -525,6 +526,7 @@ read_tree_node( __u32 blockNr, __u16 depth )
 {
      char *cache = CACHE(depth);
      int num_cached = INFO->cached_slots;
 {
      char *cache = CACHE(depth);
      int num_cached = INFO->cached_slots;
+     errnum = 0;
 
      if ( depth < num_cached )
      {
 
      if ( depth < num_cached )
      {
@@ -563,7 +565,7 @@ read_tree_node( __u32 blockNr, __u16 depth )
 }
 
 /* Get the next key, i.e. the key following the last retrieved key in
 }
 
 /* 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 )
  * INFO->current_info are adapted accordingly.  */
 static int
 next_key( void )
@@ -624,7 +626,7 @@ next_key( void )
               DEBUG_F( "  depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
 
               if ( key_nr == nr_item )
               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;
 
                     * to 0 */
                    INFO->next_key_nr[depth] = 0;
 
@@ -652,11 +654,11 @@ found:
      return 1;
 }
 
      return 1;
 }
 
-/* preconditions: reiserfs_read_super already executed, therefore 
+/* preconditions: reiserfs_read_super already executed, therefore
  *   INFO block is valid
  *   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.
  *   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.
  *   current_item fields describe the key that equals the
  *   searched key.  INFO->next_key contains the next key after
  *   the searched key.
@@ -670,7 +672,7 @@ search_stat( __u32 dir_id, __u32 objectid )
      int nr_item;
      int i;
      struct item_head *ih;
      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) );
 
      DEBUG_F( "search_stat:\n  key %u:%u:0:0\n", le32_to_cpu(dir_id),
              le32_to_cpu(objectid) );
@@ -744,7 +746,7 @@ reiserfs_read_data( char *buf, __u32 len )
      __u32 offset;
      __u32 to_read;
      char *prev_buf = buf;
      __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 );
 
      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 );
@@ -817,11 +819,11 @@ done:
 }
 
 
 }
 
 
-/* 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
  *   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
  *   the size of the file.
  */
 static int
@@ -834,6 +836,7 @@ reiserfs_open_file( char *dirname )
      char linkbuf[PATH_MAX];   /* buffer for following symbolic links */
      int link_count = 0;
      int mode;
      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);
 
      dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
      objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
@@ -882,7 +885,7 @@ reiserfs_open_file( char *dirname )
                    return 0;
               }
 
                    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 );
 
                * that DIRNAME and LINKBUF may overlap! */
               memmove( linkbuf + INFO->file->len, dirname, len + 1 );
 
@@ -973,7 +976,7 @@ reiserfs_open_file( char *dirname )
                    {
                         int cmp;
 
                    {
                         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
                          * 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
@@ -984,7 +987,7 @@ reiserfs_open_file( char *dirname )
                         if ( cmp == 0 )
                              goto found;
                    }
                         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++;
                     */
                    name_end = filename;
                    de_head++;
@@ -1022,7 +1025,7 @@ offset_v2_k_type( struct offset_v2 *v2 )
      tmp.linear = le64_to_cpu( tmp.linear );
      return tmp.offset_v2.k_type;
 }
      tmp.linear = le64_to_cpu( tmp.linear );
      return tmp.offset_v2.k_type;
 }
+
 inline loff_t
 offset_v2_k_offset( struct offset_v2 *v2 )
 {
 inline loff_t
 offset_v2_k_offset( struct offset_v2 *v2 )
 {
@@ -1044,9 +1047,9 @@ uniqueness2type (__u32 uniqueness)
      return TYPE_ANY;
 }
 
      return TYPE_ANY;
 }
 
-/* 
+/*
  * Local variables:
  * Local variables:
- * c-file-style: "K&R"
+ * c-file-style: "k&r"
  * c-basic-offset: 5
  * End:
  */
  * c-basic-offset: 5
  * End:
  */