Ejemplo n.º 1
0
int nextchar()
{
	int c=dbuf[fwd];
	if(c!=EOF)
	{
		fwd++;
		return c;
	}
	if(end_of_first_half(fwd))   //then load next buffer
	{
		read_disk_block(dbuf+SINGLE_BUF_SIZE); 
		++fwd;
		c=dbuf[fwd];
		fwd++;
		return c;
	}
	else if(end_of_second_half(fwd))  //then load first buffer
	{
		read_disk_block(dbuf);
		fwd=0;
		c=dbuf[fwd];
		fwd++;
		return c;
	}
	else
		return EOF;
}
Ejemplo n.º 2
0
static int
journal_read( __u32 block, __u32 len, char *buffer )
{
     return read_disk_block( INFO->file,
			     (INFO->journal_block + block), 0,
			     len, buffer );
}
Ejemplo n.º 3
0
init_dbuf(const char*filename)
{
	dbuf[SINGLE_BUF_SIZE-1]=EOF;
	dbuf[2*SINGLE_BUF_SIZE-1]=EOF;
	fp=fopen(filename,"r");
	if(!fp)
	{
		fprintf(stderr,"Cannot open %s",filename);
		perror(" ");
		return 1;
	}
	read_disk_block(dbuf);
}
Ejemplo n.º 4
0
static int
reiserfs_read_data( char *buf, __u32 len )
{
     __u32 blocksize;
     __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 );


     if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
	  || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
     {
	  search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
	  goto get_next_key;
     }

     while ( errnum == 0 )
     {
	  if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
	       break;

	  offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
	  blocksize = ih_item_len(INFO->current_ih);


	  DEBUG_F( "  loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
		   INFO->file->pos, len, offset, blocksize );


	  if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
	       && offset < blocksize )
	  {
	       to_read = blocksize - offset;
	       if ( to_read > len )
		    to_read = len;

	       memcpy( buf, INFO->current_item + offset, to_read );
	       goto update_buf_len;
	  }
	  else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
	  {
	       blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;

	       while ( offset < blocksize )
	       {
		    __u32 blocknr = le32_to_cpu(((__u32 *)
						 INFO->current_item)[offset >> INFO->blocksize_shift]);

		    int blk_offset = offset & (INFO->blocksize - 1);

		    to_read = INFO->blocksize - blk_offset;
		    if ( to_read > len )
			 to_read = len;

		    /* Journal is only for meta data.
		       Data blocks can be read directly without using block_read */
		    read_disk_block( INFO->file, blocknr, blk_offset, to_read,
				     buf );

	       update_buf_len:
		    len -= to_read;
		    buf += to_read;
		    offset += to_read;
		    INFO->file->pos += to_read;
		    if ( len == 0 )
			 goto done;
	       }
	  }
     get_next_key:
	  next_key();
     }
