/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
/* Reiserfs block (de)allocator, bitmap-based. */
#include <linux/time.h>
#include <linux/reiserfs_fs.h>
#include <linux/errno.h>
#include <linux/buffer_head.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
#include <linux/reiserfs_fs_sb.h>
#include <linux/reiserfs_fs_i.h>
#include <linux/quotaops.h>
#define PREALLOCATION_SIZE 9
/* different reiserfs block allocator options */
#define SB_ALLOC_OPTS(s) (REISERFS_SB(s)->s_alloc_options.bits)
#define _ALLOC_concentrating_formatted_nodes 0
#define _ALLOC_displacing_large_files 1
#define _ALLOC_displacing_new_packing_localities 2
#define _ALLOC_old_hashed_relocation 3
#define _ALLOC_new_hashed_relocation 4
#define _ALLOC_skip_busy 5
#define _ALLOC_displace_based_on_dirid 6
#define _ALLOC_hashed_formatted_nodes 7
#define _ALLOC_old_way 8
#define _ALLOC_hundredth_slices 9
#define _ALLOC_dirid_groups 10
#define _ALLOC_oid_groups 11
#define _ALLOC_packing_groups 12
#define concentrating_formatted_nodes(s) test_bit(_ALLOC_concentrating_formatted_nodes, &SB_ALLOC_OPTS(s))
#define displacing_large_files(s) test_bit(_ALLOC_displacing_large_files, &SB_ALLOC_OPTS(s))
#define displacing_new_packing_localities(s) test_bit(_ALLOC_displacing_new_packing_localities, &SB_ALLOC_OPTS(s))
#define SET_OPTION(optname) \
do { \
reiserfs_info(s, "block allocator option \"%s\" is set", #optname); \
set_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s)); \
} while(0)
#define TEST_OPTION(optname, s) \
test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s))
static inline void get_bit_address(struct super_block *s,
b_blocknr_t block,
unsigned int *bmap_nr,
unsigned int *offset)
{
/* It is in the bitmap block number equal to the block
* number divided by the number of bits in a block. */
*bmap_nr = block >> (s->s_blocksize_bits + 3);
/* Within that bitmap block it is located at bit offset *offset. */
*offset = block & ((s->s_blocksize << 3) - 1);
}
int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
{
unsigned int bmap, offset;
unsigned int bmap_count = reiserfs_bmap_count(s);
if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
reiserfs_error(s, "vs-4010",
"block number is out of range %lu (%u)",
block, SB_BLOCK_COUNT(s));
return 0;
}
get_bit_address(s, block, &bmap, &offset);
/* Old format filesystem? Unlikely, but the bitmaps are all up front so
* we need to account for it. */
if (unlikely(test_bit(REISERFS_OLD_FORMAT,
&(REISERFS_SB(s)->s_properties)))) {
b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
if (block >= bmap1 &&
block <= bmap1 + bmap_count) {
reiserfs_error(s, "vs-4019", "bitmap block %lu(%u) "
"can't be freed or reused",
block, bmap_count);
return 0;
}
} else {
if (offset == 0) {
reiserfs_error(s, "vs-4020", "bitmap block %lu(%u) "
"can't be freed or reused",
block, bmap_count);
<