示例#1
0
/* searches in journal structures for a given block number (bmap, off). If block
   is found in reiserfs journal it suggests next free block candidate to test. */
static inline  int is_block_in_journal (struct super_block * s, int bmap, int off, int *next)
{
    unsigned int tmp;

    if (reiserfs_in_journal (s, s->s_dev, bmap, off, s->s_blocksize, 1, &tmp)) {
        if (tmp) {		/* hint supplied */
            *next = tmp;
            PROC_INFO_INC( s, scan_bitmap.in_journal_hint );
        } else {
            (*next) = off + 1;		/* inc offset to avoid looping. */
            PROC_INFO_INC( s, scan_bitmap.in_journal_nohint );
        }
        PROC_INFO_INC( s, scan_bitmap.retry );
        return 1;
    }
    return 0;
}
示例#2
0
/* The function is NOT SCHEDULE-SAFE! */
static int find_forward (struct super_block * s, int * bmap_nr, int * offset, int for_unformatted)
{
  int i, j;
  struct buffer_head * bh;
  unsigned long block_to_try = 0;
  unsigned long next_block_to_try = 0 ;

  PROC_INFO_INC( s, find_forward.call );

  for (i = *bmap_nr; i < SB_BMAP_NR (s); i ++, *offset = 0, 
	       PROC_INFO_INC( s, find_forward.bmap )) {
    /* get corresponding bitmap block */
    bh = SB_AP_BITMAP (s)[i];
    if (buffer_locked (bh)) {
	PROC_INFO_INC( s, find_forward.wait );
        __wait_on_buffer (bh);
    }
retry:
    j = reiserfs_find_next_zero_le_bit ((unsigned long *)bh->b_data, 
                                         s->s_blocksize << 3, *offset);

    /* wow, this really needs to be redone.  We can't allocate a block if
    ** it is in the journal somehow.  reiserfs_in_journal makes a suggestion
    ** for a good block if the one you ask for is in the journal.  Note,
    ** reiserfs_in_journal might reject the block it suggests.  The big
    ** gain from the suggestion is when a big file has been deleted, and
    ** many blocks show free in the real bitmap, but are all not free
    ** in the journal list bitmaps.
    **
    ** this whole system sucks.  The bitmaps should reflect exactly what
    ** can and can't be allocated, and the journal should update them as
    ** it goes.  TODO.
    */
    if (j < (s->s_blocksize << 3)) {
      block_to_try = (i * (s->s_blocksize << 3)) + j; 

      /* the block is not in the journal, we can proceed */
      if (!(reiserfs_in_journal(s, s->s_dev, block_to_try, s->s_blocksize, for_unformatted, &next_block_to_try))) {
	*bmap_nr = i;
	*offset = j;
	return 1;
      } 
      /* the block is in the journal */
      else if ((j+1) < (s->s_blocksize << 3)) { /* try again */
	/* reiserfs_in_journal suggested a new block to try */
	if (next_block_to_try > 0) {
	  int new_i ;
	  get_bit_address (s, next_block_to_try, &new_i, offset);

	  PROC_INFO_INC( s, find_forward.in_journal_hint );

	  /* block is not in this bitmap. reset i and continue
	  ** we only reset i if new_i is in a later bitmap.
	  */
	  if (new_i > i) {
	    i = (new_i - 1 ); /* i gets incremented by the for loop */
	    PROC_INFO_INC( s, find_forward.in_journal_out );
	    continue ;
	  }
	} else {
	  /* no suggestion was made, just try the next block */
	  *offset = j+1 ;
	}
	PROC_INFO_INC( s, find_forward.retry );
	goto retry ;
      }
    }
  }
    /* zero bit not found */
    return 0;
}