Ejemplo n.º 5
0
/* check filesystem types and read superblock into memory buffer */
static int
reiserfs_read_super( void )
{
     struct reiserfs_super_block super;
     __u64 superblock = REISERFS_SUPERBLOCK_BLOCK;

     if (read_disk_block(INFO->file, superblock, 0, sizeof(super), &super) != sizeof(super)) {
	  DEBUG_F("read_disk_block failed!\n");
	  return 0;
     }

     DEBUG_F( "Found super->magic: \"%s\"\n", super.s_magic );

     if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
	 strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
     {
	  /* Try old super block position */
	  superblock = REISERFS_OLD_SUPERBLOCK_BLOCK;

	  if (read_disk_block( INFO->file, superblock, 0, sizeof (super),  &super ) != sizeof(super)) {
	       DEBUG_F("read_disk_block failed!\n");
	       return 0;
	  }

	  if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
	       strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
	  {
	       /* pre journaling super block - untested */
	       if ( strcmp( REISERFS_SUPER_MAGIC_STRING,
			    (char *) ((__u32) &super + 20 ) ) != 0 )
		    return 0;

	       super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE);
	       super.s_journal_block = 0;
	       super.s_version = 0;
	  }
     }

     DEBUG_F( "ReiserFS superblock data:\n" );
     DEBUG_F( "Block count: %u\n", le32_to_cpu(super.s_block_count) )
	  DEBUG_F( "Free blocks: %u\n", le32_to_cpu(super.s_free_blocks) );
     DEBUG_F( "Journal block: %u\n", le32_to_cpu(super.s_journal_block) );
     DEBUG_F( "Journal size (in blocks): %u\n",
	      le32_to_cpu(super.s_orig_journal_size) );
     DEBUG_F( "Root block: %u\n\n", le32_to_cpu(super.s_root_block) );


     INFO->version = le16_to_cpu(super.s_version);
     INFO->blocksize = le16_to_cpu(super.s_blocksize);
     INFO->blocksize_shift = 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);

     INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1;

     /* At this point, we've found a valid superblock. If we run into problems
      * mounting the FS, the user should probably know. */

     /* A few sanity checks ... */
     if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION )
     {
	  prom_printf( "ReiserFS: Unsupported version field: %u\n",
		       INFO->version );
	  return 0;
     }

     if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE
	  || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE )
     {
	  prom_printf( "ReiserFS: Unsupported block size: %u\n",
		       INFO->blocksize );
	  return 0;
     }

     /* Setup the journal.. */
     if ( INFO->journal_block != 0 )
     {
	  if ( !is_power_of_two( INFO->journal_block_count ) )
	  {
	       prom_printf( "ReiserFS: Unsupported journal size, "
			    "not a power of 2: %u\n",
			    INFO->journal_block_count );
	       return 0;
	  }

	  journal_init();
	  /* Read in super block again, maybe it is in the journal */
	  block_read( superblock, 0, sizeof (struct reiserfs_super_block),
		      (char *) &super );
     }

     /* Read in the root block */
     if ( !block_read( le32_to_cpu(super.s_root_block), 0,
		       INFO->blocksize, ROOT ) )
     {
	  prom_printf( "ReiserFS: Failed to read in root block\n" );
	  return 0;
     }

     /* The root node is always the "deepest", so we can
	determine the hieght of the tree using it. */
     INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT));


     DEBUG_F( "root read_in: block=%u, depth=%u\n",
	      le32_to_cpu(super.s_root_block), INFO->tree_depth );

     if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT )
     {
	  prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n",
		       INFO->tree_depth );
	  return 0;
     }

     if ( INFO->tree_depth == BLKH_LEVEL_LEAF )
     {
	  /* There is only one node in the whole filesystem, which is
	     simultanously leaf and root */
	  memcpy( LEAF, ROOT, INFO->blocksize );
     }
     return 1;
}
Ejemplo n.º 6
0
/* 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.
 */
static int
block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
{
     __u32 transactions = INFO->journal_transactions;
     __u32 desc_block = INFO->journal_first_desc;
     __u32 journal_mask = INFO->journal_block_count - 1;
     __u32 translatedNr = blockNr;
     __u32 *journal_table = JOURNAL_START;

//    DEBUG_F( "block_read( %u, %u, %u, ..)\n", blockNr, start, len );

     while ( transactions-- > 0 )
     {
	  int i = 0;
	  int j_len;

	  if ( *journal_table != 0xffffffff )
	  {
	       /* Search for the blockNr in cached journal */
	       j_len = le32_to_cpu(*journal_table++);
	       while ( i++ < j_len )
	       {
		    if ( le32_to_cpu(*journal_table++) == blockNr )
		    {
			 journal_table += j_len - i;
			 goto found;
		    }
	       }
	  }
	  else
	  {
	       /* This is the end of cached journal marker.  The remaining
		* transactions are still on disk. */
	       struct reiserfs_journal_desc desc;
	       struct reiserfs_journal_commit commit;

	       if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) )
		    return 0;

	       j_len = le32_to_cpu(desc.j_len);
	       while ( i < j_len && i < JOURNAL_TRANS_HALF )
		    if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr )
			 goto found;

	       if ( j_len >= JOURNAL_TRANS_HALF )
	       {
		    int commit_block = ( desc_block + 1 + j_len ) & journal_mask;

		    if ( !journal_read( commit_block,
					sizeof(commit), (char *) &commit ) )
			 return 0;

		    while ( i < j_len )
			 if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr )
			      goto found;
	       }
	  }
	  goto not_found;

     found:
	  translatedNr =
	       INFO->journal_block + ( ( desc_block + i ) & journal_mask );

	  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
	   * later transactions. */
     not_found:
	  desc_block = (desc_block + 2 + j_len) & journal_mask;
     }

     return read_disk_block( INFO->file, translatedNr, start, len, buffer );
}