/* Tries to find contiguous zero bit window (given size) in given region of * bitmap and place new blocks there. Returns number of allocated blocks. */ static int scan_bitmap (struct reiserfs_transaction_handle *th, unsigned long *start, unsigned long finish, int min, int max, int unfm, unsigned long file_block) { int nr_allocated=0; struct super_block * s = th->t_super; /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr * - Hans, it is not a block number - Zam. */ int bm, off; int end_bm, end_off; int off_max = s->s_blocksize << 3; PROC_INFO_INC( s, scan_bitmap.call ); if ( SB_FREE_BLOCKS(s) <= 0) return 0; // No point in looking for more free blocks get_bit_address (s, *start, &bm, &off); get_bit_address (s, finish, &end_bm, &end_off); // With this option set first we try to find a bitmap that is at least 10% // free, and if that fails, then we fall back to old whole bitmap scanning if ( TEST_OPTION(skip_busy, s) && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s)/20 ) { for (; bm < end_bm; bm++, off = 0) { if ( ( off && (!unfm || (file_block != 0))) || SB_AP_BITMAP(s)[bm].free_count > (s->s_blocksize << 3) / 10 ) nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm); if (nr_allocated) goto ret; } get_bit_address (s, *start, &bm, &off); } for (; bm < end_bm; bm++, off = 0) { nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm); if (nr_allocated) goto ret; } nr_allocated = scan_bitmap_block(th, bm, &off, end_off + 1, min, max, unfm); ret: *start = bm * off_max + off; return nr_allocated; }
/* Tries to find contiguous zero bit window (given size) in given region of * bitmap and place new blocks there. Returns number of allocated blocks. */ static int scan_bitmap (struct reiserfs_transaction_handle *th, b_blocknr_t *start, b_blocknr_t finish, int min, int max, int unfm, unsigned long file_block) { int nr_allocated=0; struct super_block * s = th->t_super; /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr * - Hans, it is not a block number - Zam. */ int bm, off; int end_bm, end_off; int off_max = s->s_blocksize << 3; BUG_ON (!th->t_trans_id); PROC_INFO_INC( s, scan_bitmap.call ); if ( SB_FREE_BLOCKS(s) <= 0) return 0; // No point in looking for more free blocks get_bit_address (s, *start, &bm, &off); get_bit_address (s, finish, &end_bm, &end_off); if (bm > SB_BMAP_NR(s)) return 0; if (end_bm > SB_BMAP_NR(s)) end_bm = SB_BMAP_NR(s); /* When the bitmap is more than 10% free, anyone can allocate. * When it's less than 10% free, only files that already use the * bitmap are allowed. Once we pass 80% full, this restriction * is lifted. * * We do this so that files that grow later still have space close to * their original allocation. This improves locality, and presumably * performance as a result. * * This is only an allocation policy and does not make up for getting a * bad hint. Decent hinting must be implemented for this to work well. */ if ( TEST_OPTION(skip_busy, s) && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s)/20 ) { for (; bm < end_bm; bm++, off = 0) { if ( ( off && (!unfm || (file_block != 0))) || SB_AP_BITMAP(s)[bm].free_count > (s->s_blocksize << 3) / 10 ) nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm); if (nr_allocated) goto ret; } /* we know from above that start is a reasonable number */ get_bit_address (s, *start, &bm, &off); } for (; bm < end_bm; bm++, off = 0) { nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm); if (nr_allocated) goto ret; } nr_allocated = scan_bitmap_block(th, bm, &off, end_off + 1, min, max, unfm); ret: *start = bm * off_max + off; return nr_allocated; }